Fix angle bracket project-local include paths.
[ardour2.git] / libs / ardour / export_multiplication.cc
bloba0bc7f830eb8e68959403c5330f3f0497f4b2a7b
1 /* This file is not used at the moment. It includes code related to export a
2 * multiplication graph system that can be used together with the ExportMultiplicator
3 * class in the gtk2_ardour folder.
4 * - Sakari Bergen 6.8.2008 -
5 */
7 void
8 ExportProfileManager::register_all_configs ()
10 list<TimespanNodePtr>::iterator tsl_it; // timespan list node iterator
11 for (tsl_it = graph.timespans.begin(); tsl_it != graph.timespans.end(); ++tsl_it) {
12 list<GraphNode *>::const_iterator cc_it; // channel config node iterator
13 for (cc_it = (*tsl_it)->get_children().begin(); cc_it != (*tsl_it)->get_children().end(); ++cc_it) {
14 list<GraphNode *>::const_iterator f_it; // format node iterator
15 for (f_it = (*cc_it)->get_children().begin(); f_it != (*cc_it)->get_children().end(); ++f_it) {
16 list<GraphNode *>::const_iterator fn_it; // filename node iterator
17 for (fn_it = (*f_it)->get_children().begin(); fn_it != (*f_it)->get_children().end(); ++fn_it) {
18 /* Finally loop through each timespan in the timespan list */
20 TimespanNodePtr ts_node;
21 if (!(ts_node = boost::dynamic_pointer_cast<TimespanNode> (*tsl_it))) {
22 throw ExportFailed (X_("Programming error, Invalid pointer cast in ExportProfileManager"));
25 TimespanListPtr ts_list = ts_node->data()->timespans;
26 TimespanList::iterator ts_it;
27 for (ts_it = ts_list->begin(); ts_it != ts_list->end(); ++ts_it) {
29 TimespanPtr timespan = *ts_it;
31 ChannelConfigNode * cc_node;
32 if (!(cc_node = dynamic_cast<ChannelConfigNode *> (*cc_it))) {
33 throw ExportFailed (X_("Programming error, Invalid pointer cast in ExportProfileManager"));
35 ChannelConfigPtr channel_config = cc_node->data()->config;
37 FormatNode * f_node;
38 if (!(f_node = dynamic_cast<FormatNode *> (*f_it))) {
39 throw ExportFailed (X_("Programming error, Invalid pointer cast in ExportProfileManager"));
41 FormatPtr format = f_node->data()->format;
43 FilenameNode * fn_node;
44 if (!(fn_node = dynamic_cast<FilenameNode *> (*fn_it))) {
45 throw ExportFailed (X_("Programming error, Invalid pointer cast in ExportProfileManager"));
47 FilenamePtr filename = fn_node->data()->filename;
49 handler->add_export_config (timespan, channel_config, format, filename);
57 void
58 ExportProfileManager::create_empty_config ()
60 TimespanNodePtr timespan = TimespanNode::create (new TimespanState ());
61 timespan->data()->timespans->push_back (handler->add_timespan());
63 ChannelConfigNodePtr channel_config = ChannelConfigNode::create (new ChannelConfigState(handler->add_channel_config()));
65 FormatNodePtr format;
66 load_formats ();
67 if (!format_list.empty()) {
68 format = FormatNode::create (new FormatState (*format_list.begin ()));
69 } else {
70 format = FormatNode::create (new FormatState (handler->add_format ()));
73 FilenameNodePtr filename = FilenameNode::create (new FilenameState (handler->add_filename()));
75 /* Bring everything together */
77 timespan->add_child (channel_config.get(), 0);
78 channel_config->add_child (format.get(), 0);
79 format->add_child (filename.get(), 0);
81 graph.timespans.push_back (timespan);
82 graph.channel_configs.push_back (channel_config);
83 graph.formats.push_back (format);
84 graph.filenames.push_back (filename);
87 /*** GraphNode ***/
89 uint32_t ExportProfileManager::GraphNode::id_counter = 0;
91 ExportProfileManager::GraphNode::GraphNode ()
93 _id = ++id_counter;
96 ExportProfileManager::GraphNode::~GraphNode ()
98 while (!children.empty()) {
99 remove_child (children.front());
102 while (!parents.empty()) {
103 parents.front()->remove_child (this);
107 void
108 ExportProfileManager::GraphNode::add_parent (GraphNode * parent)
110 for (list<GraphNode *>::iterator it = parents.begin(); it != parents.end(); ++it) {
111 if (*it == parent) {
112 return;
116 parents.push_back (parent);
119 void
120 ExportProfileManager::GraphNode::add_child (GraphNode * child, GraphNode * left_sibling)
122 for (list<GraphNode *>::iterator it = children.begin(); it != children.end(); ++it) {
123 if (*it == child) {
124 return;
128 if (left_sibling) {
129 insert_after (children, left_sibling, child);
130 } else {
131 children.push_back (child);
134 child->add_parent (this);
137 bool
138 ExportProfileManager::GraphNode::is_ancestor_of (GraphNode const * node) const
140 for (list<GraphNode *>::const_iterator it = children.begin(); it != children.end(); ++it) {
141 if (*it == node || (*it)->is_ancestor_of (node)) {
142 return true;
146 return false;
149 bool
150 ExportProfileManager::GraphNode::is_descendant_of (GraphNode const * node) const
152 for (list<GraphNode *>::const_iterator it = parents.begin(); it != parents.end(); ++it) {
153 if (*it == node || (*it)->is_descendant_of (node)) {
154 return true;
158 return false;
161 void
162 ExportProfileManager::GraphNode::select (bool value)
164 if (_selected == value) { return; }
166 _selected = value;
167 SelectChanged (value);
170 void
171 ExportProfileManager::GraphNode::remove_parent (GraphNode * parent)
173 for (list<GraphNode *>::iterator it = parents.begin(); it != parents.end(); ++it) {
174 if (*it == parent) {
175 parents.erase (it);
176 break;
181 void
182 ExportProfileManager::GraphNode::remove_child (GraphNode * child)
184 for (list<GraphNode *>::iterator it = children.begin(); it != children.end(); ++it) {
185 if (*it == child) {
186 children.erase (it);
187 break;
191 child->remove_parent (this);
194 void
195 ExportProfileManager::split_node (GraphNode * node, float position)
197 TimespanNode * ts_node;
198 if ((ts_node = dynamic_cast<TimespanNode *> (node))) {
199 split_timespan (ts_node->self_ptr(), position);
200 return;
203 ChannelConfigNode * cc_node;
204 if ((cc_node = dynamic_cast<ChannelConfigNode *> (node))) {
205 split_channel_config (cc_node->self_ptr(), position);
206 return;
209 FormatNode * f_node;
210 if ((f_node = dynamic_cast<FormatNode *> (node))) {
211 split_format (f_node->self_ptr(), position);
212 return;
215 FilenameNode * fn_node;
216 if ((fn_node = dynamic_cast<FilenameNode *> (node))) {
217 split_filename (fn_node->self_ptr(), position);
218 return;
222 void
223 ExportProfileManager::remove_node (GraphNode * node)
225 TimespanNode * ts_node;
226 if ((ts_node = dynamic_cast<TimespanNode *> (node))) {
227 remove_timespan (ts_node->self_ptr());
228 return;
231 ChannelConfigNode * cc_node;
232 if ((cc_node = dynamic_cast<ChannelConfigNode *> (node))) {
233 remove_channel_config (cc_node->self_ptr());
234 return;
237 FormatNode * f_node;
238 if ((f_node = dynamic_cast<FormatNode *> (node))) {
239 remove_format (f_node->self_ptr());
240 return;
243 FilenameNode * fn_node;
244 if ((fn_node = dynamic_cast<FilenameNode *> (node))) {
245 remove_filename (fn_node->self_ptr());
246 return;
250 void
251 ExportProfileManager::purge_graph ()
253 for (list<TimespanNodePtr>::iterator it = graph.timespans.begin(); it != graph.timespans.end(); ) {
254 list<TimespanNodePtr>::iterator tmp = it;
255 ++it;
257 if ((*tmp)->get_children().empty()) {
258 graph.timespans.erase (tmp);
262 for (list<ChannelConfigNodePtr>::iterator it = graph.channel_configs.begin(); it != graph.channel_configs.end(); ) {
263 list<ChannelConfigNodePtr>::iterator tmp = it;
264 ++it;
266 if ((*tmp)->get_parents().empty()) {
267 graph.channel_configs.erase (tmp);
271 for (list<FormatNodePtr>::iterator it = graph.formats.begin(); it != graph.formats.end(); ) {
272 list<FormatNodePtr>::iterator tmp = it;
273 ++it;
275 if ((*tmp)->get_parents().empty()) {
276 graph.formats.erase (tmp);
280 for (list<FilenameNodePtr>::iterator it = graph.filenames.begin(); it != graph.filenames.end(); ) {
281 list<FilenameNodePtr>::iterator tmp = it;
282 ++it;
284 if ((*tmp)->get_parents().empty()) {
285 graph.filenames.erase (tmp);
289 GraphChanged();
292 template<typename T>
293 void
294 ExportProfileManager::insert_after (list<T> & the_list, T const & position, T const & element)
296 typename list<T>::iterator it;
297 for (it = the_list.begin(); it != the_list.end(); ++it) {
298 if (*it == position) {
299 the_list.insert (++it, element);
300 return;
304 std::cerr << "invalid position given to ExportProfileManager::insert_after (aborting)" << std::endl;
306 abort();
309 template<typename T>
310 void
311 ExportProfileManager::remove_by_element (list<T> & the_list, T const & element)
313 typename list<T>::iterator it;
314 for (it = the_list.begin(); it != the_list.end(); ++it) {
315 if (*it == element) {
316 the_list.erase (it);
317 return;
322 bool
323 ExportProfileManager::nodes_have_one_common_child (list<GraphNode *> const & the_list)
325 return end_of_common_child_range (the_list, the_list.begin()) == --the_list.end();
328 list<ExportProfileManager::GraphNode *>::const_iterator
329 ExportProfileManager::end_of_common_child_range (list<GraphNode *> const & the_list, list<GraphNode *>::const_iterator beginning)
331 if ((*beginning)->get_children().size() != 1) { return beginning; }
332 GraphNode * child = (*beginning)->get_children().front();
334 list<GraphNode *>::const_iterator it = beginning;
335 while (it != the_list.end() && (*it)->get_children().size() == 1 && (*it)->get_children().front() == child) {
336 ++it;
339 return --it;
342 void
343 ExportProfileManager::split_node_at_position (GraphNode * old_node, GraphNode * new_node, float position)
345 list<GraphNode *> const & node_parents = old_node->get_parents();
346 uint32_t split_index = (int) (node_parents.size() * position + 0.5);
347 split_index = std::max ((uint32_t) 1, std::min (split_index, node_parents.size() - 1));
349 list<GraphNode *>::const_iterator it = node_parents.begin();
350 for (uint32_t index = 1; it != node_parents.end(); ++index) {
351 if (index > split_index) {
352 list<GraphNode *>::const_iterator tmp = it++;
353 (*tmp)->add_child (new_node, old_node);
354 (*tmp)->remove_child (old_node);
355 } else {
356 ++it;
361 void
362 ExportProfileManager::split_timespan (TimespanNodePtr node, float)
364 TimespanNodePtr new_timespan = duplicate_timespan_node (node);
365 insert_after (graph.timespans, node, new_timespan);
367 /* Note: Since a timespan selector allows all combinations of ranges
368 * there is no reason for a channel configuration to have two parents
371 duplicate_timespan_children (node->self_ptr(), new_timespan);
373 GraphChanged();
376 void
377 ExportProfileManager::split_channel_config (ChannelConfigNodePtr node, float)
379 ChannelConfigNodePtr new_config = duplicate_channel_config_node (node);
380 insert_after (graph.channel_configs, node, new_config);
382 /* Channel configs have only one parent, see above! */
383 node->get_parents().front()->add_child (new_config.get(), node.get());
385 if (node->get_children().size() == 1) {
386 new_config->add_child (node->first_child(), 0);
387 } else {
388 duplicate_channel_config_children (node, new_config);
391 GraphChanged();
394 void
395 ExportProfileManager::split_format (FormatNodePtr node, float position)
397 FormatNodePtr new_format = duplicate_format_node (node);
398 insert_after (graph.formats, node, new_format);
400 list<GraphNode *> const & node_parents = node->get_parents();
401 if (node_parents.size() == 1) {
402 node_parents.front()->add_child (new_format.get(), 0);
403 } else {
404 node->sort_parents (graph.channel_configs);
405 split_node_at_position (node.get(), new_format.get(), position);
408 if (node->get_children().size() == 1) {
409 new_format->add_child (node->first_child(), 0);
410 } else {
411 duplicate_format_children (node, new_format);
414 GraphChanged();
417 void
418 ExportProfileManager::split_filename (FilenameNodePtr node, float position)
420 FilenameNodePtr new_filename = duplicate_filename_node (node);
421 insert_after (graph.filenames, node, new_filename);
423 list<GraphNode *> const & node_parents = node->get_parents();
425 if (node_parents.size() == 1) {
426 node_parents.front()->add_child (new_filename.get(), 0);
427 } else {
428 node->sort_parents (graph.formats);
429 split_node_at_position (node.get(), new_filename.get(), position);
432 GraphChanged();
435 void
436 ExportProfileManager::duplicate_timespan_children (TimespanNodePtr source, TimespanNodePtr target, GraphNode * insertion_point)
438 list<GraphNode *> const & source_children = source->get_children();
439 bool one_grandchild = nodes_have_one_common_child (source_children);
440 GraphNode * child_insertion_point = 0;
442 ChannelConfigNodePtr node_insertion_point;
443 ChannelConfigNode * node_insertion_ptr;
444 if (!insertion_point) { insertion_point = source->last_child(); }
445 if (!(node_insertion_ptr = dynamic_cast<ChannelConfigNode *> (insertion_point))) {
446 throw ExportFailed (X_("Programming error, Invalid pointer cast in ExportProfileManager"));
448 node_insertion_point = node_insertion_ptr->self_ptr();
450 /* Keep track of common children */
452 list<GraphNode *>::const_iterator common_children_begin = source_children.begin();
453 list<GraphNode *>::const_iterator common_children_end = end_of_common_child_range (source_children, source_children.begin());
454 GraphNode * common_child = 0;
456 for (list<GraphNode *>::const_iterator it = source_children.begin(); it != source_children.end(); ++it) {
457 /* Duplicate node */
459 ChannelConfigNode * node;
460 ChannelConfigNodePtr new_node;
462 if (!(node = dynamic_cast<ChannelConfigNode *> (*it))) {
463 throw ExportFailed (X_("Programming error, Invalid pointer cast in ExportProfileManager"));
466 new_node = duplicate_channel_config_node (node->self_ptr());
468 /* Insert in gaph's list and update insertion position */
470 insert_after (graph.channel_configs, node_insertion_point, new_node);
471 node_insertion_point = new_node;
473 /* Handle children */
475 target->add_child (new_node.get(), child_insertion_point);
476 child_insertion_point = new_node.get();
478 if (one_grandchild) {
479 new_node->add_child (node->first_child(), 0);
480 } else {
481 list<GraphNode *>::const_iterator past_end = common_children_end;
482 if (it == ++past_end) { // At end => start new range
483 common_children_begin = it;
484 common_children_end = end_of_common_child_range (source_children, it);
487 if (it == common_children_begin) { // At beginning => do duplication
488 GraphNode * grand_child_ins_pt = common_child;
489 if (!grand_child_ins_pt) {
490 grand_child_ins_pt = source->last_child()->last_child();
492 duplicate_channel_config_children (node->self_ptr(), new_node, grand_child_ins_pt);
493 common_child = new_node->first_child();
494 } else { // Somewhere in between end and beginning => share child
495 new_node->add_child (common_child, 0);
501 void
502 ExportProfileManager::duplicate_channel_config_children (ChannelConfigNodePtr source, ChannelConfigNodePtr target, GraphNode * insertion_point)
504 list<GraphNode *> const & source_children = source->get_children();
505 bool one_grandchild = nodes_have_one_common_child (source_children);
506 GraphNode * child_insertion_point = 0;
508 FormatNodePtr node_insertion_point;
509 FormatNode * node_insertion_ptr;
510 if (!insertion_point) { insertion_point = source->last_child(); }
511 if (!(node_insertion_ptr = dynamic_cast<FormatNode *> (insertion_point))) {
512 throw ExportFailed (X_("Programming error, Invalid pointer cast in ExportProfileManager"));
514 node_insertion_point = node_insertion_ptr->self_ptr();
516 /* Keep track of common children */
518 list<GraphNode *>::const_iterator common_children_begin = source_children.begin();
519 list<GraphNode *>::const_iterator common_children_end = end_of_common_child_range (source_children, source_children.begin());
520 GraphNode * common_child = 0;
522 for (list<GraphNode *>::const_iterator it = source_children.begin(); it != source_children.end(); ++it) {
523 /* Duplicate node */
525 FormatNode * node;
526 FormatNodePtr new_node;
528 if (!(node = dynamic_cast<FormatNode *> (*it))) {
529 throw ExportFailed (X_("Programming error, Invalid pointer cast in ExportProfileManager"));
532 new_node = duplicate_format_node (node->self_ptr());
534 /* Insert in gaph's list and update insertion position */
536 insert_after (graph.formats, node_insertion_point, new_node);
537 node_insertion_point = new_node;
539 /* Handle children */
541 target->add_child (new_node.get(), child_insertion_point);
542 child_insertion_point = new_node.get();
544 if (one_grandchild) {
545 new_node->add_child (node->first_child(), 0);
546 } else {
547 list<GraphNode *>::const_iterator past_end = common_children_end;
548 if (it == ++past_end) { // At end => start new range
549 common_children_begin = it;
550 common_children_end = end_of_common_child_range (source_children, it);
553 if (it == common_children_begin) { // At beginning => do duplication
554 GraphNode * grand_child_ins_pt = common_child;
555 if (!grand_child_ins_pt) {
556 grand_child_ins_pt = source->get_parents().back()->last_child()->last_child()->last_child();
558 duplicate_format_children (node->self_ptr(), new_node, grand_child_ins_pt);
559 common_child = new_node->first_child();
560 } else { // Somewhere in between end and beginning => share child
561 new_node->add_child (common_child, 0);
567 void
568 ExportProfileManager::duplicate_format_children (FormatNodePtr source, FormatNodePtr target, GraphNode * insertion_point)
570 GraphNode * child_insertion_point = 0;
572 FilenameNodePtr node_insertion_point;
573 FilenameNode * node_insertion_ptr;
574 if (!insertion_point) { insertion_point = source->last_child(); }
575 if (!(node_insertion_ptr = dynamic_cast<FilenameNode *> (insertion_point))) {
576 throw ExportFailed (X_("Programming error, Invalid pointer cast in ExportProfileManager"));
578 node_insertion_point = node_insertion_ptr->self_ptr();
580 for (list<GraphNode *>::const_iterator it = source->get_children().begin(); it != source->get_children().end(); ++it) {
581 /* Duplicate node */
583 FilenameNode * node;
584 FilenameNodePtr new_node;
586 if (!(node = dynamic_cast<FilenameNode *> (*it))) {
587 throw ExportFailed (X_("Programming error, Invalid pointer cast in ExportProfileManager"));
590 new_node = duplicate_filename_node (node->self_ptr());
592 /* Insert in gaph's list and update insertion position */
594 insert_after (graph.filenames, node_insertion_point, new_node);
595 node_insertion_point = new_node;
597 /* Handle children */
599 target->add_child (new_node.get(), child_insertion_point);
600 child_insertion_point = new_node.get();
604 ExportProfileManager::TimespanNodePtr
605 ExportProfileManager::duplicate_timespan_node (TimespanNodePtr node)
607 TimespanStatePtr state = node->data();
608 TimespanStatePtr new_state (new TimespanState ());
609 TimespanNodePtr new_node = TimespanNode::create (new_state);
611 for (TimespanList::iterator it = state->timespans->begin(); it != state->timespans->end(); ++it) {
612 new_state->timespans->push_back (handler->add_timespan_copy (*it));
615 new_state->time_format = state->time_format;
616 new_state->marker_format = state->marker_format;
618 return new_node;
621 ExportProfileManager::ChannelConfigNodePtr
622 ExportProfileManager::duplicate_channel_config_node (ChannelConfigNodePtr node)
624 ChannelConfigStatePtr state = node->data();
625 ChannelConfigStatePtr new_state (new ChannelConfigState (handler->add_channel_config_copy (state->config)));
626 ChannelConfigNodePtr new_node = ChannelConfigNode::create (new_state);
628 return new_node;
631 ExportProfileManager::FormatNodePtr
632 ExportProfileManager::duplicate_format_node (FormatNodePtr node)
634 FormatStatePtr state = node->data();
635 FormatStatePtr new_state (new FormatState (handler->add_format_copy (state->format)));
636 FormatNodePtr new_node = FormatNode::create (new_state);
638 return new_node;
641 ExportProfileManager::FilenameNodePtr
642 ExportProfileManager::duplicate_filename_node (FilenameNodePtr node)
644 FilenameStatePtr state = node->data();
645 FilenameStatePtr new_state (new FilenameState (handler->add_filename_copy (state->filename)));
646 FilenameNodePtr new_node = FilenameNode::create (new_state);
648 return new_node;
651 void
652 ExportProfileManager::remove_timespan (TimespanNodePtr node)
654 remove_by_element (graph.timespans, node);
655 purge_graph ();
658 void
659 ExportProfileManager::remove_channel_config (ChannelConfigNodePtr node)
661 remove_by_element (graph.channel_configs, node);
662 purge_graph ();
665 void
666 ExportProfileManager::remove_format (FormatNodePtr node)
668 remove_by_element (graph.formats, node);
669 purge_graph ();
672 void
673 ExportProfileManager::remove_filename (FilenameNodePtr node)
675 remove_by_element (graph.filenames, node);
676 purge_graph ();