Skip to content
Permalink
Browse files

[temporal] Make the temporal controller's set range button more useable

  • Loading branch information
nirvn committed May 22, 2020
1 parent 4de6a53 commit 204694e191058d118126ae1106f56c6a149c6da8
@@ -15,14 +15,19 @@
* *
***************************************************************************/

#include "qgsapplication.h"
#include "qgstemporalcontrollerwidget.h"
#include "qgsgui.h"
#include "qgsmaplayermodel.h"
#include "qgsproject.h"
#include "qgsprojecttimesettings.h"
#include "qgstemporalmapsettingswidget.h"
#include "qgstemporalutils.h"
#include "qgsmaplayertemporalproperties.h"

#include <QAction>
#include <QMenu>

QgsTemporalControllerWidget::QgsTemporalControllerWidget( QWidget *parent )
: QgsPanelWidget( parent )
{
@@ -65,8 +70,33 @@ QgsTemporalControllerWidget::QgsTemporalControllerWidget( QWidget *parent )
connect( mNavigationObject, &QgsTemporalNavigationObject::updateTemporalRange, this, &QgsTemporalControllerWidget::updateSlider );

connect( mSettings, &QPushButton::clicked, this, &QgsTemporalControllerWidget::settings_clicked );
connect( mSetToProjectTimeButton, &QPushButton::clicked, this, &QgsTemporalControllerWidget::mSetToProjectTimeButton_clicked );
connect( mFixedRangeSetToProjectTimeButton, &QPushButton::clicked, this, &QgsTemporalControllerWidget::mSetToProjectTimeButton_clicked );

mMapLayerModel = new QgsMapLayerModel( this );

mRangeMenu.reset( new QMenu( this ) );

mRangeSetToAllLayersAction = new QAction( tr( "Set to Full Range" ), mRangeMenu.get() );
mRangeSetToAllLayersAction->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionRefresh.svg" ) ) );
connect( mRangeSetToAllLayersAction, &QAction::triggered, this, &QgsTemporalControllerWidget::mRangeSetToAllLayersAction_triggered );
mRangeMenu->addAction( mRangeSetToAllLayersAction );

mRangeSetToProjectAction = new QAction( tr( "Set to Preset Project Range" ), mRangeMenu.get() );
connect( mRangeSetToProjectAction, &QAction::triggered, this, &QgsTemporalControllerWidget::mRangeSetToProjectAction_triggered );
mRangeMenu->addAction( mRangeSetToProjectAction );

mRangeMenu->addSeparator();

mRangeLayersSubMenu.reset( new QMenu( tr( "Set to Single Layer's Range" ), mRangeMenu.get() ) );
mRangeLayersSubMenu->setEnabled( false );
mRangeMenu->addMenu( mRangeLayersSubMenu.get() );
connect( mRangeMenu.get(), &QMenu::aboutToShow, this, &QgsTemporalControllerWidget::aboutToShowRangeMenu );

mSetRangeButton->setPopupMode( QToolButton::MenuButtonPopup );
mSetRangeButton->setMenu( mRangeMenu.get() );
mSetRangeButton->setDefaultAction( mRangeSetToAllLayersAction );
mFixedRangeSetRangeButton->setPopupMode( QToolButton::MenuButtonPopup );
mFixedRangeSetRangeButton->setMenu( mRangeMenu.get() );
mFixedRangeSetRangeButton->setDefaultAction( mRangeSetToAllLayersAction );

connect( mExportAnimationButton, &QPushButton::clicked, this, &QgsTemporalControllerWidget::exportAnimation );

@@ -88,14 +118,6 @@ QgsTemporalControllerWidget::QgsTemporalControllerWidget( QWidget *parent )
whileBlocking( mFixedRangeEndDateTime )->setDateTime( range.end() );
}

QString setToProjectTimeButtonToolTip = tr( "Match time range to project. \n"
"If a project has no explicit time range set, \n"
"then the range will be calculated based on the \n"
"minimum and maximum dates from any temporal-enabled layers." );

mSetToProjectTimeButton->setToolTip( setToProjectTimeButtonToolTip );
mFixedRangeSetToProjectTimeButton->setToolTip( setToProjectTimeButtonToolTip );

