void QLCFixtureMode_Test::copy()
{
    QLCFixtureMode* mode = new QLCFixtureMode(m_fixtureDef);
    mode->setName("Test Mode");

    mode->insertChannel(m_ch1, 0);
    mode->insertChannel(m_ch2, 1);
    mode->insertChannel(m_ch3, 2);
    mode->insertChannel(m_ch4, 3);

    /* Create a copy of the mode to the same fixtureDef as the original */
    QLCFixtureMode* copy = new QLCFixtureMode(m_fixtureDef, mode);
    QVERIFY(copy != NULL);

    QVERIFY(copy->name() == "Test Mode");
    QVERIFY(copy->channels().size() == 4);
    QVERIFY(copy->channel(0) == m_ch1);
    QVERIFY(copy->channel(1) == m_ch2);
    QVERIFY(copy->channel(2) == m_ch3);
    QVERIFY(copy->channel(3) == m_ch4);
    delete copy;
    copy = NULL;

    /* Create another fixture def with some channels matching, some not */
    QLCFixtureDef* anotherDef = new QLCFixtureDef();
    QLCChannel* ch1 = new QLCChannel();
    ch1->setName("Channel 1"); // Should match
    anotherDef->addChannel(ch1);

    QLCChannel* ch2 = new QLCChannel();
    ch2->setName("Channel 2, not the same name"); // Shouldn't match
    anotherDef->addChannel(ch2);

    QLCChannel* ch3 = new QLCChannel();
    ch3->setName("Channel 3, still not the same name"); // Shouldn't match
    anotherDef->addChannel(ch3);

    QLCChannel* ch4 = new QLCChannel();
    ch4->setName("Channel 4"); // Should match
    anotherDef->addChannel(ch4);

    QLCChannel* ch5 = new QLCChannel();
    ch5->setName("Channel 5"); // Shouldn't match since original has 4 chans
    anotherDef->addChannel(ch5);

    /* Create a copy of the mode to the other fixtureDef */
    copy = new QLCFixtureMode(anotherDef, mode);

    QVERIFY(copy->name() == "Test Mode");
    QVERIFY(copy->channels().size() == 2);

    QVERIFY(copy->channel(0)->name() == "Channel 1");
    QVERIFY(copy->channel(0) == ch1);

    QVERIFY(copy->channel(1)->name() == "Channel 4");
    QVERIFY(copy->channel(1) == ch4);

    delete copy;
    delete anotherDef;
}
void QLCFixtureMode_Test::channels()
{
    QLCFixtureMode* mode = new QLCFixtureMode(m_fixtureDef);
    QVERIFY(mode->channels().size() == 0);

    mode->insertChannel(m_ch1, 0);
    QVERIFY(mode->channels().size() == 1);

    mode->insertChannel(m_ch2, 1);
    QVERIFY(mode->channels().size() == 2);

    mode->insertChannel(m_ch3, 2);
    QVERIFY(mode->channels().size() == 3);

    delete mode;
}
Example #3
0
void QLCFixtureEditor::refreshModeList()
{
	QTreeWidgetItem* item;
	QLCFixtureMode* mode;
	QString str;

	m_modeList->clear();

	// Fill channels list
	QListIterator <QLCFixtureMode*> it(*m_fixtureDef->modes());
	while (it.hasNext() == true)
	{
		mode = it.next();

		item = new QTreeWidgetItem(m_modeList);
		item->setText(KModesColumnName, mode->name());
		str.sprintf("%d", mode->channels());
		item->setText(KModesColumnChannels, str);

		// Store the channel pointer to the listview as a string
		str.sprintf("%lu", (unsigned long) mode);
		item->setText(KModesColumnPointer, str);
	}
	
	slotModeListSelectionChanged(m_modeList->currentItem());
}
Example #4
0
void Fixture_Test::fixtureDef()
{
    Fixture fxi(this);

    QVERIFY(fxi.fixtureDef() == NULL);
    QVERIFY(fxi.fixtureMode() == NULL);
    QVERIFY(fxi.channels() == 0);
    QVERIFY(fxi.channel(0) == NULL);
    QCOMPARE(fxi.panMsbChannel(), QLCChannel::invalid());
    QCOMPARE(fxi.tiltMsbChannel(), QLCChannel::invalid());
    QCOMPARE(fxi.panLsbChannel(), QLCChannel::invalid());
    QCOMPARE(fxi.tiltLsbChannel(), QLCChannel::invalid());
    QCOMPARE(fxi.masterIntensityChannel(), QLCChannel::invalid());

    QLCFixtureDef* fixtureDef;
    fixtureDef = m_doc->fixtureDefCache()->fixtureDef("Martin", "MAC300");
    Q_ASSERT(fixtureDef != NULL);

    fxi.setFixtureDefinition(fixtureDef, NULL);
    QVERIFY(fxi.fixtureDef() == NULL);
    QVERIFY(fxi.fixtureMode() == NULL);

    QLCFixtureMode* fixtureMode;
    fixtureMode = fixtureDef->modes().last();
    Q_ASSERT(fixtureMode != NULL);

    fxi.setFixtureDefinition(NULL, fixtureMode);
    QVERIFY(fxi.fixtureDef() == NULL);
    QVERIFY(fxi.fixtureMode() == NULL);

    fxi.setFixtureDefinition(fixtureDef, fixtureMode);
    QVERIFY(fxi.fixtureDef() != NULL);
    QVERIFY(fxi.fixtureMode() != NULL);
    QVERIFY(fxi.fixtureDef() == fixtureDef);
    QVERIFY(fxi.fixtureMode() == fixtureMode);

    QVERIFY(fxi.channels() == quint32(fixtureMode->channels().count()));
    QVERIFY(fxi.channel(fxi.channels() - 1) != NULL);
    QVERIFY(fxi.channel(fxi.channels()) == NULL);

    QVERIFY(fxi.channel(QLCChannel::Pan) != QLCChannel::invalid());
    const QLCChannel* ch = fxi.channel(fxi.channel(QLCChannel::Pan));
    QVERIFY(ch != NULL);

    QCOMPARE(fxi.panMsbChannel(), quint32(7));
    QCOMPARE(fxi.tiltMsbChannel(), quint32(9));
    QCOMPARE(fxi.panLsbChannel(), quint32(8));
    QCOMPARE(fxi.tiltLsbChannel(), quint32(10));
    QCOMPARE(fxi.masterIntensityChannel(), quint32(1));
    QCOMPARE(fxi.rgbChannels(), QVector <quint32> ());
    QCOMPARE(fxi.cmyChannels(), QVector <quint32> () << 2 << 3 << 4);
}
void QLCFixtureMode_Test::insertChannel()
{
    QLCFixtureMode* mode = new QLCFixtureMode(m_fixtureDef);
    mode->setName("Test");

    QVERIFY(mode->insertChannel(NULL, 0) == false);
    QVERIFY(mode->channels().size() == 0);

    /* Channel that doesn't belong to mode->fixtureDef() */
    QLCChannel* ch = new QLCChannel();
    ch->setName("Rogue");
    mode->insertChannel(ch, 0);
    QVERIFY(mode->channels().size() == 0);
    delete ch;

    /* First channel */
    mode->insertChannel(m_ch1, 0);
    QVERIFY(mode->channel(0) == m_ch1);

    /* Second prepended */
    mode->insertChannel(m_ch2, 0);
    QVERIFY(mode->channel(0) == m_ch2);
    QVERIFY(mode->channel(1) == m_ch1);

    /* Third appended way over the end */
    mode->insertChannel(m_ch3, 10);
    QVERIFY(mode->channel(0) == m_ch2);
    QVERIFY(mode->channel(1) == m_ch1);
    QVERIFY(mode->channel(2) == m_ch3);

    /* Fourth inserted in-between */
    mode->insertChannel(m_ch4, 1);
    QVERIFY(mode->channel(0) == m_ch2);
    QVERIFY(mode->channel(1) == m_ch4);
    QVERIFY(mode->channel(2) == m_ch1);
    QVERIFY(mode->channel(3) == m_ch3);

    delete mode;
}
void QLCFixtureMode_Test::removeChannel()
{
    QLCFixtureMode* mode = new QLCFixtureMode(m_fixtureDef);

    mode->insertChannel(m_ch1, 0);
    mode->insertChannel(m_ch2, 1);
    mode->insertChannel(m_ch3, 2);
    mode->insertChannel(m_ch4, 3);

    /* Remove one channel in the middle */
    QVERIFY(mode->channels().size() == 4);
    mode->removeChannel(m_ch2);
    QVERIFY(mode->channels().size() == 3);
    QVERIFY(mode->channel(0) == m_ch1);
    QVERIFY(mode->channel(1) == m_ch3);
    QVERIFY(mode->channel(2) == m_ch4);
    QVERIFY(mode->channel(3) == NULL);

    /* Remove the same channel again. Shouldn't change anything. */
    mode->removeChannel(m_ch2);
    QVERIFY(mode->channels().size() == 3);
    QVERIFY(mode->channel(0) == m_ch1);
    QVERIFY(mode->channel(1) == m_ch3);
    QVERIFY(mode->channel(2) == m_ch4);
    QVERIFY(mode->channel(3) == NULL);

    /* Remove last channel. */
    mode->removeChannel(m_ch4);
    QVERIFY(mode->channels().size() == 2);
    QVERIFY(mode->channel(0) == m_ch1);
    QVERIFY(mode->channel(1) == m_ch3);
    QVERIFY(mode->channel(2) == NULL);
    QVERIFY(mode->channel(3) == NULL);

    /* Remove first channel. */
    mode->removeChannel(m_ch1);
    QVERIFY(mode->channels().size() == 1);
    QVERIFY(mode->channel(0) == m_ch3);
    QVERIFY(mode->channel(1) == NULL);
    QVERIFY(mode->channel(2) == NULL);
    QVERIFY(mode->channel(3) == NULL);

    /* Remove last channel. */
    mode->removeChannel(m_ch3);
    QVERIFY(mode->channels().size() == 0);
    QVERIFY(mode->channel(0) == NULL);
    QVERIFY(mode->channel(1) == NULL);
    QVERIFY(mode->channel(2) == NULL);
    QVERIFY(mode->channel(3) == NULL);

    delete mode;
}
Example #7
0
void QLCFixtureEditor::slotEditMode()
{
	QLCFixtureMode* mode = currentMode();
	QString str;

	if (mode == NULL)
		return;
	
	EditMode em(this, mode);
	if (em.exec() == QDialog::Accepted)
	{
		QTreeWidgetItem* item = NULL;
		*mode = *(em.mode());
		
		item = m_modeList->currentItem();
		item->setText(KModesColumnName, mode->name());
		str.sprintf("%d", mode->channels());
		item->setText(KModesColumnChannels, str);
		
		setModified();
	}
}
Example #8
0
void Fixture::setFixtureDefinition(const QLCFixtureDef* fixtureDef,
                                   const QLCFixtureMode* fixtureMode)
{
    if (fixtureDef != NULL && fixtureMode != NULL)
    {
        m_fixtureDef = fixtureDef;
        m_fixtureMode = fixtureMode;

        // If there are no head entries in the mode, create one that contains
        // all channels. This const_cast is a bit heretic, but it's easier this
        // way, than to change everything def & mode related non-const, which would
        // be worse than one constness violation here.
        QLCFixtureMode* mode = const_cast<QLCFixtureMode*> (fixtureMode);
        if (mode->heads().size() == 0)
        {
            QLCFixtureHead head;
            for (int i = 0; i < mode->channels().size(); i++)
                head.addChannel(i);
            mode->insertHead(-1, head);
        }

        // Cache all head channels
        mode->cacheHeads();

        if (m_genericChannel != NULL)
            delete m_genericChannel;
        m_genericChannel = NULL;
    }
    else
    {
        m_fixtureDef = NULL;
        m_fixtureMode = NULL;
        createGenericChannel();
    }

    emit changed(m_id);
}
Example #9
0
void EFX::arm()
{
	class Scene* startScene = NULL;
	class Scene* stopScene = NULL;
	QLCFixtureMode* mode = NULL;
	QLCChannel* ch = NULL;
	int serialNumber = 0;
	Fixture* fxi = NULL;

	/* Initialization scene */
	if (m_startSceneID != KNoID && m_startSceneEnabled == true)
		startScene = static_cast <class Scene*>
			(_app->doc()->function(m_startSceneID));

	/* De-initialization scene */
	if (m_stopSceneID != KNoID && m_stopSceneEnabled == true)
		stopScene = static_cast <class Scene*>
			(_app->doc()->function(m_stopSceneID));

	QListIterator <EFXFixture*> it(m_fixtures);
	while (it.hasNext() == true)
	{
		EFXFixture* ef = it.next();
		Q_ASSERT(ef != NULL);

		ef->setSerialNumber(serialNumber++);
		ef->setStartScene(startScene);
		ef->setStopScene(stopScene);

		/* If fxi == NULL, the fixture has been destroyed */
		fxi = _app->doc()->fixture(ef->fixture());
		if (fxi == NULL)
			continue;

		/* If this fixture has no mode, it's a generic dimmer that
		   can't do pan&tilt anyway. */
		mode = fxi->fixtureMode();
		if (mode == NULL)
			continue;

		/* Find exact channel numbers for MSB/LSB pan and tilt */
		for (t_channel i = 0; i < mode->channels(); i++)
		{
			ch = mode->channel(i);
			Q_ASSERT(ch != NULL);

			if (ch->group() == KQLCChannelGroupPan)
			{
				if (ch->controlByte() == 0)
				{
					ef->setMsbPanChannel(
						fxi->universeAddress() + i);
				}
				else if (ch->controlByte() == 1)
				{
					ef->setLsbPanChannel(
						fxi->universeAddress() + i);
				}
			}
			else if (ch->group() == KQLCChannelGroupTilt)
			{
				if (ch->controlByte() == 0)
				{
					ef->setMsbTiltChannel(
						fxi->universeAddress() + i);
				}
				else if (ch->controlByte() == 1)
				{
					ef->setLsbTiltChannel(
						fxi->universeAddress() + i);
				}
			}
		}
	}

	/* Choose a point calculation function depending on the algorithm */
	if (m_algorithm == KCircleAlgorithmName)
		pointFunc = circlePoint;
	else if (m_algorithm == KEightAlgorithmName)
		pointFunc = eightPoint;
	else if (m_algorithm == KLineAlgorithmName)
		pointFunc = linePoint;
	else if (m_algorithm == KTriangleAlgorithmName)
		pointFunc = trianglePoint;
	else if (m_algorithm == KDiamondAlgorithmName)
		pointFunc = diamondPoint;
	else if (m_algorithm == KLissajousAlgorithmName)
		pointFunc = lissajousPoint;
	else
		pointFunc = NULL;
}
Example #10
0
void Fixture_Test::save()
{
    QLCFixtureDef* fixtureDef;
    fixtureDef = m_doc->fixtureDefCache()->fixtureDef("Martin", "MAC250+");
    Q_ASSERT(fixtureDef != NULL);

    QLCFixtureMode* fixtureMode;
    fixtureMode = fixtureDef->modes().at(0);
    Q_ASSERT(fixtureMode != NULL);

    Fixture fxi(this);
    fxi.setID(1337);
    fxi.setName("Test Fixture");
    fxi.setUniverse(2);
    fxi.setAddress(438);
    fxi.setFixtureDefinition(fixtureDef, fixtureMode);

    QBuffer buffer;
    buffer.open(QIODevice::WriteOnly | QIODevice::Text);
    QXmlStreamWriter xmlWriter(&buffer);

    xmlWriter.writeStartElement("TestRoot");

    QVERIFY(fxi.saveXML(&xmlWriter) == true);

    xmlWriter.setDevice(NULL);
    buffer.close();

    buffer.open(QIODevice::ReadOnly | QIODevice::Text);
    QXmlStreamReader xmlReader(&buffer);
    xmlReader.readNextStartElement();
    QVERIFY(xmlReader.name().toString() == "TestRoot");
    xmlReader.readNextStartElement();
    QVERIFY(xmlReader.name().toString() == "Fixture");

    bool manufacturer = false, model = false, mode = false, name = false,
                                       channels = false, universe = false, address = false, id = false;

    while (xmlReader.readNextStartElement())
    {
        if (xmlReader.name() == "Manufacturer")
        {
            QVERIFY(xmlReader.readElementText() == "Martin");
            manufacturer = true;
        }
        else if (xmlReader.name() == "Model")
        {
            QVERIFY(xmlReader.readElementText() == "MAC250+");
            model = true;
        }
        else if (xmlReader.name() == "Mode")
        {
            QVERIFY(xmlReader.readElementText() == fixtureMode->name());
            mode = true;
        }
        else if (xmlReader.name() == "ID")
        {
            QVERIFY(xmlReader.readElementText() == "1337");
            id = true;
        }
        else if (xmlReader.name() == "Name")
        {
            QVERIFY(xmlReader.readElementText() == "Test Fixture");
            name = true;
        }
        else if (xmlReader.name() == "Universe")
        {
            QVERIFY(xmlReader.readElementText() == "2");
            universe = true;
        }
        else if (xmlReader.name() == "Address")
        {
            QVERIFY(xmlReader.readElementText() == "438");
            address = true;
        }
        else if (xmlReader.name() == "Channels")
        {
            QVERIFY(xmlReader.readElementText().toInt()
                    == fixtureMode->channels().count());
            channels = true;
        }
        else
        {
            QFAIL(QString("Unexpected tag: %1").arg(xmlReader.name().toString())
                  .toLatin1());
            xmlReader.skipCurrentElement();
        }
    }

    QVERIFY(manufacturer == true);
    QVERIFY(model == true);
    QVERIFY(mode == true);
    QVERIFY(id == true);
    QVERIFY(name == true);
    QVERIFY(universe == true);
    QVERIFY(address == true);
    QVERIFY(channels == true);
}
Example #11
0
File: efx.cpp Project: speakman/qlc
/**
 * Prepare this function for running. This is called when
 * the user sets the mode to Operate. Basically allocates everything
 * that is needed to run the function.
 */
