]> git.tdb.fi Git - r2c2.git/blob - source/libr2c2/zone.cpp
Add support for named zones
[r2c2.git] / source / libr2c2 / zone.cpp
1 /* $Id$
2
3 This file is part of R²C²
4 Copyright © 2010  Mikkosoft Productions, Mikko Rasa
5 Distributed under the GPL
6 */
7
8 #include <msp/strings/formatter.h>
9 #include "block.h"
10 #include "layout.h"
11 #include "track.h"
12 #include "zone.h"
13
14 using namespace std;
15 using namespace Msp;
16
17 namespace R2C2 {
18
19 Zone::Zone(Layout &l):
20         layout(l),
21         number(0)
22 {
23         layout.add_zone(*this);
24 }
25
26 Zone::~Zone()
27 {
28         layout.remove_zone(*this);
29 }
30
31 void Zone::set_name(const string &g, const string &q, unsigned n)
32 {
33         group = g;
34         qualifier = q;
35         number = n;
36
37         signal_name_changed.emit(group, qualifier, number);
38 }
39
40 string Zone::get_name() const
41 {
42         string result = group;
43         if(!qualifier.empty())
44         {
45                 result += ' ';
46                 result += qualifier;
47         }
48         if(number)
49                 result += format(" %d", number);
50         return result;
51 }
52
53 void Zone::add_track(Track &track)
54 {
55         if(!is_valid(track))
56                 throw InvalidParameterValue("Can't add track to zone");
57
58         tracks.insert(&track);
59 }
60
61 bool Zone::add_tracks(const TrackSet &trks)
62 {
63         TrackSet pending = trks;
64         bool first = true;
65         while(1)
66         {
67                 bool ok = false;
68                 for(TrackSet::const_iterator i=pending.begin(); i!=pending.end(); ++i)
69                         if(is_valid(**i))
70                         {
71                                 tracks.insert(*i);
72                                 pending.erase(i);
73                                 ok = true;
74                                 break;
75                         }
76
77                 if(!ok)
78                 {
79                         if(first)
80                                 throw InvalidParameterValue("Cound not add any tracks to zone");
81                         return pending.empty();
82                 }
83
84                 first = false;
85         }
86 }
87
88 void Zone::save(list<DataFile::Statement> &st) const
89 {
90         st.push_back((DataFile::Statement("group"), group));
91         if(!qualifier.empty())
92                 st.push_back((DataFile::Statement("qualifier"), qualifier));
93         if(number)
94                 st.push_back((DataFile::Statement("number"), number));
95
96         set<unsigned> block_ids;
97         for(TrackSet::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
98                 block_ids.insert((*i)->get_block().get_id());
99
100         for(set<unsigned>::const_iterator i=block_ids.begin(); i!=block_ids.end(); ++i)
101                 st.push_back((DataFile::Statement("block"), *i));
102 }
103
104 bool Zone::is_valid(Track &t) const
105 {
106         if(tracks.empty())
107                 return true;
108
109         const vector<Track *> &links = t.get_links();
110         for(vector<Track *>::const_iterator i=links.begin(); i!=links.end(); ++i)
111                 if(*i && tracks.count(*i))
112                         return true;
113
114         return false;
115 }
116
117
118 Zone::Loader::Loader(Zone &z):
119         DataFile::ObjectLoader<Zone>(z)
120 {
121         add("block",     &Loader::block);
122         add("group",     &Zone::group);
123         add("number",    &Zone::number);
124         add("qualifier", &Zone::qualifier);
125 }
126
127 void Zone::Loader::block(unsigned b)
128 {
129         Block &blk = obj.layout.get_block(b);
130         const set<Track *> &btracks = blk.get_tracks();
131         obj.tracks.insert(btracks.begin(), btracks.end());
132 }
133
134 } // namespace R2C2