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 -
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
;
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
);
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()));
67 if (!format_list
.empty()) {
68 format
= FormatNode::create (new FormatState (*format_list
.begin ()));
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
);
89 uint32_t ExportProfileManager::GraphNode::id_counter
= 0;
91 ExportProfileManager::GraphNode::GraphNode ()
96 ExportProfileManager::GraphNode::~GraphNode ()
98 while (!children
.empty()) {
99 remove_child (children
.front());
102 while (!parents
.empty()) {
103 parents
.front()->remove_child (this);
108 ExportProfileManager::GraphNode::add_parent (GraphNode
* parent
)
110 for (list
<GraphNode
*>::iterator it
= parents
.begin(); it
!= parents
.end(); ++it
) {
116 parents
.push_back (parent
);
120 ExportProfileManager::GraphNode::add_child (GraphNode
* child
, GraphNode
* left_sibling
)
122 for (list
<GraphNode
*>::iterator it
= children
.begin(); it
!= children
.end(); ++it
) {
129 insert_after (children
, left_sibling
, child
);
131 children
.push_back (child
);
134 child
->add_parent (this);
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
)) {
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
)) {
162 ExportProfileManager::GraphNode::select (bool value
)
164 if (_selected
== value
) { return; }
167 SelectChanged (value
);
171 ExportProfileManager::GraphNode::remove_parent (GraphNode
* parent
)
173 for (list
<GraphNode
*>::iterator it
= parents
.begin(); it
!= parents
.end(); ++it
) {
182 ExportProfileManager::GraphNode::remove_child (GraphNode
* child
)
184 for (list
<GraphNode
*>::iterator it
= children
.begin(); it
!= children
.end(); ++it
) {
191 child
->remove_parent (this);
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
);
203 ChannelConfigNode
* cc_node
;
204 if ((cc_node
= dynamic_cast<ChannelConfigNode
*> (node
))) {
205 split_channel_config (cc_node
->self_ptr(), position
);
210 if ((f_node
= dynamic_cast<FormatNode
*> (node
))) {
211 split_format (f_node
->self_ptr(), position
);
215 FilenameNode
* fn_node
;
216 if ((fn_node
= dynamic_cast<FilenameNode
*> (node
))) {
217 split_filename (fn_node
->self_ptr(), position
);
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());
231 ChannelConfigNode
* cc_node
;
232 if ((cc_node
= dynamic_cast<ChannelConfigNode
*> (node
))) {
233 remove_channel_config (cc_node
->self_ptr());
238 if ((f_node
= dynamic_cast<FormatNode
*> (node
))) {
239 remove_format (f_node
->self_ptr());
243 FilenameNode
* fn_node
;
244 if ((fn_node
= dynamic_cast<FilenameNode
*> (node
))) {
245 remove_filename (fn_node
->self_ptr());
251 ExportProfileManager::purge_graph ()
253 for (list
<TimespanNodePtr
>::iterator it
= graph
.timespans
.begin(); it
!= graph
.timespans
.end(); ) {
254 list
<TimespanNodePtr
>::iterator tmp
= 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
;
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
;
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
;
284 if ((*tmp
)->get_parents().empty()) {
285 graph
.filenames
.erase (tmp
);
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
);
304 std::cerr
<< "invalid position given to ExportProfileManager::insert_after (aborting)" << std::endl
;
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
) {
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
) {
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
);
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
);
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);
388 duplicate_channel_config_children (node
, new_config
);
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);
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);
411 duplicate_format_children (node
, new_format
);
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);
428 node
->sort_parents (graph
.formats
);
429 split_node_at_position (node
.get(), new_filename
.get(), position
);
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
) {
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);
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);
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
) {
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);
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);
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
) {
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
;
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
);
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
);
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
);
652 ExportProfileManager::remove_timespan (TimespanNodePtr node
)
654 remove_by_element (graph
.timespans
, node
);
659 ExportProfileManager::remove_channel_config (ChannelConfigNodePtr node
)
661 remove_by_element (graph
.channel_configs
, node
);
666 ExportProfileManager::remove_format (FormatNodePtr node
)
668 remove_by_element (graph
.formats
, node
);
673 ExportProfileManager::remove_filename (FilenameNodePtr node
)
675 remove_by_element (graph
.filenames
, node
);