20#include "moc_qgstemporalcontrollerwidget.cpp"
33#include <QRegularExpression>
42 mStartDateTime->setDateTimeRange( QDateTime( QDate( 1, 1, 1 ), QTime( 0, 0, 0 ) ), mStartDateTime->maximumDateTime() );
43 mEndDateTime->setDateTimeRange( QDateTime( QDate( 1, 1, 1 ), QTime( 0, 0, 0 ) ), mStartDateTime->maximumDateTime() );
44 mFixedRangeStartDateTime->setDateTimeRange( QDateTime( QDate( 1, 1, 1 ), QTime( 0, 0, 0 ) ), mStartDateTime->maximumDateTime() );
45 mFixedRangeEndDateTime->setDateTimeRange( QDateTime( QDate( 1, 1, 1 ), QTime( 0, 0, 0 ) ), mStartDateTime->maximumDateTime() );
64 mNavigationObject->
pause();
72 mNavigationObject->
next();
83 connect( mAnimationLoopingCheckBox, &QCheckBox::toggled,
this, [ = ](
bool state ) { mNavigationObject->
setLooping( state ); mMovieLoopingCheckBox->setChecked( state ); } );
84 connect( mMovieLoopingCheckBox, &QCheckBox::toggled,
this, [ = ](
bool state ) { mNavigationObject->
setLooping( state ); mAnimationLoopingCheckBox->setChecked( state ); } );
86 setWidgetStateFromNavigationMode( mNavigationObject->
navigationMode() );
91 if ( mBlockFrameDurationUpdates )
94 mBlockFrameDurationUpdates++;
95 updateTimeStepInputs( timeStep );
96 mBlockFrameDurationUpdates--;
98 connect( mNavigationOff, &QPushButton::clicked,
this, &QgsTemporalControllerWidget::mNavigationOff_clicked );
99 connect( mNavigationFixedRange, &QPushButton::clicked,
this, &QgsTemporalControllerWidget::mNavigationFixedRange_clicked );
100 connect( mNavigationAnimated, &QPushButton::clicked,
this, &QgsTemporalControllerWidget::mNavigationAnimated_clicked );
101 connect( mNavigationMovie, &QPushButton::clicked,
this, &QgsTemporalControllerWidget::mNavigationMovie_clicked );
105 mAnimationController->setState( state );
106 mMovieController->setState( state );
109 connect( mStartDateTime, &QDateTimeEdit::dateTimeChanged,
this, &QgsTemporalControllerWidget::startEndDateTime_changed );
110 connect( mEndDateTime, &QDateTimeEdit::dateTimeChanged,
this, &QgsTemporalControllerWidget::startEndDateTime_changed );
111 connect( mFixedRangeStartDateTime, &QDateTimeEdit::dateTimeChanged,
this, &QgsTemporalControllerWidget::fixedRangeStartEndDateTime_changed );
112 connect( mFixedRangeEndDateTime, &QDateTimeEdit::dateTimeChanged,
this, &QgsTemporalControllerWidget::fixedRangeStartEndDateTime_changed );
113 connect( mStepSpinBox, qOverload<double>( &QDoubleSpinBox::valueChanged ),
this, &QgsTemporalControllerWidget::updateFrameDuration );
114 connect( mTimeStepsComboBox, qOverload<int>( &QComboBox::currentIndexChanged ),
this, &QgsTemporalControllerWidget::updateFrameDuration );
115 connect( mAnimationSlider, &QSlider::valueChanged,
this, &QgsTemporalControllerWidget::timeSlider_valueChanged );
116 connect( mMovieSlider, &QSlider::valueChanged,
this, &QgsTemporalControllerWidget::timeSlider_valueChanged );
118 connect( mTotalFramesSpinBox, qOverload<int>( &QSpinBox::valueChanged ),
this, [ = ](
int frames )
123 mStepSpinBox->setClearValue( 1 );
128 connect( mSettings, &QPushButton::clicked,
this, &QgsTemporalControllerWidget::settings_clicked );
132 mRangeMenu.reset(
new QMenu(
this ) );
134 mRangeSetToAllLayersAction =
new QAction( tr(
"Set to Full Range" ), mRangeMenu.get() );
136 connect( mRangeSetToAllLayersAction, &QAction::triggered,
this, &QgsTemporalControllerWidget::mRangeSetToAllLayersAction_triggered );
137 mRangeMenu->addAction( mRangeSetToAllLayersAction );
139 mRangeSetToProjectAction =
new QAction( tr(
"Set to Preset Project Range" ), mRangeMenu.get() );
140 connect( mRangeSetToProjectAction, &QAction::triggered,
this, &QgsTemporalControllerWidget::mRangeSetToProjectAction_triggered );
141 mRangeMenu->addAction( mRangeSetToProjectAction );
143 mRangeMenu->addSeparator();
145 mRangeLayersSubMenu.reset(
new QMenu( tr(
"Set to Single Layer's Range" ), mRangeMenu.get() ) );
146 mRangeLayersSubMenu->setEnabled(
false );
147 mRangeMenu->addMenu( mRangeLayersSubMenu.get() );
148 connect( mRangeMenu.get(), &QMenu::aboutToShow,
this, &QgsTemporalControllerWidget::aboutToShowRangeMenu );
150 mSetRangeButton->setPopupMode( QToolButton::MenuButtonPopup );
151 mSetRangeButton->setMenu( mRangeMenu.get() );
152 mSetRangeButton->setDefaultAction( mRangeSetToAllLayersAction );
153 mFixedRangeSetRangeButton->setPopupMode( QToolButton::MenuButtonPopup );
154 mFixedRangeSetRangeButton->setMenu( mRangeMenu.get() );
155 mFixedRangeSetRangeButton->setDefaultAction( mRangeSetToAllLayersAction );
165 if ( range.
begin().isValid() && range.
end().isValid() )
195 mStepSpinBox->setDecimals( 3 );
197 mStepSpinBox->setMinimum( 0.001 );
198 mStepSpinBox->setMaximum( std::numeric_limits<int>::max() );
199 mStepSpinBox->setSingleStep( 1 );
200 mStepSpinBox->setValue( 1 );
202 updateFrameDuration();
216 if ( ( mAnimationSlider->hasFocus() || mMovieSlider->hasFocus() ) && e->key() == Qt::Key_Space )
218 mAnimationController->togglePause();
224void QgsTemporalControllerWidget::aboutToShowRangeMenu()
229 mRangeSetToProjectAction->setEnabled( projectRange.
begin().isValid() && projectRange.
end().isValid() );
231 mRangeLayersSubMenu->clear();
232 for (
int i = 0; i < mMapLayerModel->
rowCount(); ++i )
234 const QModelIndex index = mMapLayerModel->
index( i, 0 );
239 const QIcon icon = qvariant_cast<QIcon>( mMapLayerModel->
data( index, Qt::DecorationRole ) );
240 const QString text = mMapLayerModel->
data( index, Qt::DisplayRole ).toString();
242 if ( range.
begin().isValid() && range.
end().isValid() )
244 QAction *action =
new QAction( icon, text, mRangeLayersSubMenu.get() );
245 connect( action, &QAction::triggered,
this, [ = ]
248 saveRangeToProject();
250 mRangeLayersSubMenu->addAction( action );
253 mRangeLayersSubMenu->setEnabled( !mRangeLayersSubMenu->actions().isEmpty() );
256void QgsTemporalControllerWidget::updateTemporalExtent()
260 const QDateTime start = mStartDateTime->dateTime();
261 const QDateTime end = mEndDateTime->dateTime();
262 const bool isTimeInstant = start == end;
266 mAnimationSlider->setRange( 0, mNavigationObject->
totalFrameCount() - 1 );
272void QgsTemporalControllerWidget::updateFrameDuration()
274 if ( mBlockSettingUpdates )
282 if ( !mBlockFrameDurationUpdates )
289 mAnimationSlider->setRange( 0, mNavigationObject->
totalFrameCount() - 1 );
296 mStepSpinBox->setEnabled(
false );
297 mStepSpinBox->setValue( 1 );
298 mAnimationSlider->setTickInterval( 1 );
299 mAnimationSlider->setTickPosition( QSlider::TicksBothSides );
303 mStepSpinBox->setEnabled(
true );
304 mAnimationSlider->setTickInterval( 0 );
305 mAnimationSlider->setTickPosition( QSlider::NoTicks );
309void QgsTemporalControllerWidget::setWidgetStateFromProject()
311 mBlockSettingUpdates++;
314 mBlockSettingUpdates--;
318 QStringLiteral(
"/NavigationMode" ), 0, &ok ) );
322 setWidgetStateFromNavigationMode( mode );
333 const QString startString =
QgsProject::instance()->
readEntry( QStringLiteral(
"TemporalControllerWidget" ), QStringLiteral(
"/StartDateTime" ) );
334 const QString endString =
QgsProject::instance()->
readEntry( QStringLiteral(
"TemporalControllerWidget" ), QStringLiteral(
"/EndDateTime" ) );
335 if ( !startString.isEmpty() && !endString.isEmpty() )
337 whileBlocking( mStartDateTime )->setDateTime( QDateTime::fromString( startString, Qt::ISODateWithMs ) );
338 whileBlocking( mEndDateTime )->setDateTime( QDateTime::fromString( endString, Qt::ISODateWithMs ) );
339 whileBlocking( mFixedRangeStartDateTime )->setDateTime( QDateTime::fromString( startString, Qt::ISODateWithMs ) );
340 whileBlocking( mFixedRangeEndDateTime )->setDateTime( QDateTime::fromString( endString, Qt::ISODateWithMs ) );
344 setDatesToProjectTime(
false );
346 updateTemporalExtent();
347 updateFrameDuration();
353void QgsTemporalControllerWidget::mNavigationOff_clicked()
362void QgsTemporalControllerWidget::mNavigationFixedRange_clicked()
371void QgsTemporalControllerWidget::mNavigationAnimated_clicked()
380void QgsTemporalControllerWidget::mNavigationMovie_clicked()
399 mNavigationModeStackedWidget->setCurrentIndex( 0 );
402 mNavigationModeStackedWidget->setCurrentIndex( 1 );
405 mNavigationModeStackedWidget->setCurrentIndex( 2 );
408 mNavigationModeStackedWidget->setCurrentIndex( 3 );
413void QgsTemporalControllerWidget::onLayersAdded(
const QList<QgsMapLayer *> &layers )
415 if ( !mHasTemporalLayersLoaded )
419 if ( layer->temporalProperties() )
421 mHasTemporalLayersLoaded |= layer->temporalProperties()->isActive();
423 if ( !mHasTemporalLayersLoaded )
427 if ( layer->isValid() && layer->temporalProperties()->isActive() && !mHasTemporalLayersLoaded )
429 mHasTemporalLayersLoaded = true;
430 firstTemporalLayerLoaded( layer );
431 mNavigationObject->setAvailableTemporalRanges( QgsTemporalUtils::usedTemporalRangesForProject( QgsProject::instance() ) );
436 firstTemporalLayerLoaded( layer );
444void QgsTemporalControllerWidget::firstTemporalLayerLoaded(
QgsMapLayer *layer )
446 setDatesToProjectTime(
true );
448 if (
QgsMeshLayer *meshLayer = qobject_cast<QgsMeshLayer *>( layer ) )
450 mBlockFrameDurationUpdates++;
451 setTimeStep( meshLayer->firstValidTimeStep() );
452 mBlockFrameDurationUpdates--;
453 updateFrameDuration();
455 else if (
QgsRasterLayer *rasterLayer = qobject_cast<QgsRasterLayer *>( layer ) )
457 if ( rasterLayer->dataProvider() && rasterLayer->dataProvider()->temporalCapabilities() )
459 mBlockFrameDurationUpdates++;
460 setTimeStep( rasterLayer->dataProvider()->temporalCapabilities()->defaultInterval() );
461 mBlockFrameDurationUpdates--;
462 updateFrameDuration();
467void QgsTemporalControllerWidget::onProjectCleared()
469 mHasTemporalLayersLoaded =
false;
476 const QTime startOfCurrentHour = QTime( QTime::currentTime().hour(), 0, 0 );
477 const QDateTime end = QDateTime( QDate::currentDate(), startOfCurrentHour, Qt::UTC );
478 const QDateTime start = end.addSecs( -24 * 60 * 60 );
482 whileBlocking( mFixedRangeStartDateTime )->setDateTime( start );
485 updateTemporalExtent();
487 mStepSpinBox->setValue( 1 );
490void QgsTemporalControllerWidget::updateSlider(
const QgsDateTimeRange &range )
494 updateRangeLabel( range );
497void QgsTemporalControllerWidget::totalMovieFramesChanged(
long long frames )
500 mTotalFramesSpinBox->setValue( frames );
501 mCurrentRangeLabel->setText( tr(
"Current frame: %1/%2" ).arg( mNavigationObject->
currentFrameNumber() ).arg( frames ) );
504void QgsTemporalControllerWidget::updateRangeLabel(
const QgsDateTimeRange &range )
506 QString timeFrameFormat = QStringLiteral(
"yyyy-MM-dd HH:mm:ss" );
509 timeFrameFormat = QStringLiteral(
"yyyy-MM-dd HH:mm:ss.zzz" );
513 mCurrentRangeLabel->setText( tr(
"Current frame: %1 ≤ <i>t</i> < %2" ).arg(
514 range.
begin().toString( timeFrameFormat ),
515 range.
end().toString( timeFrameFormat ) ) );
518 mCurrentRangeLabel->setText( tr(
"Range: %1 ≤ <i>t</i> < %2" ).arg(
519 range.
begin().toString( timeFrameFormat ),
520 range.
end().toString( timeFrameFormat ) ) );
523 mCurrentRangeLabel->setText( tr(
"Temporal navigation disabled" ) );
533 return mNavigationObject;
536void QgsTemporalControllerWidget::settings_clicked()
538 QgsTemporalMapSettingsWidget *settingsWidget =
new QgsTemporalMapSettingsWidget(
this );
539 settingsWidget->setFrameRateValue( mNavigationObject->
framesPerSecond() );
542 connect( settingsWidget, &QgsTemporalMapSettingsWidget::frameRateChanged,
this, [ = ](
double rate )
549 connect( settingsWidget, &QgsTemporalMapSettingsWidget::temporalRangeCumulativeChanged,
this, [ = ](
bool state )
558void QgsTemporalControllerWidget::timeSlider_valueChanged(
int value )
563void QgsTemporalControllerWidget::startEndDateTime_changed()
565 whileBlocking( mFixedRangeStartDateTime )->setDateTime( mStartDateTime->dateTime() );
566 whileBlocking( mFixedRangeEndDateTime )->setDateTime( mEndDateTime->dateTime() );
568 updateTemporalExtent();
569 saveRangeToProject();
572void QgsTemporalControllerWidget::fixedRangeStartEndDateTime_changed()
574 whileBlocking( mStartDateTime )->setDateTime( mFixedRangeStartDateTime->dateTime() );
575 whileBlocking( mEndDateTime )->setDateTime( mFixedRangeEndDateTime->dateTime() );
577 updateTemporalExtent();
578 saveRangeToProject();
581void QgsTemporalControllerWidget::mRangeSetToAllLayersAction_triggered()
583 setDatesToAllLayers();
584 saveRangeToProject();
587void QgsTemporalControllerWidget::setTimeStep(
const QgsInterval &timeStep )
592 int selectedUnit = -1;
593 double selectedValue = std::numeric_limits<double>::max();
599 int stringSize = std::numeric_limits<int>::max();
600 const int precision = mStepSpinBox->decimals();
601 for (
int i = 0; i < mTimeStepsComboBox->count(); ++i )
605 QString
string = QString::number( value,
'f',
precision );
607 const thread_local QRegularExpression trailingZeroRegEx = QRegularExpression( QStringLiteral(
"0+$" ) );
609 string.remove( trailingZeroRegEx );
611 const thread_local QRegularExpression trailingPointRegEx = QRegularExpression( QStringLiteral(
"[.]+$" ) );
613 string.remove( trailingPointRegEx );
616 &&
string.size() <= stringSize
617 && value < selectedValue )
620 selectedValue = value;
621 stringSize =
string.size();
623 else if (
string !=
'0'
625 &&
string.size() < stringSize )
628 selectedValue = value ;
629 stringSize =
string.size();
635 selectedUnit = mTimeStepsComboBox->findData(
static_cast< int >( timeStep.
originalUnit() ) );
639 if ( selectedUnit >= 0 )
641 mStepSpinBox->setValue( selectedValue );
642 mTimeStepsComboBox->setCurrentIndex( selectedUnit );
645 updateFrameDuration();
648void QgsTemporalControllerWidget::updateTimeStepInputs(
const QgsInterval &timeStep )
653 QString timeDisplayFormat = QStringLiteral(
"yyyy-MM-dd HH:mm:ss" );
656 timeDisplayFormat = QStringLiteral(
"yyyy-MM-dd HH:mm:ss.zzz" );
658 updateTemporalExtent();
660 mStartDateTime->setDisplayFormat( timeDisplayFormat );
661 mEndDateTime->setDisplayFormat( timeDisplayFormat );
662 mFixedRangeStartDateTime->setDisplayFormat( timeDisplayFormat );
663 mFixedRangeEndDateTime->setDisplayFormat( timeDisplayFormat );
666 if ( timeStep ==
QgsInterval( mStepSpinBox->value(),
673 mTimeStepsComboBox->setCurrentIndex( mTimeStepsComboBox->findData(
static_cast< int >( timeStep.
originalUnit() ) ) );
676 updateFrameDuration();
679void QgsTemporalControllerWidget::mRangeSetToProjectAction_triggered()
681 setDatesToProjectTime(
false );
682 saveRangeToProject();
687 if ( range.
begin().isValid() && range.
end().isValid() )
693 updateTemporalExtent();
697void QgsTemporalControllerWidget::setDatesToAllLayers()
706void QgsTemporalControllerWidget::setDatesToProjectTime(
bool tryLastStoredRange )
710 if ( tryLastStoredRange )
712 const QString startString =
QgsProject::instance()->
readEntry( QStringLiteral(
"TemporalControllerWidget" ), QStringLiteral(
"/StartDateTime" ) );
713 const QString endString =
QgsProject::instance()->
readEntry( QStringLiteral(
"TemporalControllerWidget" ), QStringLiteral(
"/EndDateTime" ) );
714 if ( !startString.isEmpty() && !endString.isEmpty() )
716 range =
QgsDateTimeRange( QDateTime::fromString( startString, Qt::ISODateWithMs ),
717 QDateTime::fromString( endString, Qt::ISODateWithMs ) );
726 if ( !range.
begin().isValid() || !range.
end().isValid() )
736void QgsTemporalControllerWidget::saveRangeToProject()
739 QStringLiteral(
"/StartDateTime" ), mStartDateTime->dateTime().toTimeSpec( Qt::OffsetFromUTC ).toString( Qt::ISODateWithMs ) );
741 QStringLiteral(
"/EndDateTime" ), mEndDateTime->dateTime().toTimeSpec( Qt::OffsetFromUTC ).toString( Qt::ISODateWithMs ) );
TemporalNavigationMode
Temporal navigation modes.
@ Animated
Temporal navigation relies on frames within a datetime range.
@ Movie
Movie mode – behaves like a video player, with a fixed frame duration and no temporal range.
@ FixedRange
Temporal navigation relies on a fixed datetime range.
@ Disabled
Temporal navigation is disabled.
PlaybackOperation
Media playback operations.
@ PlayReverse
Play in reverse.
@ PlayForward
Play forward.
@ SkipToStart
Jump to start of playback.
@ PreviousFrame
Step to previous frame.
@ SkipToEnd
Jump to end of playback.
@ NextFrame
Step to next frame.
TemporalUnit
Temporal units.
@ IrregularStep
Special 'irregular step' time unit, used for temporal data which uses irregular, non-real-world unit ...
@ Milliseconds
Milliseconds.
@ Unknown
Unknown time unit.
AnimationState
Animation states.
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
A representation of the interval between two datetime values.
double originalDuration() const
Returns the original interval duration.
bool isValid() const
Returns true if the interval is valid.
double seconds() const
Returns the interval duration in seconds.
Qgis::TemporalUnit originalUnit() const
Returns the original interval temporal unit.
The QgsMapLayerModel class is a model to display layers in widgets.
int rowCount(const QModelIndex &parent=QModelIndex()) const override
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
@ Layer
Stores pointer to the map layer itself.
virtual QgsDateTimeRange calculateTemporalExtent(QgsMapLayer *layer) const
Attempts to calculate the overall temporal extent for the specified layer, using the settings defined...
Base class for all map layer types.
void dataSourceChanged()
Emitted whenever the layer's data source has been changed.
virtual QgsMapLayerTemporalProperties * temporalProperties()
Returns the layer's temporal properties.
Represents a mesh layer supporting display of data on structured or unstructured meshes.
QgsDateTimeRange temporalRange() const
Returns the project's temporal range, which indicates the earliest and latest datetime ranges associa...
void setTotalMovieFrames(long long frames)
Sets the total number of frames for the movie.
void setFramesPerSecond(double rate)
Sets the project's default animation frame rate, in frames per second.
Qgis::TemporalUnit timeStepUnit() const
Returns the project's time step (length of one animation frame) unit, which is used as the default va...
void setTimeStepUnit(Qgis::TemporalUnit unit)
Sets the project's time step (length of one animation frame) unit, which is used as the default value...
void setIsTemporalRangeCumulative(bool state)
Sets the project's temporal range as cumulative in animation settings.
void setTimeStep(double step)
Sets the project's time step (length of one animation frame), which is used as the default value when...
int readNumEntry(const QString &scope, const QString &key, int def=0, bool *ok=nullptr) const
Reads an integer from the specified scope and key.
static QgsProject * instance()
Returns the QgsProject singleton instance.
void cleared()
Emitted when the project is cleared (and additionally when an open project is cleared just before a n...
QString readEntry(const QString &scope, const QString &key, const QString &def=QString(), bool *ok=nullptr) const
Reads a string from the specified scope and key.
bool writeEntry(const QString &scope, const QString &key, bool value)
Write a boolean value to the project file.
void readProject(const QDomDocument &document)
Emitted when a project is being read.
void layersAdded(const QList< QgsMapLayer * > &layers)
Emitted when one or more layers were added to the registry.
const QgsProjectTimeSettings * timeSettings() const
Returns the project's time settings, which contains the project's temporal range and other time based...
Represents a raster layer.
void updateTemporalRange(const QgsDateTimeRange &range)
Signals that a temporal range has changed and needs to be updated in all connected objects.
Implements a temporal controller based on a frame by frame navigation and animation.
void stateChanged(Qgis::AnimationState state)
Emitted whenever the animation state changes.
long long totalMovieFrames() const
Returns the total number of frames for the movie.
void previous()
Jumps back to the previous frame.
double framesPerSecond() const
Returns the animation frame rate, in frames per second.
void setAvailableTemporalRanges(const QList< QgsDateTimeRange > &ranges)
Sets the list of all available temporal ranges which have data available.
void setFrameDuration(const QgsInterval &duration)
Sets the frame duration, which dictates the temporal length of each frame in the animation.
void navigationModeChanged(Qgis::TemporalNavigationMode mode)
Emitted whenever the navigation mode changes.
void setNavigationMode(const Qgis::TemporalNavigationMode mode)
Sets the temporal navigation mode.
void playForward()
Starts the animation playing in a forward direction up till the end of all frames.
long long currentFrameNumber() const
Returns the current frame number.
void rewindToStart()
Rewinds the temporal navigation to start of the temporal extent.
void pause()
Pauses the temporal navigation.
void setCurrentFrameNumber(long long frame)
Sets the current animation frame number.
long long totalFrameCount() const
Returns the total number of frames for the navigation.
void skipToEnd()
Skips the temporal navigation to end of the temporal extent.
void temporalFrameDurationChanged(const QgsInterval &interval)
Emitted whenever the frameDuration interval of the controller changes.
void setFramesPerSecond(double rate)
Sets the animation frame rate, in frames per second.
bool temporalRangeCumulative() const
Returns the animation temporal range cumulative settings.
void next()
Advances to the next frame.
void totalMovieFramesChanged(long long frames)
Emitted whenever the total number of frames in the movie is changed.
void setTotalMovieFrames(long long frames)
Sets the total number of frames for the movie.
void setTemporalExtents(const QgsDateTimeRange &extents)
Sets the navigation temporal extents, which dictate the earliest and latest date time possible in the...
Qgis::TemporalNavigationMode navigationMode() const
Returns the current temporal navigation mode.
void setTemporalRangeCumulative(bool state)
Sets the animation temporal range as cumulative.
void setLooping(bool loop)
Sets whether the animation should loop after hitting the end or start frame.
void playBackward()
Starts the animation playing in a reverse direction until the beginning of the time range.
void temporalExtentsChanged(const QgsDateTimeRange &extent)
Emitted whenever the temporalExtent extent changes.
bool isActive() const
Returns true if the temporal property is active.
T begin() const
Returns the beginning of the range.
T end() const
Returns the upper bound of the range.
static QgsDateTimeRange calculateTemporalRangeForProject(QgsProject *project)
Calculates the temporal range for a project.
static QList< QgsDateTimeRange > usedTemporalRangesForProject(QgsProject *project)
Calculates all temporal ranges which are in use for a project.
static Q_INVOKABLE QString toString(Qgis::DistanceUnit unit)
Returns a translated string representing a distance unit.
static Q_INVOKABLE double fromUnitToUnitFactor(Qgis::DistanceUnit fromUnit, Qgis::DistanceUnit toUnit)
Returns the conversion factor between the specified distance units.
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
QgsTemporalRange< QDateTime > QgsDateTimeRange
QgsRange which stores a range of date times.