1 /* This file is part of the KDE project
2  * Copyright (C) 2007 Marijn Kruisselbrink <mkruisselbrink@kde.org>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public License
15  * along with this library; see the file COPYING.LIB.  If not, write to
16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19 #include "Sheet.h"
20 #include "Part.h"
21 #include "PartGroup.h"
22 #include "Bar.h"
23 #include "StaffSystem.h"
24 #include "Staff.h"
25 
26 #include <QList>
27 
28 namespace MusicCore {
29 
30 class Sheet::Private
31 {
32 public:
33     QList<Part*> parts;
34     QList<PartGroup*> partGroups;
35     QList<Bar*> bars;
36     QList<StaffSystem*> staffSystems;
37 };
38 
Sheet(QObject * parent)39 Sheet::Sheet(QObject* parent) : QObject(parent), d(new Private)
40 {
41 }
42 
~Sheet()43 Sheet::~Sheet()
44 {
45     delete d;
46 }
47 
partCount() const48 int Sheet::partCount() const
49 {
50     return d->parts.size();
51 }
52 
part(int index)53 Part* Sheet::part(int index)
54 {
55     Q_ASSERT( index >= 0 && index < partCount() );
56     return d->parts[index];
57 }
58 
partIndex(Part * part)59 int Sheet::partIndex(Part* part)
60 {
61     return d->parts.indexOf(part);
62 }
63 
addPart(const QString & name)64 Part* Sheet::addPart(const QString& name)
65 {
66     Part* part = new Part(this, name);
67     d->parts.append(part);
68     emit partAdded(d->parts.size(), part);
69     return part;
70 }
71 
addPart(Part * part)72 void Sheet::addPart(Part* part)
73 {
74     Q_ASSERT( part );
75     part->setParent(this);
76     d->parts.append(part);
77     emit partAdded(d->parts.size(), part);
78 }
79 
insertPart(int before,const QString & name)80 Part* Sheet::insertPart(int before, const QString& name)
81 {
82     Q_ASSERT( before >= 0 && before <= partCount() );
83     Part* part = new Part(this, name);
84     d->parts.insert(before, part);
85     emit partAdded(before, part);
86     return part;
87 }
88 
insertPart(int before,Part * part)89 void Sheet::insertPart(int before, Part* part)
90 {
91     Q_ASSERT( before >= 0 && before <= partCount() );
92     Q_ASSERT( part );
93     part->setParent(this);
94     d->parts.insert(before, part);
95     emit partAdded(before, part);
96 }
97 
removePart(int index,bool deletePart)98 void Sheet::removePart(int index, bool deletePart)
99 {
100     Q_ASSERT( index >= 0 && index < partCount() );
101     Part* part = d->parts.takeAt(index);
102     emit partRemoved(index, part);
103     if (deletePart) {
104         delete part;
105     }
106 }
107 
removePart(Part * part,bool deletePart)108 void Sheet::removePart(Part* part, bool deletePart)
109 {
110     Q_ASSERT( part && part->sheet() == this);
111     int index = d->parts.indexOf(part);
112     Q_ASSERT( index != -1 );
113     removePart(index, deletePart);
114 }
115 
partGroupCount() const116 int Sheet::partGroupCount() const
117 {
118     return d->partGroups.size();
119 }
120 
partGroup(int index)121 PartGroup* Sheet::partGroup(int index)
122 {
123     Q_ASSERT( index >= 0 && index < partGroupCount() );
124     return d->partGroups[index];
125 }
126 
addPartGroup(int firstPart,int lastPart)127 PartGroup* Sheet::addPartGroup(int firstPart, int lastPart)
128 {
129     Q_ASSERT( firstPart >= 0 && firstPart < partCount() );
130     Q_ASSERT( lastPart >= 0 && lastPart < partCount() );
131     PartGroup *group = new PartGroup(this, firstPart, lastPart);
132     d->partGroups.append(group);
133     return group;
134 }
135 
removePartGroup(PartGroup * group,bool deleteGroup)136 void Sheet::removePartGroup(PartGroup* group, bool deleteGroup)
137 {
138     Q_ASSERT( group && group->sheet() == this );
139     int index = d->partGroups.indexOf(group);
140     Q_ASSERT( index != -1 );
141     d->partGroups.removeAt(index);
142     if (deleteGroup) {
143         delete group;
144     }
145 }
146 
barCount() const147 int Sheet::barCount() const
148 {
149     return d->bars.size();
150 }
151 
bar(int index)152 Bar* Sheet::bar(int index)
153 {
154     Q_ASSERT( index >= 0 && index < barCount() );
155     return d->bars[index];
156 }
157 
indexOfBar(Bar * bar)158 int Sheet::indexOfBar(Bar* bar)
159 {
160     Q_ASSERT( bar );
161     return d->bars.indexOf(bar);
162 }
163 
addBars(int count)164 void Sheet::addBars(int count)
165 {
166     for (int i = 0; i < count; i++) {
167 	d->bars.append(new Bar(this));
168     }
169 }
170 
addBar()171 Bar* Sheet::addBar()
172 {
173     Bar* bar = new Bar(this);
174     d->bars.append(bar);
175     return bar;
176 }
177 
insertBar(int before)178 Bar* Sheet::insertBar(int before)
179 {
180     Q_ASSERT( before >= 0 && before <= barCount() );
181     Bar* bar = new Bar(this);
182     d->bars.insert(before, bar);
183     return bar;
184 }
185 
insertBar(int before,Bar * bar)186 void Sheet::insertBar(int before, Bar* bar)
187 {
188     Q_ASSERT( before >= 0 && before <= barCount() );
189     d->bars.insert(before, bar);
190 }
191 
removeBar(int index,bool deleteBar)192 void Sheet::removeBar(int index, bool deleteBar)
193 {
194     Q_ASSERT( index >= 0 && index < barCount() );
195     Bar* bar = d->bars.takeAt(index);
196     if (deleteBar) {
197         delete bar;
198     }
199 }
200 
removeBars(int index,int count,bool deleteBar)201 void Sheet::removeBars(int index, int count, bool deleteBar)
202 {
203     Q_ASSERT( index >= 0 && count > 0 && index + count <= barCount() );
204     for (int i = 0; i < count; i++) {
205         Bar* b = d->bars.takeAt(index);
206         if (deleteBar) {
207             delete b;
208         }
209     }
210 }
211 
staffSystem(int index)212 StaffSystem* Sheet::staffSystem(int index)
213 {
214     Q_ASSERT( index >= 0 );
215     int idx = d->staffSystems.size();
216     qreal ssHeight = 0;
217     if (partCount() > 0) {
218         Part* prt = part(partCount() - 1);
219         ssHeight = prt->staff(prt->staffCount() - 1)->bottom() + 30;
220     }
221     while (index >= d->staffSystems.size()) {
222         StaffSystem *ss = new StaffSystem(this);
223         ss->setHeight(ssHeight);
224         if (idx > 0 && partCount() > 0) {
225             Part* prt = part(partCount() - 1);
226             ss->setTop(d->staffSystems[idx-1]->top() + prt->staff(prt->staffCount() - 1)->bottom() + 30);
227         }
228         d->staffSystems.append(ss);
229         idx++;
230     }
231     return d->staffSystems[index];
232 }
233 
setStaffSystemCount(int count)234 void Sheet::setStaffSystemCount(int count)
235 {
236     Q_ASSERT( count >= 0 );
237     while (count < d->staffSystems.size()) {
238         d->staffSystems.removeLast();
239     }
240 }
241 
staffSystemCount()242 int Sheet::staffSystemCount()
243 {
244     return d->staffSystems.size();
245 }
246 
updateAccidentals()247 void Sheet::updateAccidentals()
248 {
249     foreach (Part* part, d->parts) {
250         for (int i = 0; i < part->staffCount(); i++) {
251             part->staff(i)->updateAccidentals();
252         }
253     }
254 }
255 
256 } // namespace MusicCore
257