void EFX::arm()
{
	class Scene* startScene = NULL;
	class Scene* stopScene = NULL;
	QLCFixtureMode* mode = NULL;
	QLCChannel* ch = NULL;
	t_fixture_id fxi_id = KNoID;
	Fixture* fxi = NULL;
	int channels = 0;
	int order = 0;

	m_channels = 0;

	/* Initialization scene */
	if (m_startSceneID != KNoID && m_startSceneEnabled == true)
	{
		startScene = static_cast <class Scene*>
			(_app->doc()->function(m_startSceneID));
		Q_ASSERT(startScene != NULL);
	}

	/* De-initialization scene */
	if (m_stopSceneID != KNoID && m_stopSceneEnabled == true)
	{
		stopScene = static_cast <class Scene*>
			(_app->doc()->function(m_stopSceneID));
		Q_ASSERT(stopScene != NULL);
	}

	QListIterator <t_function_id> it(m_fixtures);
	while (it.hasNext() == true)
	{
		fxi_id = it.next();
		Q_ASSERT(fxi_id != KNoID);

		EFXFixture ef(this, fxi_id, m_channels, order, m_direction,
			      startScene, stopScene);

		fxi = _app->doc()->fixture(fxi_id);
		Q_ASSERT(fxi != NULL);

		mode = fxi->fixtureMode();
		Q_ASSERT(mode != NULL);

		channels = 0;

		for (t_channel i = 0; i < mode->channels(); i++)
		{
			ch = mode->channel(i);
			Q_ASSERT(ch != NULL);

			if (ch->group() == KQLCChannelGroupPan)
			{
				if (ch->controlByte() == 0)
				{
					ef.setMsbPanChannel(
						fxi->universeAddress() + i);
					channels++;
				}
				else if (ch->controlByte() == 1)
				{
					ef.setLsbPanChannel(
						fxi->universeAddress() + i);
					channels++;
				}
			}
			else if (ch->group() == KQLCChannelGroupTilt)
			{
				if (ch->controlByte() == 0)
				{
					ef.setMsbTiltChannel(
						fxi->universeAddress() + i);
					channels++;
				}
				else if (ch->controlByte() == 1)
				{
					ef.setLsbTiltChannel(
						fxi->universeAddress() + i);
					channels++;
				}
			}
		}

		/* The fixture must have at least an LSB channel for 8bit
		   precision to get accepted into the EFX */
		if (ef.isValid() == true)
		{
			ef.updateSkipThreshold();
			m_runTimeData.append(ef);
			m_channels += channels;
			order++;
		}
	}

	/* Allocate space for channel data that is set to the eventbuffer */
	if (m_channelData == NULL)
		m_channelData = new unsigned int[m_channels];

	/* Allocate space for the event buffer, 1/2 seconds worth of events */
	if (m_eventBuffer == NULL)
		m_eventBuffer = new EventBuffer(m_channels, KFrequency >> 1);

	/* Choose a point calculation function depending on the algorithm */
	if (m_algorithm == KCircleAlgorithmName)
		pointFunc = circlePoint;
	else if (m_algorithm == KEightAlgorithmName)
		pointFunc = eightPoint;
	else if (m_algorithm == KLineAlgorithmName)
		pointFunc = linePoint;
	else if (m_algorithm == KTriangleAlgorithmName)
		pointFunc = trianglePoint;
	else if (m_algorithm == KDiamondAlgorithmName)
		pointFunc = diamondPoint;
	else if (m_algorithm == KLissajousAlgorithmName)
		pointFunc = lissajousPoint;
	else
		pointFunc = NULL;
}
Example #12
0
void Fixture_Test::save()
{
    QLCFixtureDef* fixtureDef;
    fixtureDef = m_doc->fixtureDefCache()->fixtureDef("Martin", "MAC250+");
    Q_ASSERT(fixtureDef != NULL);

    QLCFixtureMode* fixtureMode;
    fixtureMode = fixtureDef->modes().at(0);
    Q_ASSERT(fixtureMode != NULL);

    Fixture fxi(this);
    fxi.setID(1337);
    fxi.setName("Test Fixture");
    fxi.setUniverse(2);
    fxi.setAddress(438);
    fxi.setFixtureDefinition(fixtureDef, fixtureMode);

    QDomDocument doc;
    QDomElement root = doc.createElement("TestRoot");
    QVERIFY(fxi.saveXML(&doc, &root) == true);
    QDomNode node = root.firstChild();
    QVERIFY(node.toElement().tagName() == "Fixture");

    bool manufacturer = false, model = false, mode = false, name = false,
                                       channels = false, universe = false, address = false, id = false;

    node = node.firstChild();
    while (node.isNull() == false)
    {
        QDomElement e = node.toElement();

        if (e.tagName() == "Manufacturer")
        {
            QVERIFY(e.text() == "Martin");
            manufacturer = true;
        }
        else if (e.tagName() == "Model")
        {
            QVERIFY(e.text() == "MAC250+");
            model = true;
        }
        else if (e.tagName() == "Mode")
        {
            QVERIFY(e.text() == fixtureMode->name());
            mode = true;
        }
        else if (e.tagName() == "ID")
        {
            QVERIFY(e.text() == "1337");
            id = true;
        }
        else if (e.tagName() == "Name")
        {
            QVERIFY(e.text() == "Test Fixture");
            name = true;
        }
        else if (e.tagName() == "Universe")
        {
            QVERIFY(e.text() == "2");
            universe = true;
        }
        else if (e.tagName() == "Address")
        {
            QVERIFY(e.text() == "438");
            address = true;
        }
        else if (e.tagName() == "Channels")
        {
            QVERIFY(e.text().toInt()
                    == fixtureMode->channels().count());
            channels = true;
        }
        else
        {
            QFAIL(QString("Unexpected tag: %1").arg(e.tagName())
                  .toLatin1());
        }

        node = node.nextSibling();
    }

    QVERIFY(manufacturer == true);
    QVERIFY(model == true);
    QVERIFY(mode == true);
    QVERIFY(id == true);
    QVERIFY(name == true);
    QVERIFY(universe == true);
    QVERIFY(address == true);
    QVERIFY(channels == true);
}
Example #13
0
void Fixture_Test::fixtureDef()
{
    Fixture fxi(this);

    QVERIFY(fxi.fixtureDef() == NULL);
    QVERIFY(fxi.fixtureMode() == NULL);
    QVERIFY(fxi.channels() == 0);
    QVERIFY(fxi.channel(0) == NULL);
    QCOMPARE(fxi.panMsbChannel(), QLCChannel::invalid());
    QCOMPARE(fxi.tiltMsbChannel(), QLCChannel::invalid());
    QCOMPARE(fxi.panLsbChannel(), QLCChannel::invalid());
    QCOMPARE(fxi.tiltLsbChannel(), QLCChannel::invalid());
    QCOMPARE(fxi.masterIntensityChannel(), QLCChannel::invalid());

    QLCFixtureDef* fixtureDef;
    fixtureDef = m_doc->fixtureDefCache()->fixtureDef("Martin", "MAC300");
    Q_ASSERT(fixtureDef != NULL);

    fxi.setFixtureDefinition(fixtureDef, NULL);
    QVERIFY(fxi.fixtureDef() == NULL);
    QVERIFY(fxi.fixtureMode() == NULL);

    QLCFixtureMode* fixtureMode;
    fixtureMode = fixtureDef->modes().last();
    Q_ASSERT(fixtureMode != NULL);

    fxi.setFixtureDefinition(NULL, fixtureMode);
    QVERIFY(fxi.fixtureDef() == NULL);
    QVERIFY(fxi.fixtureMode() == NULL);

    fxi.setFixtureDefinition(fixtureDef, fixtureMode);
    QVERIFY(fxi.fixtureDef() != NULL);
    QVERIFY(fxi.fixtureMode() != NULL);
    QVERIFY(fxi.fixtureDef() == fixtureDef);
    QVERIFY(fxi.fixtureMode() == fixtureMode);

    QVERIFY(fxi.channels() == quint32(fixtureMode->channels().count()));
    QVERIFY(fxi.channel(fxi.channels() - 1) != NULL);
    QVERIFY(fxi.channel(fxi.channels()) == NULL);

    QVERIFY(fxi.channel("Pan") != QLCChannel::invalid());
    const QLCChannel* ch = fxi.channel(fxi.channel("Pan"));
    QVERIFY(ch != NULL);
    QVERIFY(ch->name().toLower() == "pan");

    ch = fxi.channel(fxi.channel("Pan", Qt::CaseInsensitive, QLCChannel::Colour));
    QVERIFY(ch == NULL);

    QVERIFY(fxi.channel("fect") != QLCChannel::invalid());
    ch = fxi.channel(fxi.channel("fect"));
    QVERIFY(ch != NULL);
    QCOMPARE(ch->name(), QString("Effect speed"));

    QCOMPARE(fxi.panMsbChannel(), quint32(7));
    QCOMPARE(fxi.tiltMsbChannel(), quint32(9));
    QCOMPARE(fxi.panLsbChannel(), quint32(8));
    QCOMPARE(fxi.tiltLsbChannel(), quint32(10));
    QCOMPARE(fxi.masterIntensityChannel(), quint32(1));
    QCOMPARE(fxi.rgbChannels(), QList <quint32> ());
    QCOMPARE(fxi.cmyChannels(), QList <quint32> () << 2 << 3 << 4);
}