Skip to content

Commit

Permalink
Merge branch 'master' into winbuild
Browse files Browse the repository at this point in the history
  • Loading branch information
mcallegari committed Mar 6, 2023
2 parents dc743d9 + 2d03619 commit 0be5c32
Show file tree
Hide file tree
Showing 50 changed files with 2,130 additions and 173 deletions.
8 changes: 8 additions & 0 deletions debian/changelog
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ qlcplus (4.12.7) stable; urgency=low
* Virtual Console: submaster now affects widgets on all pages but only on active frames
* Web Access: add support for widget background images
* Input profiles: added ADJ MIDICON-2 (thanks to David Thomas)
* Input profiles: added Akai APC Mini MK2 (thanks to Michael Mertens)
* Fixture updated: Blizzard Lighting Pixellicious (thanks to Yestalgia)
* New fixture: Vari-Lite VL4000 Spot (thanks to Håvard Ose Nordstrand)
* New fixtures: Clay Paky Tambora Batten, Tambora Flash, Tambora Linear 100, Sharpy X Frame, Volero Wave (thanks to Gianluca Baggi)
Expand All @@ -39,6 +40,13 @@ qlcplus (4.12.7) stable; urgency=low
* New fixture: U'King ZQ-B93 Pinspot RGBW (thanks to Jarosław Biernacki)
* New fixtures: Stage Right 200W COB LED Ellipsoidal, Stage Right 30W LED Spot (thanks to Dave Vecchio)
* New fixture: Rockville Rockwedge LED (thanks to Ryan Carter)
* New fixture: Showtec Starforce LED (thanks to gnomesenpai)
* New fixture: Chauvet SlimPAR Pro Pix (thanks to Ryan Carter)
* New fixture: DTS Scena LED 200 (thanks to Freddy Hoogstoel)
* New fixture: Chauvet Intimidator Beam Q60 (thanks to Nathan)
* New fixtures: Eurolite LED T-36 RGB Spot, Eurolite LED SLS-183/10 RGB, Stairville Stage PAR CX-2 RGBAW (thanks to Felix Hartnagel)
* New fixture: American DJ WiFly Bar QA5 (thanks to Edgar Aichinger)
* New fixture: Laserworld EL-230RGB MK2 (thanks to e-shock)

-- Massimo Callegari <massimocallegari@yahoo.it> Sun, 12 Mar 2023 12:13:14 +0200

