Merge branch 'master' of https://github.com/calamares/calamares into development

This commit is contained in:
Philip Müller 2019-08-27 12:20:54 -04:00
commit a9732a71ae
7 changed files with 109 additions and 27 deletions

View File

@ -20,6 +20,9 @@ This release contains contributions from (alphabetically by first name):
(maintained!) upstream version instead. It also gives us KMacroExpander (maintained!) upstream version instead. It also gives us KMacroExpander
everywhere, which will simplify code for handling substitutions everywhere, which will simplify code for handling substitutions
in configuration files. in configuration files.
- *Slideshows* now have a new property *activatedInCalamares* which
controls the keyboard shortcuts (and can control timers and other
properties of the slideshow, too).
## Modules ## ## Modules ##

View File

@ -66,6 +66,16 @@ The setting *slideshowAPI* in `branding.desc` indicates which one to use
for a given branding slideshow. Which API to use is really a function of for a given branding slideshow. Which API to use is really a function of
the QML. Expect the version 1 API to be deprecated in the course of Calamares 3.3. the QML. Expect the version 1 API to be deprecated in the course of Calamares 3.3.
In Calamares 3.2.13 support for activation notification to the QML
parts is improved:
- If the root object has a property *activatedInCalamares* (the examples do),
then that property is set to *true* when the slideshow becomes visible
(activated) and is set to *false* when the slideshow is hidden (e.g.
when the installation phase is done).
- The *actvatedInCalamares* property can be used to set up timers also in V1.
- The keyboard shortcuts in the example slideshow are enabled only while
the slideshow is visible.
## Translations ## Translations

View File

@ -25,14 +25,14 @@ Presentation
id: presentation id: presentation
function nextSlide() { function nextSlide() {
console.log("Next slide"); console.log("QML Component (default slideshow) Next slide");
presentation.goToNextSlide(); presentation.goToNextSlide();
} }
Timer { Timer {
id: advanceTimer id: advanceTimer
interval: 1000 interval: 1000
running: false running: presentation.activatedInCalamares
repeat: true repeat: true
onTriggered: nextSlide() onTriggered: nextSlide()
} }
@ -68,9 +68,19 @@ Presentation
centeredText: qsTr("This is a third Slide element.") centeredText: qsTr("This is a third Slide element.")
} }
// When this slideshow is loaded as a V1 slideshow, only
// activatedInCalamares is set, which starts the timer (see above).
//
// In V2, also the onActivate() and onLeave() methods are called.
// These example functions log a message (and re-start the slides
// from the first).
function onActivate() { function onActivate() {
presentation.currentSlide = 0;
advanceTimer.running = true
console.log("QML Component (default slideshow) activated"); console.log("QML Component (default slideshow) activated");
presentation.currentSlide = 0;
} }
function onLeave() {
console.log("QML Component (default slideshow) deactivated");
}
} }

View File

@ -226,7 +226,9 @@ Branding::Branding( const QString& brandingFilePath, QObject* parent )
QString pathString = slideShowPictures[ i ]; QString pathString = slideShowPictures[ i ];
QFileInfo imageFi( componentDir.absoluteFilePath( pathString ) ); QFileInfo imageFi( componentDir.absoluteFilePath( pathString ) );
if ( !imageFi.exists() ) if ( !imageFi.exists() )
{
bail( QString( "Slideshow file %1 does not exist." ).arg( imageFi.absoluteFilePath() ) ); bail( QString( "Slideshow file %1 does not exist." ).arg( imageFi.absoluteFilePath() ) );
}
slideShowPictures[ i ] = imageFi.absoluteFilePath(); slideShowPictures[ i ] = imageFi.absoluteFilePath();
} }

View File