for ( QgsUnitTypes::TemporalUnit u :
{
QgsUnitTypes::TemporalMilliseconds,
@@ -145,6 +167,38 @@ void QgsTemporalControllerWidget::keyPressEvent( QKeyEvent *e )
QWidget::keyPressEvent( e );
}

void QgsTemporalControllerWidget::aboutToShowRangeMenu()
{
QgsDateTimeRange projectRange;
if ( QgsProject::instance()->timeSettings() )
projectRange = QgsProject::instance()->timeSettings()->temporalRange();
mRangeSetToProjectAction->setEnabled( projectRange.begin().isValid() && projectRange.end().isValid() );

mRangeLayersSubMenu->clear();
for ( int i = 0; i < mMapLayerModel->rowCount(); ++i )
{
QModelIndex index = mMapLayerModel->index( i, 0 );
QgsMapLayer *currentLayer = mMapLayerModel->data( index, QgsMapLayerModel::LayerRole ).value<QgsMapLayer *>();
if ( !currentLayer->temporalProperties() || !currentLayer->temporalProperties()->isActive() )
continue;

QIcon icon = qvariant_cast<QIcon>( mMapLayerModel->data( index, Qt::DecorationRole ) );
QString text = mMapLayerModel->data( index, Qt::DisplayRole ).toString();
QgsDateTimeRange range = currentLayer->temporalProperties()->calculateTemporalExtent( currentLayer );
if ( range.begin().isValid() && range.end().isValid() )
{
QAction *action = new QAction( icon, text, mRangeLayersSubMenu.get() );
connect( action, &QAction::triggered, this, [ = ]
{
setDates( range );
saveRangeToProject();
} );
mRangeLayersSubMenu->addAction( action );
}
}
mRangeLayersSubMenu->setEnabled( !mRangeLayersSubMenu->actions().isEmpty() );
}

void QgsTemporalControllerWidget::togglePlayForward()
{
mPlayingForward = true;
@@ -426,11 +480,7 @@ void QgsTemporalControllerWidget::startEndDateTime_changed()
whileBlocking( mFixedRangeEndDateTime )->setDateTime( mEndDateTime->dateTime() );

updateTemporalExtent();

QgsProject::instance()->writeEntry( QStringLiteral( "TemporalControllerWidget" ),
QStringLiteral( "/StartDateTime" ), mStartDateTime->dateTime().toTimeSpec( Qt::OffsetFromUTC ).toString( Qt::ISODate ) );
QgsProject::instance()->writeEntry( QStringLiteral( "TemporalControllerWidget" ),
QStringLiteral( "/EndDateTime" ), mEndDateTime->dateTime().toTimeSpec( Qt::OffsetFromUTC ).toString( Qt::ISODate ) );
saveRangeToProject();
}

void QgsTemporalControllerWidget::fixedRangeStartEndDateTime_changed()
@@ -439,21 +489,38 @@ void QgsTemporalControllerWidget::fixedRangeStartEndDateTime_changed()
whileBlocking( mEndDateTime )->setDateTime( mFixedRangeEndDateTime->dateTime() );

updateTemporalExtent();
saveRangeToProject();
}

QgsProject::instance()->writeEntry( QStringLiteral( "TemporalControllerWidget" ),
QStringLiteral( "/StartDateTime" ), mStartDateTime->dateTime().toTimeSpec( Qt::OffsetFromUTC ).toString( Qt::ISODate ) );
QgsProject::instance()->writeEntry( QStringLiteral( "TemporalControllerWidget" ),
QStringLiteral( "/EndDateTime" ), mEndDateTime->dateTime().toTimeSpec( Qt::OffsetFromUTC ).toString( Qt::ISODate ) );
void QgsTemporalControllerWidget::mRangeSetToAllLayersAction_triggered()
{
setDatesToAllLayers();
saveRangeToProject();
}

void QgsTemporalControllerWidget::mSetToProjectTimeButton_clicked()
void QgsTemporalControllerWidget::mRangeSetToProjectAction_triggered()
{
setDatesToProjectTime();
saveRangeToProject();
}

QgsProject::instance()->writeEntry( QStringLiteral( "TemporalControllerWidget" ),
QStringLiteral( "/StartDateTime" ), mStartDateTime->dateTime().toTimeSpec( Qt::OffsetFromUTC ).toString( Qt::ISODate ) );
QgsProject::instance()->writeEntry( QStringLiteral( "TemporalControllerWidget" ),
QStringLiteral( "/EndDateTime" ), mEndDateTime->dateTime().toTimeSpec( Qt::OffsetFromUTC ).toString( Qt::ISODate ) );
void QgsTemporalControllerWidget::setDates( const QgsDateTimeRange &range )
{
if ( range.begin().isValid() && range.end().isValid() )
{
whileBlocking( mStartDateTime )->setDateTime( range.begin() );
whileBlocking( mEndDateTime )->setDateTime( range.end() );
whileBlocking( mFixedRangeStartDateTime )->setDateTime( range.begin() );
whileBlocking( mFixedRangeEndDateTime )->setDateTime( range.end() );
updateTemporalExtent();
}
}

void QgsTemporalControllerWidget::setDatesToAllLayers()
{
QgsDateTimeRange range;
range = QgsTemporalUtils::calculateTemporalRangeForProject( QgsProject::instance() );
setDates( range );
}

void QgsTemporalControllerWidget::setDatesToProjectTime()
@@ -470,26 +537,13 @@ void QgsTemporalControllerWidget::setDatesToProjectTime()
range = QgsTemporalUtils::calculateTemporalRangeForProject( QgsProject::instance() );
}