Expand Down
7 changes: 7 additions & 0 deletions engine/audio/src/audio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,13 @@ void Audio::preRun(MasterTimer* timer)
{
uint fadeIn = overrideFadeInSpeed() == defaultSpeed() ? fadeInSpeed() : overrideFadeInSpeed();

if (m_audio_out != NULL && m_audio_out->isRunning())
{
m_audio_out->stop();
m_audio_out->deleteLater();
m_audio_out = NULL;
}

m_decoder->seek(elapsed());
AudioParameters ap = m_decoder->audioParameters();
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
Expand Down
3 changes: 3 additions & 0 deletions engine/audio/src/audiorenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ void AudioRenderer::adjustIntensity(qreal fraction)

void AudioRenderer::setFadeIn(uint fadeTime)
{
m_fadeStep = 0;
m_currentIntensity = 1.0;

if (fadeTime == 0 || m_adec == NULL)
return;

Expand Down
10 changes: 10 additions & 0 deletions engine/src/chaserrunner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,16 @@ int ChaserRunner::getNextStepIndex()
m_chaser->direction() == Function::Backward)
currentStepIndex = m_chaser->stepsCount();

// Handle reverse Ping Pong at boundaries
if (m_chaser->runOrder() == Function::PingPong &&
m_pendingAction.m_action == ChaserPreviousStep)
{
if (currentStepIndex == 0)
m_direction = Function::Backward;
else if (currentStepIndex == m_chaser->stepsCount() - 1)
m_direction = Function::Forward;
}

// Next step
if (m_direction == Function::Forward)
{
Expand Down
3 changes: 3 additions & 0 deletions plugins/artnet/src/artnetcontroller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,9 @@ bool ArtNetController::handleArtNetRDM(const QByteArray &datagram, const QHostAd

bool ArtNetController::handlePacket(QByteArray const& datagram, QHostAddress const& senderAddress)
{
//if (senderAddress.toIPv4Address() == m_ipAddr.toIPv4Address())
// return false;

#if _DEBUG_RECEIVED_PACKETS
qDebug() << "Received packet with size: " << datagram.size() << ", host: " << senderAddress.toString();
#endif
Expand Down
2 changes: 1 addition & 1 deletion plugins/artnet/src/artnetpacketizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ void ArtNetPacketizer::setupArtNetPollReply(QByteArray &data, QHostAddress ipAdd
for (i = 0; i < 14; i++)
data.append((char)0x00); // 14 bytes of stuffing
data.append("Q Light Controller Plus - ArtNet interface"); // Long Name
for (i = 0; i < 22; i++) // 64-42 bytes of stuffing. 42 is the lenght of the long name
for (i = 0; i < 22; i++) // 64-42 bytes of stuffing. 42 is the length of the long name
data.append((char)0x00);
for (i = 0; i < 64; i++)
data.append((char)0x00); // Node report
Expand Down
24 changes: 16 additions & 8 deletions plugins/interfaces/rdmprotocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

RDMProtocol::RDMProtocol()
: m_estaID(QLCPLUS_ESTA_ID)
, m_deviceID(0x01090709)
, m_deviceID(QLCPLUS_DEVICE_ID)
, m_transactionNum(0x01)
{
}
Expand Down Expand Up @@ -148,6 +148,14 @@ bool RDMProtocol::packetizeCommand(ushort command, QVariantList params, bool sta
{
int size = params.at(i).toInt();

// special case for byte arrays
if (size == 99)
{
QByteArray ba = params.at(i + 1).toByteArray();
buffer.append(ba);
break;
}

switch (size)
{
case 1:
Expand All @@ -159,11 +167,6 @@ bool RDMProtocol::packetizeCommand(ushort command, QVariantList params, bool sta
case 4:
buffer.append(longToByteArray(params.at(i + 1).toUInt()));
break;
case 99:
{
QByteArray ba = params.at(i + 1).toByteArray();
buffer.append(ba);
}
default:
break;
}
Expand Down Expand Up @@ -285,6 +288,10 @@ bool RDMProtocol::parsePacket(const QByteArray &buffer, QVariantMap &values)
QString sourceUID = byteArrayToUID(buffer.mid(i, 6), ESTAId, deviceId);
i += 6;

// check if we are reading our own request
if (ESTAId == m_estaID && deviceId == m_deviceID)
return false;

values.insert("UID_INFO", sourceUID);

// transaction number
Expand Down Expand Up @@ -339,12 +346,13 @@ bool RDMProtocol::parsePacket(const QByteArray &buffer, QVariantMap &values)
case PID_SUPPORTED_PARAMETERS:
{
QVector<quint16> pidList;

QDebug out = qDebug();
out.nospace().noquote() << "Supported PIDs list: ";
for (int n = 0; n < PDL; n += 2)
{
quint16 pid = byteArrayToShort(buffer, i + n);
pidList.append(pid);
qDebug().nospace().noquote() << "Supported PID: 0x" << QString::number(pid, 16);
out << "0x" << QString::number(pid, 16) << ", ";
}
values.insert("PID_LIST", QVariant::fromValue(pidList));
}
Expand Down
9 changes: 7 additions & 2 deletions plugins/interfaces/rdmprotocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@
#define PID_POWER_ON_SELF_TEST 0x1044

#define QLCPLUS_ESTA_ID 0x7FF8
#define QLCPLUS_DEVICE_ID 0x01090709
#define BROADCAST_ESTA_ID 0xFFFF
#define BROADCAST_DEVICE_ID 0xFFFFFFFF

Expand Down Expand Up @@ -180,15 +181,19 @@ class RDMProtocol
/** Return a PID as a string */
static QString pidToString(quint16 pid);

/** Return the RDM command reply as a string */
static QString responseToString(quint8 response);

/** Return the device info category as string */
static QString categoryToString(quint16 category);

private:
QByteArray UIDToByteArray(quint16 ESTAId, quint32 deviceId);
QByteArray shortToByteArray(quint16 data);
QByteArray longToByteArray(quint32 data);
quint16 byteArrayToShort(const QByteArray &buffer, int index);
quint32 byteArrayToLong(const QByteArray &buffer, int index);
quint16 calculateChecksum(bool startCode, const QByteArray &ba, int len);
QString responseToString(quint8 response);
QString categoryToString(quint16 category);

protected:
quint16 m_estaID;
Expand Down
33 changes: 32 additions & 1 deletion qmlui/chasereditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,8 @@ void ChaserEditor::setPlaybackIndex(int playbackIndex)
if (m_playbackIndex == playbackIndex)
return;

if (m_chaser != nullptr && m_chaser->type() == Function::SequenceType && playbackIndex >= 0)
if (m_chaser != nullptr && m_previewEnabled == false &&
m_chaser->type() == Function::SequenceType && playbackIndex >= 0)
{
Sequence *sequence = qobject_cast<Sequence*>(m_chaser);
Scene *currScene = qobject_cast<Scene*> (m_doc->function(sequence->boundSceneID()));
Expand Down Expand Up @@ -297,6 +298,36 @@ void ChaserEditor::deleteItems(QVariantList list)
emit stepsListChanged();
}

void ChaserEditor::removeFixtures(QVariantList list)
{
if (m_chaser == nullptr)
return;

Sequence *sequence = qobject_cast<Sequence *>(m_chaser);
Scene *scene = qobject_cast<Scene *>(m_doc->function(sequence->boundSceneID()));
if (scene == nullptr)
return;

// transform the list of fixture indices into a list of fixture IDs
QList<quint32> sceneFixtureList = scene->fixtures();
QList<quint32> fixtureIdList;
for (QVariant &fIndex : list)
fixtureIdList.append(sceneFixtureList.at(fIndex.toInt()));

// run though steps and search for matching fixture IDs
for (int i = 0; i < m_chaser->stepsCount(); i++)
{
ChaserStep *step = m_chaser->stepAt(i);
QMutableListIterator<SceneValue> it(step->values);
while (it.hasNext())
{
SceneValue scv = it.next();
if (fixtureIdList.contains(scv.fxi))
it.remove();
}
}
}

void ChaserEditor::slotStepIndexChanged(int index)
{
setPlaybackIndex(index);
Expand Down
2 changes: 2 additions & 0 deletions qmlui/chasereditor.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ class ChaserEditor : public FunctionEditor
/** @reimp */
void deleteItems(QVariantList list);

void removeFixtures(QVariantList list);

protected:
/** Set the steps $param to $value.
* If $selectedOnly is true, $value is applied only to the selected steps,
Expand Down
57 changes: 57 additions & 0 deletions qmlui/fixturemanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -842,6 +842,63 @@ QString FixtureManager::fixtureIcon(quint32 fixtureID)
return fixture->iconResource(true);
}

QStringList FixtureManager::fixtureModes(quint32 itemID)
{
QStringList modes;
quint32 fixtureID = FixtureUtils::itemFixtureID(itemID);
Fixture *fixture = m_doc->fixture(fixtureID);
if (fixture == nullptr)
return modes;

for (QLCFixtureMode *mode : fixture->fixtureDef()->modes())
modes.append(mode->name());

return modes;
}

int FixtureManager::fixtureModeIndex(quint32 itemID)
{
quint32 fixtureID = FixtureUtils::itemFixtureID(itemID);
Fixture *fixture = m_doc->fixture(fixtureID);
if (fixture == nullptr)
return -1;

QLCFixtureMode *currMode = fixture->fixtureMode();
QList<QLCFixtureMode *> modes = fixture->fixtureDef()->modes();

return modes.indexOf(currMode);
}

bool FixtureManager::setFixtureModeIndex(quint32 itemID, int index)
{
quint32 fixtureID = FixtureUtils::itemFixtureID(itemID);
Fixture *fixture = m_doc->fixture(fixtureID);
if (fixture == nullptr)
return false;

QList<QLCFixtureMode *> modes = fixture->fixtureDef()->modes();
if (index < 0 || index >= modes.count())
return false;

QLCFixtureMode *newMode = modes.at(index);

// check if new channels are available
int chNum = newMode->channels().count();

for (quint32 i = fixture->universeAddress(); i < fixture->universeAddress() + chNum; i++)
{
quint32 id = m_doc->fixtureForAddress(i);
if (id != fixture->id() && id != Fixture::invalidId())
return false;
}

fixture->setFixtureDefinition(fixture->fixtureDef(), newMode);

emit fixturesMapChanged();

return true;
}

int FixtureManager::fixtureIDfromItemID(quint32 itemID)
{
return FixtureUtils::itemFixtureID(itemID);
Expand Down
8 changes: 8 additions & 0 deletions qmlui/fixturemanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,14 @@ public slots:
/** Return the type as string of the Fixture with ID $fixtureID */
Q_INVOKABLE QString fixtureIcon(quint32 fixtureID);

/** Return the list of modes available for the item with the provided $itemID */
Q_INVOKABLE QStringList fixtureModes(quint32 itemID);

/** Get/Set the currently selected fixture mode index
* for the item with the provided $itemID */
Q_INVOKABLE int fixtureModeIndex(quint32 itemID);
Q_INVOKABLE bool setFixtureModeIndex(quint32 itemID, int index);

/** Return the Fixture ID of the provided $itemID */
Q_INVOKABLE int fixtureIDfromItemID(quint32 itemID);

Expand Down
20 changes: 20 additions & 0 deletions qmlui/functionmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,13 @@ quint32 FunctionManager::createFunction(int type, QVariantList fixturesList)
* that awful effect of playing steps with 0 duration */
Chaser *chaser = qobject_cast<Chaser*>(f);
chaser->setDuration(1000);

for (QVariant &fId : m_selectedIDList)
{
ChaserStep chs;
chs.fid = fId.toUInt();
chaser->addStep(chs);
}
}
m_chaserCount++;
emit chaserCountChanged();
Expand Down Expand Up @@ -844,6 +851,19 @@ void FunctionManager::deleteEditorItems(QVariantList list)
m_currentEditor->deleteItems(list);
}

void FunctionManager::deleteSequenceFixtures(QVariantList list)
{
if (m_sceneEditor == nullptr)
return;

// First remove fixtures from the Sequence steps
ChaserEditor *chaserEditor = qobject_cast<ChaserEditor*>(m_currentEditor);
chaserEditor->removeFixtures(list);

// Then delete the fixtures from the Scene
m_sceneEditor->deleteItems(list);
}

void FunctionManager::renameSelectedItems(QString newName, bool numbering, int startNumber, int digits)
{
if (m_selectedIDList.isEmpty() && m_selectedFolderList.isEmpty())
Expand Down
4 changes: 4 additions & 0 deletions qmlui/functionmanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,10 @@ class FunctionManager : public QObject
* This happens AFTER a popup confirmation */
Q_INVOKABLE void deleteEditorItems(QVariantList list);

/** Specific method to delete fixtures from the currently edited Sequence.
* This happens AFTER a popup confirmation */
Q_INVOKABLE void deleteSequenceFixtures(QVariantList list);

/** Rename the currently selected items (functions and/or folders)
* with the provided $newName.
* If $numbering is true, then $startNumber and $digits will compose
Expand Down

0 comments on commit 0be5c32

Please sign in to comment.