+template <class T>
+int
+place (TimelineViewList& views, int& tracks)
+{
+ int const base = tracks;
+
+ BOOST_FOREACH (shared_ptr<TimelineView> i, views) {
+ if (!dynamic_pointer_cast<T>(i)) {
+ continue;
+ }
+
+ shared_ptr<TimelineContentView> cv = dynamic_pointer_cast<TimelineContentView> (i);
+
+ int t = base;
+
+ shared_ptr<Content> content = cv->content();
+ DCPTimePeriod const content_period (content->position(), content->end());
+
+ while (true) {
+ TimelineViewList::iterator j = views.begin();
+ while (j != views.end()) {
+ shared_ptr<T> test = dynamic_pointer_cast<T> (*j);
+ if (!test) {
+ ++j;
+ continue;
+ }
+
+ shared_ptr<Content> test_content = test->content();
+ if (
+ test->track() && test->track().get() == t &&
+ content_period.overlap(DCPTimePeriod(test_content->position(), test_content->end()))) {
+ /* we have an overlap on track `t' */
+ ++t;
+ break;
+ }
+
+ ++j;
+ }
+
+ if (j == views.end ()) {
+ /* no overlap on `t' */
+ break;
+ }
+ }
+
+ cv->set_track (t);
+ tracks = max (tracks, t + 1);
+ }
+
+ return tracks - base;
+}
+