@ -179,12 +179,63 @@ ExecutionViewStep::loadQmlV2()
} }
} }
/// @brief State-change of the slideshow, for changeSlideShowState()
enum class Slideshow
{
Start,
Stop
};
/** @brief Tells the slideshow we activated or left the show.
*
* If @p state is @c Slideshow::Start, calls suitable activation procedures.
* If @p state is @c Slideshow::Stop, calls deactivation procedures.
*
* Applies V1 and V2 QML activation / deactivation:
* - V1 loads the QML in @p widget on activation. Sets root object property
* *activatedInCalamares* as appropriate.
* - V2 calls onActivate() or onLeave() in the QML as appropriate. Also
* sets the *activatedInCalamares* property.
*/
static void
changeSlideShowState( Slideshow state, QQuickItem* slideshow, QQuickWidget* widget )
{
bool activate = state == Slideshow::Start;
if ( Branding::instance()->slideshowAPI() == 2 )
{
// The QML was already loaded in the constructor, need to start it
callQMLFunction( slideshow, activate ? "onActivate" : "onLeave" );
}
else if ( !Calamares::Branding::instance()->slideshowPath().isEmpty() )
{
// API version 1 assumes onCompleted is the trigger
if ( activate )
{
widget->setSource( QUrl::fromLocalFile( Calamares::Branding::instance()->slideshowPath() ) );
}
// needs the root object for property setting, below
slideshow = widget->rootObject();
}
// V1 API has picked up the root object for use, V2 passed it in.
if ( slideshow )
{
static const char propertyName[] = "activatedInCalamares";
auto property = slideshow->property( propertyName );
if ( property.isValid() && ( property.type() == QVariant::Bool ) && ( property.toBool() != activate ) )
{
slideshow->setProperty( propertyName, activate );
}
}
}
void void
ExecutionViewStep::loadQmlV2Complete() ExecutionViewStep::loadQmlV2Complete()
{ {
if ( m_qmlComponent && m_qmlComponent->isReady() && !m_qmlObject ) if ( m_qmlComponent && m_qmlComponent->isReady() && !m_qmlObject )
{ {
cDebug() << "QML loading complete, API 2"; cDebug() << "QML component complete, API 2";
// Don't do this again // Don't do this again
disconnect( m_qmlComponent, &QQmlComponent::statusChanged, this, &ExecutionViewStep::loadQmlV2Complete ); disconnect( m_qmlComponent, &QQmlComponent::statusChanged, this, &ExecutionViewStep::loadQmlV2Complete );
@ -196,6 +247,8 @@ ExecutionViewStep::loadQmlV2Complete()
} }
else else
{ {
cDebug() << Logger::SubEntry << "Loading" << Calamares::Branding::instance()->slideshowPath();
// setContent() is public API, but not documented publicly. // setContent() is public API, but not documented publicly.
// It is marked \internal in the Qt sources, but does exactly // It is marked \internal in the Qt sources, but does exactly
// what is needed: sets up visual parent by replacing the root // what is needed: sets up visual parent by replacing the root
@ -206,7 +259,7 @@ ExecutionViewStep::loadQmlV2Complete()
{ {
// We're alreay visible! Must have been slow QML loading, and we // We're alreay visible! Must have been slow QML loading, and we
// passed onActivate already. // passed onActivate already.
callQMLFunction( m_qmlObject, "onActivate" ); changeSlideShowState( Slideshow::Start, m_qmlObject, m_qmlShow );
} }
} }
} }
@ -215,16 +268,7 @@ ExecutionViewStep::loadQmlV2Complete()
void void
ExecutionViewStep::onActivate() ExecutionViewStep::onActivate()
{ {
if ( Branding::instance()->slideshowAPI() == 2 ) changeSlideShowState( Slideshow::Start, m_qmlObject, m_qmlShow );
{
// The QML was already loaded in the constructor, need to start it
callQMLFunction( m_qmlObject, "onActivate" );
}
else if ( !Calamares::Branding::instance()->slideshowPath().isEmpty() )
{
// API version 1 assumes onCompleted is the trigger
m_qmlShow->setSource( QUrl::fromLocalFile( Calamares::Branding::instance()->slideshowPath() ) );
}
JobQueue* queue = JobQueue::instance(); JobQueue* queue = JobQueue::instance();
foreach ( const QString& instanceKey, m_jobInstanceKeys ) foreach ( const QString& instanceKey, m_jobInstanceKeys )
@ -272,10 +316,10 @@ ExecutionViewStep::updateFromJobQueue( qreal percent, const QString& message )
void void
ExecutionViewStep::onLeave() ExecutionViewStep::onLeave()
{ {
changeSlideShowState( Slideshow::Stop, m_qmlObject, m_qmlShow );
// API version 2 is explicitly stopped; version 1 keeps running // API version 2 is explicitly stopped; version 1 keeps running
if ( Branding::instance()->slideshowAPI() == 2 ) if ( Branding::instance()->slideshowAPI() == 2 )
{ {
callQMLFunction( m_qmlObject, "onLeave" );
delete m_qmlObject; delete m_qmlObject;
m_qmlObject = nullptr; m_qmlObject = nullptr;
} }

View File

@ -28,6 +28,7 @@
#include "GlobalStorage.h" #include "GlobalStorage.h"
#include "JobQueue.h" #include "JobQueue.h"
#include "utils/CalamaresUtilsSystem.h"
#include "utils/Logger.h" #include "utils/Logger.h"
DummyCppJob::DummyCppJob( QObject* parent ) DummyCppJob::DummyCppJob( QObject* parent )
@ -113,8 +114,9 @@ Calamares::JobResult
DummyCppJob::exec() DummyCppJob::exec()
{ {
// Ported from dummypython // Ported from dummypython
QProcess::execute( "/bin/sh", CalamaresUtils::System::runCommand( CalamaresUtils::System::RunLocation::RunInHost,
QStringList() << "-c" QStringList() << "/bin/sh"
<< "-c"
<< "touch ~/calamares-dummycpp" ); << "touch ~/calamares-dummycpp" );
QString accumulator = QDateTime::currentDateTimeUtc().toString( Qt::ISODate ) + '\n'; QString accumulator = QDateTime::currentDateTimeUtc().toString( Qt::ISODate ) + '\n';
accumulator += QStringLiteral( "Calamares version: " ) + CALAMARES_VERSION_SHORT + '\n'; accumulator += QStringLiteral( "Calamares version: " ) + CALAMARES_VERSION_SHORT + '\n';

View File

@ -8,6 +8,9 @@
* (this and the 'c' key make sense in a *presentation* * (this and the 'c' key make sense in a *presentation*
* slideshow, not in a passive slideshow like Calamares) * slideshow, not in a passive slideshow like Calamares)
* - remove quit key * - remove quit key
* Copyright 2019, Adriaan de Groot <groot@kde.org>
* - Support "V2" loading
* - Disable shortcuts until the content is visible in Calamares
* *
* SPDX-License-Identifier: LGPL-2.1 * SPDX-License-Identifier: LGPL-2.1
* License-Filename: LICENSES/LGPLv2.1-Presentation * License-Filename: LICENSES/LGPLv2.1-Presentation
@ -77,6 +80,14 @@ Item {
property string fontFamily: "Helvetica" property string fontFamily: "Helvetica"
property string codeFontFamily: "Courier New" property string codeFontFamily: "Courier New"
// This is set by the C++ part of Calamares when the slideshow
// becomes visible. You can connect it to a timer, or whatever
// else needs to start only when the slideshow becomes visible.
//
// It is used in this example also to keep the keyboard shortcuts
// enabled only while the slideshow is active.
property bool activatedInCalamares: false
// Private API // Private API
property int _lastShownSlide: 0 property int _lastShownSlide: 0
@ -136,17 +147,17 @@ Item {
Keys.onLeftPressed: goToPreviousSlide() Keys.onLeftPressed: goToPreviousSlide()
// navigate with arrow keys // navigate with arrow keys
Shortcut { sequence: StandardKey.MoveToNextLine; enabled: root.arrowNavigation; onActivated: goToNextSlide() } Shortcut { sequence: StandardKey.MoveToNextLine; enabled: root.activatedInCalamares && root .arrowNavigation; onActivated: goToNextSlide() }
Shortcut { sequence: StandardKey.MoveToPreviousLine; enabled: root.arrowNavigation; onActivated: goToPreviousSlide() } Shortcut { sequence: StandardKey.MoveToPreviousLine; enabled: root.activatedInCalamares && root.arrowNavigation; onActivated: goToPreviousSlide() }
Shortcut { sequence: StandardKey.MoveToNextChar; enabled: root.arrowNavigation; onActivated: goToNextSlide() } Shortcut { sequence: StandardKey.MoveToNextChar; enabled: root.activatedInCalamares && root.arrowNavigation; onActivated: goToNextSlide() }
Shortcut { sequence: StandardKey.MoveToPreviousChar; enabled: root.arrowNavigation; onActivated: goToPreviousSlide() } Shortcut { sequence: StandardKey.MoveToPreviousChar; enabled: root.activatedInCalamares && root.arrowNavigation; onActivated: goToPreviousSlide() }
// presentation-specific single-key shortcuts (which interfere with normal typing) // presentation-specific single-key shortcuts (which interfere with normal typing)
Shortcut { sequence: " "; enabled: root.keyShortcutsEnabled; onActivated: goToNextSlide() } Shortcut { sequence: " "; enabled: root.activatedInCalamares && root.keyShortcutsEnabled; onActivated: goToNextSlide() }
// standard shortcuts // standard shortcuts
Shortcut { sequence: StandardKey.MoveToNextPage; onActivated: goToNextSlide() } Shortcut { sequence: StandardKey.MoveToNextPage; enabled: root.activatedInCalamares; onActivated: goToNextSlide() }
Shortcut { sequence: StandardKey.MoveToPreviousPage; onActivated: goToPreviousSlide() } Shortcut { sequence: StandardKey.MoveToPreviousPage; enabled: root.activatedInCalamares; onActivated: goToPreviousSlide() }
MouseArea { MouseArea {
id: mouseArea id: mouseArea