26#include "phononnamespace_p.h"
27#include "backendinterface.h"
30#include "medianode_p.h"
35class ConnectionTransaction
38 ConnectionTransaction(BackendInterface *b,
const QSet<QObject*> &x) : backend(b), list(x)
42 ~ConnectionTransaction()
52 BackendInterface *
const backend;
56PathPrivate::~PathPrivate()
58#ifndef QT_NO_PHONON_EFFECT
59 for (
int i = 0; i < effects.count(); ++i) {
60 effects.at(i)->k_ptr->removeDestructionHandler(
this);
82 return d->sourceNode !=
nullptr && d->sinkNode !=
nullptr;
85#ifndef QT_NO_PHONON_EFFECT
88 if (!d->effectsParent) {
106 QObject *newEffectBackend = newEffect ? newEffect->k_ptr->backendObject() :
nullptr;
107 if (!
isValid() || !newEffectBackend || d->effects.contains(newEffect) ||
108 (insertBefore && (!d->effects.contains(insertBefore) || !insertBefore->k_ptr->backendObject()))) {
113 const int insertIndex = insertBefore ? d->effects.indexOf(insertBefore) : d->effects.size();
114 if (insertIndex == 0) {
116 leftNode = d->sourceNode->k_ptr->backendObject();
118 leftNode = d->effects[insertIndex - 1]->k_ptr->backendObject();
121 if (insertIndex == d->effects.size()) {
123 rightNode = d->sinkNode->k_ptr->backendObject();
125 Q_ASSERT(insertBefore);
126 rightNode = insertBefore->k_ptr->backendObject();
130 disconnections << QObjectPair(leftNode, rightNode);
131 connections << QObjectPair(leftNode, newEffectBackend)
132 << QObjectPair(newEffectBackend, rightNode);
134 if (d->executeTransaction(disconnections, connections)) {
135 newEffect->k_ptr->addDestructionHandler(d.
data());
136 d->effects.insert(insertIndex, newEffect);
145 return d->removeEffect(effect);
165 QObject *bcurrentSource = d->sourceNode ? d->sourceNode->k_ptr->backendObject() :
nullptr;
166 QObject *bcurrentSink = d->sinkNode ? d->sinkNode->k_ptr->backendObject() :
nullptr;
168 if (bnewSource != bcurrentSource) {
170#ifndef QT_NO_PHONON_EFFECT
171 MediaNode *next = d->effects.isEmpty() ?
sink : d->effects.first();
173 MediaNode *next =
sink;
175 QObject *bnext = next->k_ptr->backendObject();
177 disconnections << QObjectPair(bcurrentSource, bnext);
178 connections << QObjectPair(bnewSource, bnext);
181 if (bnewSink != bcurrentSink) {
182#ifndef QT_NO_PHONON_EFFECT
183 MediaNode *previous = d->effects.isEmpty() ?
source : d->effects.last();
185 MediaNode *previous =
source;
187 QObject *bprevious = previous->k_ptr->backendObject();
189 disconnections << QObjectPair(bprevious, bcurrentSink);
190 QObjectPair pair(bprevious, bnewSink);
195 if (d->executeTransaction(disconnections, connections)) {
198 if (d->sinkNode !=
sink) {
200 d->sinkNode->k_ptr->removeInputPath(*
this);
201 d->sinkNode->k_ptr->removeDestructionHandler(d.
data());
203 sink->k_ptr->addInputPath(*
this);
205 d->sinkNode->k_ptr->addDestructionHandler(d.
data());
209 if (d->sourceNode !=
source) {
210 source->k_ptr->addOutputPath(*
this);
212 d->sourceNode->k_ptr->removeOutputPath(*
this);
213 d->sourceNode->k_ptr->removeDestructionHandler(d.
data());
216 d->sourceNode->k_ptr->addDestructionHandler(d.
data());
232 list << d->sourceNode->k_ptr->backendObject();
233#ifndef QT_NO_PHONON_EFFECT
234 for (
int i = 0; i < d->effects.count(); ++i) {
235 list << d->effects.at(i)->k_ptr->backendObject();
239 list << d->sinkNode->k_ptr->backendObject();
244 if (list.
count() >=2 ) {
245 QObjectList::const_iterator it = list.
constBegin();
246 for(;it+1 != list.
constEnd();++it) {
247 disco << QObjectPair(*it, *(it+1));
255 d->sourceNode->k_ptr->removeOutputPath(*
this);
256 d->sourceNode->k_ptr->removeDestructionHandler(d.
data());
258 d->sourceNode =
nullptr;
260#ifndef QT_NO_PHONON_EFFECT
261 for (
int i = 0; i < d->effects.count(); ++i) {
262 d->effects.at(i)->k_ptr->removeDestructionHandler(d.
data());
268 d->sinkNode->k_ptr->removeInputPath(*
this);
269 d->sinkNode->k_ptr->removeDestructionHandler(d.
data());
271 d->sinkNode =
nullptr;
280 return d->sourceNode;
293 for (
int i = 0; i < disconnections.
count(); ++i) {
294 const QObjectPair &pair = disconnections.
at(i);
295 nodesForTransaction << pair.first;
296 nodesForTransaction << pair.second;
298 for (
int i = 0; i < connections.
count(); ++i) {
299 const QObjectPair &pair = connections.
at(i);
300 nodesForTransaction << pair.first;
301 nodesForTransaction << pair.second;
303 BackendInterface *backend = qobject_cast<BackendInterface *>(Factory::backend());
307 ConnectionTransaction transaction(backend, nodesForTransaction);
312 for(;it != disconnections.
end();++it) {
313 const QObjectPair &pair = *it;
314 if (!backend->disconnectNodes(pair.first, pair.second)) {
318 for(; it2 != it; ++it2) {
319 const QObjectPair &pair = *it2;
320 bool success = backend->connectNodes(pair.first, pair.second);
328 for(it = connections.
begin(); it != connections.
end();++it) {
329 const QObjectPair &pair = *it;
330 if (!backend->connectNodes(pair.first, pair.second)) {
333 for(; it2 != it; ++it2) {
334 const QObjectPair &pair = *it2;
335 bool success = backend->disconnectNodes(pair.first, pair.second);
341 for (
int i = 0; i < disconnections.
count(); ++i) {
342 const QObjectPair &pair = disconnections.
at(i);
343 bool success = backend->connectNodes(pair.first, pair.second);
355#ifndef QT_NO_PHONON_EFFECT
356bool PathPrivate::removeEffect(Effect *effect)
358 if (!effects.contains(effect))
363 const int index = effects.indexOf(effect);
365 leftNode = sourceNode->k_ptr->backendObject();
367 leftNode = effects[index - 1]->k_ptr->backendObject();
369 if (index == effects.size()-1) {
370 rightNode = sinkNode->k_ptr->backendObject();
372 rightNode = effects[index + 1]->k_ptr->backendObject();
376 QObject *beffect = effect->k_ptr->backendObject();
377 disconnections << QObjectPair(leftNode, beffect) << QObjectPair(beffect, rightNode);
378 connections << QObjectPair(leftNode, rightNode);
380 if (executeTransaction(disconnections, connections)) {
381 effect->k_ptr->removeDestructionHandler(
this);
382 effects.removeAt(index);
390void PathPrivate::phononObjectDestroyed(MediaNodePrivate *mediaNodePrivate)
392 Q_ASSERT(mediaNodePrivate);
393 if (mediaNodePrivate == sinkNode->k_ptr || mediaNodePrivate == sourceNode->k_ptr) {
395 QObject *bsink = sinkNode->k_ptr->backendObject();
396 QObject *bsource = sourceNode->k_ptr->backendObject();
398#ifndef QT_NO_PHONON_EFFECT
399 disconnections << QObjectPair(bsource, effects.isEmpty() ? bsink : effects.first()->k_ptr->backendObject());
400 if (!effects.isEmpty())
401 disconnections << QObjectPair(effects.last()->k_ptr->backendObject(), bsink);
403 disconnections << QObjectPair(bsource, bsink);
410 if (mediaNodePrivate == sinkNode->k_ptr) {
411 sourceNode->k_ptr->removeOutputPath(p);
412 sourceNode->k_ptr->removeDestructionHandler(
this);
414 sinkNode->k_ptr->removeInputPath(p);
415 sinkNode->k_ptr->removeDestructionHandler(
this);
417 sourceNode =
nullptr;
420#ifndef QT_NO_PHONON_EFFECT
421 for (
int i = 0; i < effects.count(); ++i) {
422 Effect *e = effects.at(i);
423 if (e->k_ptr == mediaNodePrivate) {
431Path createPath(MediaNode *source, MediaNode *sink)
435 const QObject *
const src = source ? (source->k_ptr->qObject()
436#ifndef QT_NO_DYNAMIC_CAST
437 ? source->k_ptr->qObject() :
dynamic_cast<QObject *
>(source)
440 const QObject *
const snk = sink ? (sink->k_ptr->qObject()
441#ifndef QT_NO_DYNAMIC_CAST
442 ? sink->k_ptr->qObject() :
dynamic_cast<QObject *
>(sink)
445 pWarning() <<
"Phonon::createPath: Cannot connect "
446 << (src ? src->
metaObject()->className() :
"")
447 <<
'(' << (src ? (src->
objectName().isEmpty() ?
"no objectName" : qPrintable(src->
objectName())) :
"null") <<
") to "
448 << (snk ? snk->
metaObject()->className() :
"")
449 <<
'(' << (snk ? (snk->
objectName().isEmpty() ?
"no objectName" : qPrintable(snk->
objectName())) :
"null")
virtual bool startConnectionChange(QSet< QObject * >)=0
When this function is called the nodes given in the parameter list should not lose any signal data wh...
virtual bool endConnectionChange(QSet< QObject * >)=0
When this function is called the nodes given in the parameter list may lose signal data when a port i...
Effects that can be inserted into a Path.
Provides a tuple of enduser visible name and description.
Connection object providing convenient effect insertion.
bool operator!=(const Path &p) const
Returns true if this Path is not equal to p; otherwise returns false;.
Path & operator=(const Path &p)
Assigns p to this Path and returns a reference to this Path.
Effect * insertEffect(const EffectDescription &desc, Effect *insertBefore=nullptr)
Creates and inserts an effect into the path.
bool reconnect(MediaNode *source, MediaNode *sink)
Tries to change the MediaNodes the path is connected to.
bool removeEffect(Effect *effect)
Removes an effect from the path.
Path()
Creates an invalid path.
bool isValid() const
Returns whether the path object connects two MediaNodes or not.
bool operator==(const Path &p) const
Returns true if this Path is equal to p; otherwise returns false;.
~Path()
Destroys this reference to the Path.
MediaNode * sink() const
Returns the sink MediaNode used by the path.
QList< Effect * > effects() const
Returns a list of Effect objects that are currently used as effects.
bool disconnect()
Disconnects the path from the MediaNodes it was connected to.
MediaNode * source() const
Returns the source MediaNode used by the path.
const_reference at(qsizetype i) const const
const_iterator constBegin() const const
const_iterator constEnd() const const
bool contains(const AT &value) const const
qsizetype count() const const