8#include "FlyToEditWidget.h"
9#include "TourControlEditWidget.h"
10#include "WaitEditWidget.h"
11#include "SoundCueEditWidget.h"
12#include "TourItemDelegate.h"
14#include "ui_TourWidget.h"
15#include "GeoDataPlacemark.h"
16#include "GeoDataDocument.h"
17#include "GeoDataLookAt.h"
18#include "GeoDataPlaylist.h"
19#include "GeoDataTour.h"
20#include "GeoDataTreeModel.h"
21#include "GeoDataFlyTo.h"
22#include "GeoDataWait.h"
23#include "GeoDataCamera.h"
24#include "GeoDataTourControl.h"
25#include "GeoDataSoundCue.h"
26#include "GeoDataCreate.h"
27#include "GeoDataUpdate.h"
28#include "GeoDataDelete.h"
29#include "GeoDataChange.h"
30#include "GeoDataAnimatedUpdate.h"
31#include "GeoDataDocumentWriter.h"
32#include "KmlElementDictionary.h"
34#include "MarblePlacemarkModel.h"
36#include "ParsingRunnerManager.h"
37#include "TourPlayback.h"
38#include "MovieCapture.h"
39#include "TourCaptureDialog.h"
40#include "MarbleDebug.h"
41#include "PlaybackFlyToItem.h"
42#include "EditPlacemarkDialog.h"
43#include "MarbleDirs.h"
44#include "GeoDataStyle.h"
45#include "GeoDataIconStyle.h"
62class TourWidgetPrivate
66 explicit TourWidgetPrivate( TourWidget *parent );
68 GeoDataFeature *getPlaylistFeature()
const;
69 void updateRootIndex();
73 bool openFile(
const QString &filename );
82 void addRemovePlacemark();
83 void addChangePlacemark();
84 void addTourPrimitive(GeoDataTourPrimitive *primitive );
85 void deleteSelected();
86 void updateButtonsStates();
90 void handlePlaybackProgress(
const double position );
91 void handlePlaybackFinish();
92 GeoDataObject *rootIndexObject()
const;
95 GeoDataTour* findTour( GeoDataFeature* feature )
const;
96 bool openDocument( GeoDataDocument *document );
97 bool saveTourAs(
const QString &filename );
98 bool overrideModifications();
102 MarbleWidget *m_widget;
103 Ui::TourWidget m_tourUi;
104 TourCaptureDialog *m_tourCaptureDialog;
105 TourPlayback m_playback;
106 TourItemDelegate *m_delegate;
109 bool m_isLoopingStopped;
110 GeoDataDocument* m_document;
111 QAction *m_actionToggleLoopPlay;
117 QAction *m_actionAddRemovePlacemark;
118 QAction *m_actionAddChangePlacemark;
121TourWidgetPrivate::TourWidgetPrivate( TourWidget *parent )
124 m_playback( nullptr ),
125 m_delegate( nullptr ),
126 m_isChanged( false ),
127 m_playState( false ),
128 m_document( nullptr ),
131 m_tourUi.setupUi( parent );
132 m_tourUi.m_actionRecord->setEnabled(
false );
134 QAction *separator = m_tourUi.m_toolBarControl->insertSeparator( m_tourUi.m_actionMoveUp );
136 m_addPrimitiveButton->
setIcon(
QIcon(QStringLiteral(
":/marble/flag.png")));
137 m_addPrimitiveButton->setToolTip(
QObject::tr(
"Add FlyTo" ) );
142 m_actionAddFlyTo =
new QAction(
QIcon(QStringLiteral(
":/marble/flag.png")),
QObject::tr(
"Add FlyTo"), addPrimitiveMenu);
143 addPrimitiveMenu->
addAction( m_actionAddFlyTo );
144 m_actionAddWait =
new QAction(
QIcon(QStringLiteral(
":/marble/player-time.png")),
QObject::tr(
"Add Wait"), addPrimitiveMenu);
145 addPrimitiveMenu->
addAction( m_actionAddWait );
146 m_actionAddSoundCue =
new QAction(
QIcon(QStringLiteral(
":/marble/audio-x-generic.png")),
QObject::tr(
"Add SoundCue"), addPrimitiveMenu);
147 addPrimitiveMenu->
addAction( m_actionAddSoundCue );
149 m_actionAddPlacemark =
new QAction(
QIcon(QStringLiteral(
":/icons/add-placemark.png")),
QObject::tr(
"Add Placemark"), addPrimitiveMenu);
150 addPrimitiveMenu->
addAction( m_actionAddPlacemark );
151 m_actionAddRemovePlacemark =
new QAction(
QIcon(QStringLiteral(
":/icons/remove.png")),
QObject::tr(
"Remove placemark"), addPrimitiveMenu);
152 addPrimitiveMenu->
addAction( m_actionAddRemovePlacemark );
153 m_actionAddChangePlacemark =
new QAction(
QIcon(QStringLiteral(
":/marble/document-edit.png")),
QObject::tr(
"Change placemark"), addPrimitiveMenu);
154 addPrimitiveMenu->
addAction( m_actionAddChangePlacemark );
156 m_actionToggleLoopPlay->setCheckable(
true );
157 m_actionToggleLoopPlay->setChecked(
false );
159 m_tourUi.m_slider->addAction( m_actionToggleLoopPlay );
161 m_addPrimitiveButton->setMenu( addPrimitiveMenu );
162 m_addPrimitiveButton->setEnabled(
false );
164 m_tourUi.m_toolBarControl->insertWidget( separator, m_addPrimitiveButton );
167 QObject::connect( m_addPrimitiveButton, SIGNAL(clicked()), q, SLOT(addFlyTo()) );
168 QObject::connect( m_actionAddFlyTo, SIGNAL(triggered()), q, SLOT(addFlyTo()) );
169 QObject::connect( m_actionAddWait, SIGNAL(triggered()), q, SLOT(addWait()) );
170 QObject::connect( m_actionAddSoundCue, SIGNAL(triggered()), q, SLOT(addSoundCue()) );
171 QObject::connect( m_actionAddPlacemark, SIGNAL(triggered()), q, SLOT(addPlacemark()) );
172 QObject::connect( m_actionAddRemovePlacemark, SIGNAL(triggered()), q, SLOT(addRemovePlacemark()) );
173 QObject::connect( m_actionAddChangePlacemark, SIGNAL(triggered()), q, SLOT(addChangePlacemark()) );
174 QObject::connect( m_tourUi.m_actionDelete, SIGNAL(triggered()), q, SLOT(deleteSelected()) );
175 QObject::connect( m_tourUi.m_actionMoveUp, SIGNAL(triggered()), q, SLOT(moveUp()) );
176 QObject::connect( m_tourUi.m_actionMoveDown, SIGNAL(triggered()), q, SLOT(moveDown()) );
177 QObject::connect( m_tourUi.m_actionNewTour, SIGNAL(triggered()), q, SLOT(createTour()) );
178 QObject::connect( m_tourUi.m_actionOpenTour, SIGNAL(triggered()), q, SLOT(openFile()) );
179 QObject::connect( m_tourUi.m_actionSaveTour, SIGNAL(triggered()), q, SLOT(saveTour()) );
180 QObject::connect( m_tourUi.m_actionSaveTourAs, SIGNAL(triggered()), q, SLOT(saveTourAs()) );
181 QObject::connect( m_tourUi.m_actionRecord, SIGNAL(triggered()), q, SLOT(captureTour()) );
182 QObject::connect( &m_playback, SIGNAL(finished()), q, SLOT(stopPlaying()) );
183 QObject::connect( &m_playback, SIGNAL(itemFinished(
int)), q, SLOT(setHighlightedItemIndex(
int)) );
187TourWidgetPrivate::~TourWidgetPrivate()
194 d( new TourWidgetPrivate( this ) )
196 layout()->setMargin( 0 );
198 connect( d->m_tourUi.actionPlay, SIGNAL(triggered()),
199 this, SLOT(togglePlaying()) );
200 connect( d->m_tourUi.actionStop, SIGNAL(triggered()),
201 this, SLOT(stopLooping()) );
202 connect( d->m_tourUi.actionStop, SIGNAL(triggered()),
203 this, SLOT(stopPlaying()) );
204 connect( d->m_tourUi.m_slider, SIGNAL(sliderMoved(
int)),
205 this, SLOT(handleSliderMove(
int)) );
207 d->m_tourUi.m_toolBarPlayback->setDisabled(
true );
208 d->m_tourUi.m_slider->setDisabled(
true );
209 d->m_tourUi.m_listView->installEventFilter(
this );
212TourWidget::~TourWidget()
217bool TourWidget::eventFilter(
QObject *watched,
QEvent *event )
221 Q_ASSERT( watched == d->m_tourUi.m_listView );
222 GeoDataObject *rootObject = d->rootIndexObject();
230 QModelIndexList selectedIndexes = d->m_tourUi.m_listView->selectionModel()->selectedIndexes();
233 if ( !selectedIndexes.isEmpty() ) {
240 && !selectedIndexes.isEmpty() )
242 QModelIndexList::iterator
end = selectedIndexes.end() - 1;
243 if (
const GeoDataPlaylist *playlist = (rootObject ? geodata_cast<GeoDataPlaylist>(rootObject) : nullptr)) {
244 if (
end->row() != playlist->size() - 1 ) {
252 && !selectedIndexes.isEmpty() )
254 QModelIndexList::iterator
start = selectedIndexes.begin();
255 if (
start->row() != 0 ) {
265void TourWidget::setMarbleWidget( MarbleWidget *widget )
267 d->m_widget = widget;
268 delete d->m_delegate;
269 d->m_delegate =
new TourItemDelegate( d->m_tourUi.m_listView, d->m_widget,
this );
271 connect( d->m_delegate, SIGNAL(edited(
QModelIndex)), &d->m_playback, SLOT(updateTracks()) );
272 d->m_tourUi.m_listView->setItemDelegate( d->m_delegate );
275void TourWidget::togglePlaying()
277 if( !d->m_playState ){
278 d->m_playState =
true;
281 d->m_playState =
false;
286void TourWidget::startPlaying()
288 setHighlightedItemIndex( 0 );
289 d->m_isLoopingStopped =
false;
290 d->m_playback.play();
291 d->m_tourUi.actionPlay->setIcon(
QIcon(QStringLiteral(
":/marble/playback-pause.png")));
292 d->m_tourUi.actionPlay->setEnabled(
true );
293 d->m_tourUi.actionStop->setEnabled(
true );
294 d->m_tourUi.m_actionRecord->setEnabled(
false );
295 d->m_delegate->setEditable(
false );
296 d->m_addPrimitiveButton->setEnabled(
false );
297 d->m_playState =
true;
300void TourWidget::pausePlaying()
302 d->m_playback.pause();
303 d->m_tourUi.actionPlay->setIcon(
QIcon(QStringLiteral(
":/marble/playback-play.png")));
304 d->m_tourUi.actionPlay->setEnabled(
true );
305 d->m_tourUi.actionStop->setEnabled(
true );
308void TourWidget::stopPlaying()
311 d->m_playback.stop();
312 d->m_tourUi.actionPlay->setIcon(
QIcon(QStringLiteral(
":/marble/playback-play.png")));
313 d->m_tourUi.actionPlay->setEnabled(
true );
314 d->m_tourUi.m_actionRecord->setEnabled(
true );
315 d->m_tourUi.actionStop->setEnabled(
false );
316 d->m_playState =
false;
317 d->m_delegate->setEditable(
true );
318 d->m_addPrimitiveButton->setEnabled(
true );
321 if ( d->m_actionToggleLoopPlay->isChecked() && !d->m_isLoopingStopped ) {
326void TourWidget::stopLooping()
328 d->m_isLoopingStopped =
true;
333 if ( !d->m_document || !d->m_isChanged ) {
340 QObject::tr(
"There are unsaved Tours. Do you want to save your changes?" ),
356void TourWidget::handleSliderMove(
int value )
359 d->m_playback.seek( value / 100.0 );
360 QTime nullTime( 0, 0, 0 );
365void TourWidgetPrivate::openFile()
367 if ( overrideModifications() ) {
370 ParsingRunnerManager manager( m_widget->model()->pluginManager() );
371 GeoDataDocument* document = manager.openFile( filename );
373 openDocument( document );
378bool TourWidgetPrivate::openFile(
const QString &filename )
380 if ( overrideModifications() ) {
382 ParsingRunnerManager manager( m_widget->model()->pluginManager() );
383 GeoDataDocument* document = manager.openFile( filename );
385 return openDocument( document );
392GeoDataTour *TourWidgetPrivate::findTour( GeoDataFeature *feature )
const
394 if (GeoDataTour *tour = (feature ? geodata_cast<GeoDataTour>(feature) : nullptr)) {
398 GeoDataContainer *container =
dynamic_cast<GeoDataContainer*
>( feature );
402 for( ; iter !=
end; ++iter ) {
403 GeoDataTour *tour = findTour( *iter );
412void TourWidgetPrivate::mapCenterOn(
const QModelIndex &index )
414 QVariant coordinatesVariant = m_widget->model()->treeModel()->
data( index, MarblePlacemarkModel::CoordinateRole );
415 if ( !coordinatesVariant.
isNull() ) {
416 GeoDataCoordinates
const coordinates = coordinatesVariant.
value<GeoDataCoordinates>();
417 GeoDataLookAt lookat;
418 lookat.setCoordinates( coordinates );
419 lookat.setRange( coordinates.altitude() );
420 m_widget->flyTo( lookat, Instant );
424void TourWidgetPrivate::addFlyTo()
426 GeoDataFlyTo *flyTo =
new GeoDataFlyTo();
427 GeoDataLookAt *lookat =
new GeoDataLookAt( m_widget->lookAt() );
428 lookat->setAltitude( lookat->range() );
429 flyTo->setView( lookat );
430 bool isMainTrackEmpty = m_playback.mainTrackSize() == 0;
431 flyTo->setDuration( isMainTrackEmpty ? 0.0 : 1.0 );
432 addTourPrimitive( flyTo );
435void TourWidgetPrivate::addWait()
437 GeoDataWait *wait =
new GeoDataWait();
438 wait->setDuration( 1.0 );
439 addTourPrimitive( wait );
442void TourWidgetPrivate::addSoundCue()
444 GeoDataSoundCue *soundCue =
new GeoDataSoundCue();
445 addTourPrimitive( soundCue );
448void TourWidgetPrivate::addPlacemark()
452 qreal lat = m_widget->focusPoint().latitude();
453 qreal lon = m_widget->focusPoint().longitude();
454 GeoDataCoordinates::normalizeLonLat( lon, lat );
456 GeoDataDocument *document =
new GeoDataDocument;
457 if( m_document->id().isEmpty() ) {
458 if( m_document->name().isEmpty() ) {
459 m_document->setId(QStringLiteral(
"untitled_tour"));
461 m_document->setId( m_document->name().trimmed().replace(
QLatin1Char(
' '),
QLatin1Char(
'_') ).toLower() );
464 document->setTargetId( m_document->id() );
466 GeoDataPlacemark *placemark =
new GeoDataPlacemark;
467 placemark->setCoordinate( lon, lat );
468 placemark->setVisible(
true );
469 placemark->setBalloonVisible(
true );
470 GeoDataStyle *newStyle =
new GeoDataStyle( *placemark->style() );
471 newStyle->iconStyle().setIconPath(MarbleDirs::path(QStringLiteral(
"bitmaps/redflag_22.png")));
472 placemark->setStyle( GeoDataStyle::Ptr(newStyle) );
474 document->append( placemark );
476 GeoDataCreate *
create =
new GeoDataCreate;
477 create->append( document );
478 GeoDataUpdate *
update =
new GeoDataUpdate;
479 update->setCreate( create );
480 GeoDataAnimatedUpdate *animatedUpdate =
new GeoDataAnimatedUpdate;
481 animatedUpdate->setUpdate( update );
483 if( m_delegate->editAnimatedUpdate( animatedUpdate ) ) {
484 addTourPrimitive( animatedUpdate );
485 m_delegate->setDefaultFeatureId( placemark->id() );
487 delete animatedUpdate;
491void TourWidgetPrivate::addRemovePlacemark()
493 GeoDataDelete *deleteItem =
new GeoDataDelete;
494 GeoDataPlacemark *placemark =
new GeoDataPlacemark;
495 placemark->setTargetId( m_delegate->defaultFeatureId() );
496 deleteItem->append( placemark );
497 GeoDataUpdate *
update =
new GeoDataUpdate;
498 update->setDelete( deleteItem );
499 GeoDataAnimatedUpdate *animatedUpdate =
new GeoDataAnimatedUpdate;
500 animatedUpdate->setUpdate( update );
501 addTourPrimitive( animatedUpdate );
504void TourWidgetPrivate::addChangePlacemark()
506 GeoDataChange *change =
new GeoDataChange;
507 GeoDataPlacemark *placemark =
nullptr;
508 GeoDataFeature *lastFeature = m_delegate->findFeature( m_delegate->defaultFeatureId() );
509 if (GeoDataPlacemark *target = (lastFeature !=
nullptr ? geodata_cast<GeoDataPlacemark>(lastFeature) : nullptr)) {
510 placemark =
new GeoDataPlacemark( *target );
511 placemark->setTargetId( m_delegate->defaultFeatureId() );
514 placemark =
new GeoDataPlacemark;
516 change->append( placemark );
517 GeoDataUpdate *
update =
new GeoDataUpdate;
518 update->setChange( change );
519 GeoDataAnimatedUpdate *animatedUpdate =
new GeoDataAnimatedUpdate;
520 animatedUpdate->setUpdate( update );
521 addTourPrimitive( animatedUpdate );
524void TourWidgetPrivate::addTourPrimitive( GeoDataTourPrimitive *primitive )
526 GeoDataObject *rootObject = rootIndexObject();
527 if (
auto playlist = geodata_cast<GeoDataPlaylist>(rootObject)) {
528 QModelIndex currentIndex = m_tourUi.m_listView->currentIndex();
530 int row = currentIndex.
isValid() ? currentIndex.
row()+1 : playlist->size();
531 m_widget->model()->treeModel()->addTourPrimitive( playlistIndex, primitive, row );
533 m_tourUi.m_actionSaveTour->setEnabled(
true );
536 if ( currentIndex.
isValid() ) {
537 m_tourUi.m_listView->scrollTo( currentIndex );
540 m_tourUi.m_listView->scrollToBottom();
545void TourWidgetPrivate::deleteSelected()
552 GeoDataObject *rootObject = rootIndexObject();
553 if (GeoDataPlaylist *playlist = (rootObject ? geodata_cast<GeoDataPlaylist>(rootObject) : nullptr)) {
555 QModelIndexList selected = m_tourUi.m_listView->selectionModel()->selectedIndexes();
556 std::sort( selected.begin(), selected.end(), [](
const QModelIndex &a,
const QModelIndex &b) { return b < a; } );
557 QModelIndexList::iterator
end = selected.end();
558 QModelIndexList::iterator iter = selected.begin();
559 for( ; iter !=
end; ++iter ) {
560 m_widget->model()->treeModel()->removeTourPrimitive( playlistIndex, iter->row() );
563 m_tourUi.m_actionSaveTour->setEnabled(
true );
569void TourWidgetPrivate::updateButtonsStates()
571 QModelIndexList selectedIndexes = m_tourUi.m_listView->selectionModel()->selectedIndexes();
572 if ( selectedIndexes.isEmpty() ) {
573 m_tourUi.m_actionDelete->setEnabled(
false );
574 m_tourUi.m_actionMoveDown->setEnabled(
false );
575 m_tourUi.m_actionMoveUp->setEnabled(
false );
577 m_tourUi.m_actionDelete->setEnabled(
true );
578 std::sort( selectedIndexes.begin(), selectedIndexes.end(), std::less<QModelIndex>() );
579 QModelIndexList::iterator
end = selectedIndexes.end()-1;
580 QModelIndexList::iterator
start = selectedIndexes.begin();
581 m_tourUi.m_actionMoveUp->setEnabled( (
start->row() != 0 ) );
582 GeoDataObject *rootObject = rootIndexObject();
583 if (GeoDataPlaylist *playlist = (rootObject ? geodata_cast<GeoDataPlaylist>(rootObject) : nullptr)) {
584 m_tourUi.m_actionMoveDown->setEnabled( (
end->row() != playlist->size()-1 ) );
589void TourWidgetPrivate::moveUp()
591 GeoDataObject *rootObject = rootIndexObject();
592 if (GeoDataPlaylist *playlist = (rootObject ? geodata_cast<GeoDataPlaylist>(rootObject) : nullptr)) {
594 QModelIndexList selected = m_tourUi.m_listView->selectionModel()->selectedIndexes();
595 std::sort( selected.begin(), selected.end(), std::less<QModelIndex>() );
596 QModelIndexList::iterator
end = selected.end();
597 QModelIndexList::iterator iter = selected.begin();
598 for( ; iter !=
end; ++iter ) {
599 int const index = iter->
row();
600 Q_ASSERT( index > 0 );
601 m_widget->model()->treeModel()->swapTourPrimitives( playlistIndex, index-1, index );
604 m_tourUi.m_actionSaveTour->setEnabled(
true );
605 updateButtonsStates();
609void TourWidgetPrivate::moveDown()
611 GeoDataObject *rootObject = rootIndexObject();
612 if (GeoDataPlaylist *playlist = (rootObject ? geodata_cast<GeoDataPlaylist>(rootObject) : nullptr)) {
614 QModelIndexList selected = m_tourUi.m_listView->selectionModel()->selectedIndexes();
615 std::sort( selected.begin(), selected.end(), [](
const QModelIndex &a,
const QModelIndex &b) { return b < a; } );
616 QModelIndexList::iterator
end = selected.end();
617 QModelIndexList::iterator iter = selected.begin();
618 for( ; iter !=
end; ++iter ) {
619 int const index = iter->row();
620 Q_ASSERT( index < playlist->size()-1 );
621 m_widget->model()->treeModel()->swapTourPrimitives( playlistIndex, index, index+1 );
624 m_tourUi.m_actionSaveTour->setEnabled(
true );
625 updateButtonsStates();
629GeoDataFeature* TourWidgetPrivate::getPlaylistFeature()
const
631 GeoDataObject *rootObject = rootIndexObject();
632 if (GeoDataPlaylist *playlist = (rootObject ? geodata_cast<GeoDataPlaylist>(rootObject) : nullptr)) {
633 GeoDataObject *
object = playlist->parent();
634 if (GeoDataTour *tour = (
object ? geodata_cast<GeoDataTour>(
object) : nullptr)) {
641void TourWidgetPrivate::updateRootIndex()
643 GeoDataTour *tour = findTour( m_document );
645 GeoDataPlaylist *playlist = tour->playlist();
647 m_tourUi.m_listView->setModel( m_widget->model()->treeModel() );
648 m_tourUi.m_listView->setRootIndex( m_widget->model()->treeModel()->index( playlist ) );
650 q, SLOT(updateButtonsStates()) );
652 m_playback.setMarbleWidget( m_widget );
653 m_playback.setTour( tour );
654 m_tourUi.m_slider->setMaximum( m_playback.duration() * 100 );
655 QTime nullTime( 0, 0, 0 );
659 q, SLOT(handlePlaybackProgress(
double)) );
661 m_tourUi.m_toolBarPlayback->setEnabled(
true );
662 bool isPlaybackEmpty = m_playback.mainTrackSize() != 0;
663 m_tourUi.actionPlay->setEnabled( isPlaybackEmpty );
664 m_tourUi.m_slider->setEnabled( isPlaybackEmpty );
665 m_tourUi.m_actionRecord->setEnabled( isPlaybackEmpty );
666 m_tourUi.actionStop->setEnabled(
false );
667 if( m_playback.mainTrackSize() > 0 ) {
668 if(
dynamic_cast<PlaybackFlyToItem*
>( m_playback.mainTrackItemAt( 0 ) ) ) {
670 for(
int i = 0; playlist && i < playlist->size(); ++i ) {
671 if (geodata_cast<GeoDataFlyTo>(playlist->primitive(i))) {
672 m_delegate->setFirstFlyTo( m_widget->model()->treeModel()->index( i, 0, playlistIndex ) );
683void TourWidget::addFlyTo()
689void TourWidget::addWait()
695void TourWidget::addSoundCue()
701void TourWidget::addPlacemark()
707void TourWidget::addRemovePlacemark()
709 d->addRemovePlacemark();
713void TourWidget::addChangePlacemark()
715 d->addChangePlacemark();
719void TourWidget::deleteSelected()
722 GeoDataFeature *feature = d->getPlaylistFeature();
724 emit featureUpdated( feature );
725 d->updateRootIndex();
729void TourWidget::updateDuration()
731 d->m_tourUi.m_slider->setMaximum( d->m_playback.duration() * 100 );
732 QTime nullTime( 0, 0, 0 );
733 QTime totalTime = nullTime.
addSecs( d->m_playback.duration() );
735 d->m_tourUi.m_slider->setValue( 0 );
739void TourWidget::finishAddingItem()
741 GeoDataFeature *feature = d->getPlaylistFeature();
743 emit featureUpdated( feature );
744 d->updateRootIndex();
748void TourWidget::moveDown()
751 GeoDataFeature *feature = d->getPlaylistFeature();
753 emit featureUpdated( feature );
754 d->updateRootIndex();
758void TourWidget::moveUp()
761 GeoDataFeature *feature = d->getPlaylistFeature();
763 emit featureUpdated( feature );
764 d->updateRootIndex();
768GeoDataObject *TourWidgetPrivate::rootIndexObject()
const
770 QModelIndex const rootIndex = m_tourUi.m_listView->rootIndex();
774void TourWidgetPrivate::createTour()
776 if ( overrideModifications() ) {
777 GeoDataDocument *document =
new GeoDataDocument();
778 document->setDocumentRole( UserDocument );
779 document->setName(QStringLiteral(
"New Tour"));
780 document->setId(QStringLiteral(
"new_tour"));
781 GeoDataTour *tour =
new GeoDataTour();
782 tour->setName(QStringLiteral(
"New Tour"));
783 GeoDataPlaylist *playlist =
new GeoDataPlaylist;
784 tour->setPlaylist( playlist );
785 document->append(
static_cast<GeoDataFeature*
>( tour ) );
787 openDocument( document );
789 m_tourUi.m_actionSaveTour->setEnabled(
true );
790 m_tourUi.m_slider->setEnabled(
true );
794bool TourWidgetPrivate::openDocument(GeoDataDocument* document)
798 m_widget->model()->treeModel()->removeDocument( m_document );
801 m_document = document;
802 m_widget->model()->treeModel()->addDocument( m_document );
805 m_addPrimitiveButton->setEnabled(
true );
806 m_tourUi.m_actionSaveTourAs->setEnabled(
true );
807 m_tourUi.m_actionSaveTour->setEnabled(
false );
814void TourWidgetPrivate::saveTour()
817 if ( !m_document->fileName().isEmpty() ) {
818 saveTourAs( m_document->fileName() );
825void TourWidgetPrivate::saveTourAs()
831 saveTourAs( filename );
836bool TourWidgetPrivate::saveTourAs(
const QString &filename)
839 if (GeoDataDocumentWriter::write(filename, *m_document)) {
840 m_tourUi.m_actionSaveTour->setEnabled(
false );
842 GeoDataDocument* document = m_document;
843 if ( !document->fileName().isNull() ) {
844 m_widget->model()->removeGeoData( document->fileName() );
846 m_widget->model()->addGeoDataFile( filename );
847 m_document->setFileName( filename );
854void TourWidgetPrivate::captureTour()
856 MarbleWidget* widget =
new MarbleWidget;
857 widget->setMapThemeId( m_widget->mapThemeId() );
858 widget->resize( 1280, 720 );
860 m_widget->model()->treeModel()->removeDocument(m_document);
861 widget->model()->treeModel()->addDocument(m_document);
863 GeoDataTour* tour = findTour( m_document );
864 TourPlayback* playback =
new TourPlayback;
865 playback->setMarbleWidget( widget );
866 playback->setTour( tour );
868 m_tourUi.m_listView->setModel( widget->model()->treeModel() );
870 m_tourUi.m_listView->setRootIndex( widget->model()->treeModel()->index( tour->playlist() ) );
871 m_tourUi.m_listView->repaint();
874 tourCaptureDialog->setDefaultFilename( tour->name() );
875 tourCaptureDialog->setTourPlayback( playback );
876 tourCaptureDialog->exec();
880 widget->model()->treeModel()->removeDocument(m_document);
881 m_widget->model()->treeModel()->addDocument(m_document);
886bool TourWidgetPrivate::overrideModifications()
888 if ( m_document && m_isChanged ) {
890 QString text =
QObject::tr(
"Are you sure want to discard all unsaved changes and close current document?" );
902bool TourWidget::openTour(
const QString &filename)
904 return d->openFile( filename );
907void TourWidgetPrivate::handlePlaybackProgress(
const double position)
909 if( !m_tourUi.m_slider->isSliderDown() ){
910 m_tourUi.m_slider->setValue( position * 100 );
911 QTime nullTime( 0, 0, 0 );
917void TourWidget::setHighlightedItemIndex(
int index )
919 GeoDataObject* rootObject = d->rootIndexObject();
920 GeoDataPlaylist* playlist =
static_cast<GeoDataPlaylist*
>( rootObject );
924 int searchedIndex = 0;
925 for (
int i = 0; i < playlist->size(); i++ ) {
928 GeoDataObject*
object = qvariant_cast<GeoDataObject*>(currentIndex.
data( MarblePlacemarkModel::ObjectPointerRole ) );
930 if (geodata_cast<GeoDataFlyTo>(
object)
931 || geodata_cast<GeoDataWait>(
object))
934 if ( index == searchedIndex ) {
936 d->m_tourUi.m_listView->scrollTo( currentIndex );
940 d->m_tourUi.m_listView->viewport()->update();
943void TourWidget::removeHighlight()
949 if ( d->m_tourUi.m_listView->selectionModel()->hasSelection() ) {
950 index = d->m_tourUi.m_listView->selectionModel()->selectedIndexes().last();
957 d->m_tourUi.m_listView->viewport()->update();
960bool TourWidget::isPlaying()
const
962 return d->m_playState;
967#include "moc_TourWidget.cpp"
This file contains the headers for MarbleModel.
Q_SCRIPTABLE Q_NOREPLY void start()
AKONADI_CALENDAR_EXPORT KCalendarCore::Event::Ptr event(const Akonadi::Item &item)
void update(Part *part, const QByteArray &data, qint64 dataSize)
QAction * create(GameStandardAction id, const QObject *recvr, const char *slot, QObject *parent)
const QList< QKeySequence > & end()
Binds a QML item to a specific geodetic location in screen coordinates.
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const const=0
void setIcon(const QIcon &icon)
QString getOpenFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, Options options)
QString getSaveFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, Options options)
Qt::KeyboardModifiers modifiers() const const
StandardButton question(QWidget *parent, const QString &title, const QString &text, StandardButtons buttons, StandardButton defaultButton)
QVariant data(int role) const const
void * internalPointer() const const
bool isValid() const const
const QAbstractItemModel * model() const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QString tr(const char *sourceText, const char *disambiguation, int n)
bool isEmpty() const const
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
QTime addSecs(int s) const const
QUrl fromLocalFile(const QString &localFile)
bool isNull() const const