if ( range.begin().isValid() && range.end().isValid() )
{
whileBlocking( mStartDateTime )->setDateTime( range.begin() );
whileBlocking( mEndDateTime )->setDateTime( range.end() );
whileBlocking( mFixedRangeStartDateTime )->setDateTime( range.begin() );
whileBlocking( mFixedRangeEndDateTime )->setDateTime( range.end() );
updateTemporalExtent();
}
}

void QgsTemporalControllerWidget::setDateInputsEnable( bool enabled )
{
mStartDateTime->setEnabled( enabled );
mEndDateTime->setEnabled( enabled );
setDates( range );
}

void QgsTemporalControllerWidget::updateButtonsEnable( bool enabled )
void QgsTemporalControllerWidget::saveRangeToProject()
{
mPreviousButton->setEnabled( enabled );
mNextButton->setEnabled( enabled );
mBackButton->setEnabled( enabled );
mForwardButton->setEnabled( enabled );
QgsProject::instance()->writeEntry( QStringLiteral( "TemporalControllerWidget" ),
QStringLiteral( "/StartDateTime" ), mStartDateTime->dateTime().toTimeSpec( Qt::OffsetFromUTC ).toString( Qt::ISODate ) );
QgsProject::instance()->writeEntry( QStringLiteral( "TemporalControllerWidget" ),
QStringLiteral( "/EndDateTime" ), mEndDateTime->dateTime().toTimeSpec( Qt::OffsetFromUTC ).toString( Qt::ISODate ) );
}
@@ -25,6 +25,7 @@
#include "qgstemporalnavigationobject.h"

class QgsMapLayer;
class QgsMapLayerModel;
class QgsTemporalNavigationObject;
class QgsTemporalController;
class QgsInterval;
@@ -69,17 +70,7 @@ class GUI_EXPORT QgsTemporalControllerWidget : public QgsPanelWidget, private Ui

private:

/**
* Updates the controller widget navigation buttons enabled status.
*/
void updateButtonsEnable( bool enabled );

/**
* Sets the enable status of the widget date time inputs.
**/
void setDateInputsEnable( bool enabled );

//! Handles all non gui navigation logic
//! Handles all non-GUI navigation logic
QgsTemporalNavigationObject *mNavigationObject = nullptr;

int mBlockSettingUpdates = 0;
@@ -91,42 +82,61 @@ class GUI_EXPORT QgsTemporalControllerWidget : public QgsPanelWidget, private Ui
void togglePause();
bool mPlayingForward = true;

std::unique_ptr< QMenu > mRangeMenu;
QAction *mRangeSetToProjectAction = nullptr;
QAction *mRangeSetToAllLayersAction = nullptr;

std::unique_ptr< QMenu > mRangeLayersSubMenu;
QgsMapLayerModel *mMapLayerModel = nullptr;

private slots:

/**
* Handles the action to be done when the
* time slider value has changed.
**/
*/
void timeSlider_valueChanged( int value );

/**
* Loads a temporal map settings dialog.
**/
*/
void settings_clicked();

/**
* Updates the controller dates time inputs.
* Set date widgets to match the given \a range.
*/
void setDates( const QgsDateTimeRange &range );

/**
* Updates the controller dates time inputs using the full range of all layers.
*/
void setDatesToAllLayers();

/**
* Updates the controller dates time inputs from the preset project range. If
* that isn't defined, the range will fallback to the full range of all
* layers.
*/
void setDatesToProjectTime();

/**
* Updates the value of the slider
**/
*/
void updateSlider( const QgsDateTimeRange &range );

/**
* Updates the current range label
**/
*/
void updateRangeLabel( const QgsDateTimeRange &range );

/**
* Updates the navigation temporal extent.
**/
*/
void updateTemporalExtent();

/**
* Updates the navigation frame duration.
**/
*/
void updateFrameDuration();

void setWidgetStateFromProject();
@@ -141,7 +151,13 @@ class GUI_EXPORT QgsTemporalControllerWidget : public QgsPanelWidget, private Ui

void startEndDateTime_changed();
void fixedRangeStartEndDateTime_changed();
void mSetToProjectTimeButton_clicked();

void saveRangeToProject();

void aboutToShowRangeMenu();

void mRangeSetToProjectAction_triggered();
void mRangeSetToAllLayersAction_triggered();
};

#endif // QGSTEMPORALCONTROLLERWIDGET_H
@@ -216,7 +216,7 @@
</widget>
</item>
<item>
<widget class="QToolButton" name="mFixedRangeSetToProjectTimeButton">
<widget class="QToolButton" name="mFixedRangeSetRangeButton">
<property name="text">
<string/>
</property>
@@ -441,7 +441,7 @@
</widget>
</item>
<item>
<widget class="QToolButton" name="mSetToProjectTimeButton">
<widget class="QToolButton" name="mSetRangeButton">
<property name="text">
<string/>
</property>

0 comments on commit 204694e

Please sign in to comment.
You can’t perform that action at this time.