Example #1
0
static QList<int> reindexList(const GlobalConfig *config, Phonon::Category category, QList<int>newOrder, bool output)
{
    Q_ASSERT(config);
#ifdef QT_NO_PHONON_AUDIOCAPTURE
    Q_ASSERT(output);
#endif

    /*QString sb;
    sb = QString("(Size %1)").arg(currentList.size());
    foreach (int i, currentList)
    sb += QString("%1, ").arg(i);
    fprintf(stderr, "=== Reindex Current: %s\n", sb.toUtf8().constData());
    sb = QString("(Size %1)").arg(newOrder.size());
    foreach (int i, newOrder)
    sb += QString("%1, ").arg(i);
    fprintf(stderr, "=== Reindex Before : %s\n", sb.toUtf8().constData());*/

    QList<int> currentList;
    if (output)
        currentList = config->audioOutputDeviceListFor(category, GlobalConfig::ShowUnavailableDevices|GlobalConfig::ShowAdvancedDevices);
#ifndef QT_NO_PHONON_AUDIOCAPTURE
    else
        currentList = config->audioCaptureDeviceListFor(category, GlobalConfig::ShowUnavailableDevices|GlobalConfig::ShowAdvancedDevices);
#endif

    QList<int> newList;

    foreach (int i, newOrder) {
        int found = currentList.indexOf(i);
        if (found < 0) {
            // It's not in the list, so something is odd (e.g. client error). Ignore it.
            continue;
        }

        // Iterate through the list from this point onward. If there are hidden devices
        // immediately following, take them too.
        newList.append(currentList.takeAt(found));
        while (found < currentList.size()) {
            bool hidden = true;
            if (output)
                hidden = isHiddenAudioOutputDevice(config, currentList.at(found));
#ifndef QT_NO_PHONON_AUDIOCAPTURE
            else
                hidden = isHiddenAudioCaptureDevice(config, currentList.at(found));
#endif

            if (!hidden)
                break;
            newList.append(currentList.takeAt(found));
        }
    }
Example #2
0
static void qt_qdnsmailexchangerecord_sort(QList<QDnsMailExchangeRecord> &records)
{
    // If we have no more than one result, we are done.
    if (records.size() <= 1)
        return;

    // Order the records by preference.
    std::sort(records.begin(), records.end(), qt_qdnsmailexchangerecord_less_than);

    int i = 0;
    while (i < records.size()) {

        // Determine the slice of records with the current preference.
        QList<QDnsMailExchangeRecord> slice;
        const quint16 slicePreference = records.at(i).preference();
        for (int j = i; j < records.size(); ++j) {
            if (records.at(j).preference() != slicePreference)
                break;
            slice << records.at(j);
        }

        // Randomize the slice of records.
        while (!slice.isEmpty()) {
            const unsigned int pos = QRandomGenerator::global()->bounded(slice.size());
            records[i++] = slice.takeAt(pos);
        }
    }
}
Example #3
0
void reorderGridLayout(QGridLayout* layout, int maxCols)
{
	QList<QLayoutItem*> items;
	for (int i = 0; i < layout->rowCount(); i++) {
		for (int j = 0; j < layout->columnCount(); j++) {
			QLayoutItem* item = layout->itemAtPosition(i, j);
			if (item) {
				layout->removeItem(item);
				if (item->isEmpty()) {
					delete item;
				}
				else {
					items.append(item);
				}
			}
		}
	}
	int col = 0, row = 0;
	while (!items.isEmpty()) {
		QLayoutItem* item = items.takeAt(0);
		layout->addItem(item, row, col);
		col++;
		if (col >= maxCols) {
			col = 0;
			row++;
		}
	}
}
Example #4
0
void Preferences::updateDroppedUserLayouts(int newRow, int oldRow)
{
  int userLayoutIndex = this->m_Data[UserLayoutIndex].toInt();
  QList<QVariant> userLayouts = this->m_Data[UserLayouts].toList();
  QVariant name = userLayouts.takeAt(oldRow*2);
  QVariant data = userLayouts.takeAt(oldRow*2);
  userLayouts.insert(newRow*2, data);
  userLayouts.insert(newRow*2, name);
  
  if (userLayoutIndex != -1)
  {
    if (userLayoutIndex == oldRow)
      userLayoutIndex = newRow;
    else
    {
      if ((newRow > oldRow) && (oldRow < userLayoutIndex))
        userLayoutIndex -= 1;
      else if ((newRow < oldRow) && (newRow < userLayoutIndex))
        userLayoutIndex += 1;
    }
  }
  
  this->m_Data[UserLayoutIndex] = userLayoutIndex;
  this->m_Data[UserLayouts] = userLayouts;
};
//called during the validation of the client certificate.
void OwncloudSetupPage::slotCertificateAccepted()
{
    QSslCertificate sslCertificate;

    resultP12ToPem certif = p12ToPem(addCertDial->getCertificatePath().toStdString() , addCertDial->getCertificatePasswd().toStdString());
    if(certif.ReturnCode){
        QString s = QString::fromStdString(certif.Certificate);
        QByteArray ba = s.toLocal8Bit();

        QList<QSslCertificate> sslCertificateList = QSslCertificate::fromData(ba, QSsl::Pem);
        sslCertificate = sslCertificateList.takeAt(0);

        _ocWizard->ownCloudCertificate = ba;
        _ocWizard->ownCloudPrivateKey = certif.PrivateKey.c_str();
        _ocWizard->ownCloudCertificatePath = addCertDial->getCertificatePath();
        _ocWizard->ownCloudCertificatePasswd = addCertDial->getCertificatePasswd();

        AccountPtr acc = _ocWizard->account();
        acc->setCertificate(_ocWizard->ownCloudCertificate, _ocWizard->ownCloudPrivateKey);
        addCertDial->reinit();
        validatePage();
    } else {
        QString message;
        message = certif.Comment.c_str();
        addCertDial->showErrorMessage(message);
        addCertDial->show();
    }
}
    foreach( const QString &key, keys )
    {
        // --- commit the albums as compilation or normal album

        QList<CollectionScanner::Album*> albums = m_albumNames.values( key );
        // debug() << "commit got" <<albums.count() << "x" << key;

        // if we have multiple albums with the same name, check if it
        // might be a compilation

        for( int i = albums.count() - 1; i >= 0; --i )
        {
            CollectionScanner::Album *album = albums.at( i );
            // commit all albums with a track with the noCompilation flag
            if( album->isNoCompilation() ||
                    nonCompilationAlbumNames.contains( album->name(), Qt::CaseInsensitive ) )
                commitAlbum( albums.takeAt( i ) );
        }

        // only one album left. It's no compilation.
        if( albums.count() == 1 )
        {
            commitAlbum( albums.takeFirst() );
        }

        // compilation
        else if( albums.count() > 1 )
        {
            CollectionScanner::Album compilation( key, QString() );
            for( int i = albums.count() - 1; i >= 0; --i )
            {
                CollectionScanner::Album *album = albums.takeAt( i );
                foreach( CollectionScanner::Track *track, album->tracks() )
                    compilation.addTrack( track );
                compilation.setCovers( album->covers() + compilation.covers() );
            }
            commitAlbum( &compilation );
        }

        // --- unblock every 5 second. Maybe not really needed, but still nice
        if( blockedTime.secsTo( QDateTime::currentDateTime() ) >= 5 )
        {
            unblockUpdates();
            blockedTime = QDateTime::currentDateTime();
            blockUpdates();
        }
    }
Example #7
0
void SearchDialog::toggleItems(bool enabled)
{
	QCheckBox *checkBox = qobject_cast<QCheckBox*>(sender());
	for (QListView *list : this->findChildren<QListView*>()) {
		QStandardItemModel *m = qobject_cast<QStandardItemModel*>(list->model());
		// Hiding / restoring items has to be done in 2-steps
		// First step is for finding items that are about to be moved
		// Second step is for iterating backward on marked items -> you cannot remove items on a single for loop
		if (enabled) {
			// Restore hidden items for every list
			QList<QStandardItem*> items = _hiddenItems.value(list);
			QList<int> indexes;
			for (int i = 0; i < items.size(); i++) {
				QStandardItem *item = items.at(i);
				// Extract only matching items
				if (item->data(AbstractSearchDialog::DT_Origin) == checkBox->text()) {
					indexes.prepend(i);
				}
			}

			// Moving back from hidden to visible
			for (int i = 0; i < indexes.size(); i++) {
				QStandardItem *item = items.takeAt(indexes.at(i));
				m->appendRow(item);
			}

			// Replace existing values with potentially empty list
			_hiddenItems.insert(list, items);
			m->sort(0);
		} else {
			// Hide items for every list
			QStandardItemModel *m = qobject_cast<QStandardItemModel*>(list->model());
			QList<QStandardItem*> items;
			QList<QPersistentModelIndex> indexes;
			for (int i = 0; i < m->rowCount(); i++) {
				QStandardItem *item = m->item(i, 0);
				if (item->data(AbstractSearchDialog::DT_Origin).toString() == checkBox->text()) {
					indexes << m->index(i, 0);
					// Default copy-constructor is protected!
					QStandardItem *copy = new QStandardItem(item->text());
					copy->setData(checkBox->text(), AbstractSearchDialog::DT_Origin);
					copy->setIcon(item->icon());
					items.append(copy);
				}
			}

			for (const QPersistentModelIndex &i : indexes) {
				m->removeRow(i.row());
			}

			// Finally, hide selected items
			if (!items.isEmpty()) {
				QList<QStandardItem*> hItems = _hiddenItems.value(list);
				hItems.append(items);
				_hiddenItems.insert(list, hItems);
			}
		}
	}
}
 ~QGLSgImageTextureCleanup()
 {
     QList<qint64> keys = m_cache.keys();
     while(keys.size() > 0) {
         QGLPixmapData *data = m_cache.take(keys.takeAt(0));
         if (data)
             data->destroyTexture();
     }
 }
Example #9
0
void ToolBar::randomize()
{
    QList<QAction *> randomized;
    QList<QAction *> actions = this->actions();
    while (!actions.isEmpty()) {
        QAction *action = actions.takeAt(rand() % actions.size());
        randomized.append(action);
    }
    clear();
    addActions(randomized);

    orderAction->setEnabled(true);
}
Example #10
0
QColor MoodLampManager::generateColor()
{
    static QList<QColor> unselectedColors;

    if (unselectedColors.empty())
    {
        for (int i = 0; i < ColorsMoodLampCount; i++)
            unselectedColors << m_colorsMoodLamp[i];
    }

    int randIndex = PrismatikMath::rand(unselectedColors.size());

    return unselectedColors.takeAt(randIndex);
}
Example #11
0
static void qt_qdnsservicerecord_sort(QList<QDnsServiceRecord> &records)
{
    // If we have no more than one result, we are done.
    if (records.size() <= 1)
        return;

    // Order the records by priority, and for records with an equal
    // priority, put records with a zero weight first.
    std::sort(records.begin(), records.end(), qt_qdnsservicerecord_less_than);

    int i = 0;
    while (i < records.size()) {

        // Determine the slice of records with the current priority.
        QList<QDnsServiceRecord> slice;
        const quint16 slicePriority = records.at(i).priority();
        unsigned int sliceWeight = 0;
        for (int j = i; j < records.size(); ++j) {
            if (records.at(j).priority() != slicePriority)
                break;
            sliceWeight += records.at(j).weight();
            slice << records.at(j);
        }
#ifdef QDNSLOOKUP_DEBUG
        qDebug("qt_qdnsservicerecord_sort() : priority %i (size: %i, total weight: %i)",
               slicePriority, slice.size(), sliceWeight);
#endif

        // Order the slice of records.
        while (!slice.isEmpty()) {
            const unsigned int weightThreshold = QRandomGenerator::global()->bounded(sliceWeight + 1);
            unsigned int summedWeight = 0;
            for (int j = 0; j < slice.size(); ++j) {
                summedWeight += slice.at(j).weight();
                if (summedWeight >= weightThreshold) {
#ifdef QDNSLOOKUP_DEBUG
                    qDebug("qt_qdnsservicerecord_sort() : adding %s %i (weight: %i)",
                           qPrintable(slice.at(j).target()), slice.at(j).port(),
                           slice.at(j).weight());
#endif
                    // Adjust the slice weight and take the current record.
                    sliceWeight -= slice.at(j).weight();
                    records[i++] = slice.takeAt(j);
                    break;
                }
            }
        }
    }
}
Example #12
0
/** Maps to what groups the source row belongs by returning the data of those groups.
  *
  * @returns a list of data for the rows the argument belongs to. In common cases this list will
  * contain only one entry. An empty list means that the source item will be placed in the root of
  * this proxyModel. There is no support for hiding source items.
  *
  * Group data can be pre-loaded in the return value so it's added to the cache maintained by this
  * class. This is required if you want to have data that is not present in the source model.
  */
QList<RowData>
QtGroupingProxy::belongsTo( const QModelIndex &idx )
{
    //qDebug() << __FILE__ << __FUNCTION__;
    QList<RowData> rowDataList;

    //get all the data for this index from the model
    ItemData itemData = sourceModel()->itemData( idx );
    QMapIterator<int, QVariant> i( itemData );
    while( i.hasNext() )
    {
        i.next();
        int role = i.key();
        QVariant variant = i.value();
        // qDebug() << "role " << role << " : (" << variant.typeName() << ") : "<< variant;
        if( variant.type() == QVariant::List )
        {
            //a list of variants get's expanded to multiple rows
            QVariantList list = variant.toList();
            for( int i = 0; i < list.length(); i++ )
            {
                //take an existing row data or create a new one
                RowData rowData = (rowDataList.count() > i) ?  rowDataList.takeAt( i )
                                       : RowData();

                //we only gather data for the first column
                ItemData indexData = rowData.contains( 0 ) ? rowData.take( 0 ) : ItemData();
                indexData.insert( role, list.value( i ) );
                rowData.insert( 0, indexData );
                //for the grouped column the data should not be gathered from the children
                //this will allow filtering on the content of this column with a
                //QSortFilterProxyModel
                rowData.insert( m_groupedColumn, indexData );
                rowDataList.insert( i, rowData );
            }
        }
        else if( !variant.isNull() )
        {
            //it's just a normal item. Copy all the data and break this loop.
            RowData rowData;
            rowData.insert( 0, itemData );
            rowDataList << rowData;
            break;
        }
    }

    return rowDataList;
}
Example #13
0
bool GUITestLauncher::initGUITestBase() {
    UGUITestBase* b = AppContext::getGUITestBase();
    SAFE_POINT(NULL != b, "Test base is NULL", false);
    QString label = qgetenv("UGENE_GUI_TEST_LABEL");
    QList<HI::GUITest *> list = b->getTests(UGUITestBase::Normal, label);
    if (list.isEmpty()) {
        setError(tr("No tests to run"));
        return false;
    }

    QList<QList<HI::GUITest *> > suiteList;
    if(suiteNumber){
        for(int i=0; i<(list.length()/NUMBER_OF_TESTS_IN_SUITE + 1);i++){
            suiteList << list.mid(i*NUMBER_OF_TESTS_IN_SUITE,NUMBER_OF_TESTS_IN_SUITE);
        }
        if(suiteNumber<0 || suiteNumber>suiteList.size()){
            setError(tr("Invalid suite number: %1. There are %2 suites").arg(suiteNumber).arg(suiteList.size()));
            return false;
        }
        tests = suiteList.takeAt(suiteNumber - 1);
    }else if(!pathToSuite.isEmpty()){
        QString absPath = QDir().absoluteFilePath(pathToSuite);
        QFile suite(absPath);
        SAFE_POINT(suite.exists(), "file " + absPath + " does not exists", false);
        if(suite.open(QFile::ReadOnly)){
            char buf[1024];
            while(suite.readLine(buf, sizeof(buf)) != -1){
                QString testName(buf);
                testName.remove('\n');
                testName.remove('\t');
                testName.remove(' ');
                bool added = false;
                foreach (HI::GUITest* t, list) {
                    if((t->getFullName()) == testName){
                        tests<<t;
                        added = true;
                        break;
                    }
                }
                SAFE_POINT(added, "test " + testName + " not found", false)
            }
        }else{
Example #14
0
QList<data_curs> get_curs_curency()
{
    QList<data_curs> lRet;

    data_curs data;

    QSqlQuery query(QSqlDatabase::database(data_u.NameDBc));
    query.prepare("select * from currency where 1");
    query.exec();
    while (query.next())
    {
        data.name_curency = query.value(0).toString();
        data.curs = query.value(1).toDouble();
        data.b_main = false;
        lRet.append(data);
    }

    query.prepare("select * from primary_currency where 1");
    query.exec();
    QString s;
    while (query.next())
    {
        s = query.value(0).toString();
    }

    for (int i = 0; i < lRet.size(); ++i)
    {
        data = lRet.takeAt(i);

        if(data.name_curency == s)
        {
            data.b_main = true;
		    lRet.insert(0,data);
		    break;
		}
    }

    return lRet;
}
Example #15
0
bool XmppUriQueries::openXmppUri(const Jid &AStreamJid, const QUrl &AUrl) const
{
	if (AUrl.isValid() && AUrl.scheme()=="xmpp")
	{
		QUrl url =  QUrl::fromEncoded(AUrl.toEncoded().replace(';','&'), QUrl::StrictMode);
		Jid contactJid = url.path();
		QList< QPair<QString, QString> > keyValues = url.queryItems();
		if (keyValues.count() > 0)
		{
			QString action = keyValues.takeAt(0).first;
			if (contactJid.isValid() && !action.isEmpty())
			{
				QMultiMap<QString, QString> params;
				for (int i=0; i<keyValues.count(); i++)
					params.insertMulti(keyValues.at(i).first, keyValues.at(i).second);

				LOG_STRM_INFO(AStreamJid,QString("Opening XMPP URI, url=%1").arg(AUrl.toString()));
				foreach (IXmppUriHandler *handler, FHandlers)
				{
					if (handler->xmppUriOpen(AStreamJid, contactJid, action, params))
						return true;
				}
			}
bool QToolBarAreaLayout::restoreState(QDataStream &stream, const QList<QToolBar*> &_toolBars, uchar tmarker, bool testing)
{
    QList<QToolBar*> toolBars = _toolBars;
    int lines;
    stream >> lines;

    for (int j = 0; j < lines; ++j) {
        int pos;
        stream >> pos;
        if (pos < 0 || pos >= QInternal::DockCount)
            return false;
        int cnt;
        stream >> cnt;

        QToolBarAreaLayoutInfo &dock = docks[pos];
        const bool applyingLayout = !testing;
        QToolBarAreaLayoutLine line(dock.o);

        for (int k = 0; k < cnt; ++k) {
            QToolBarAreaLayoutItem item;

            QString objectName;
            stream >> objectName;
            uchar shown;
            stream >> shown;
            item.pos = getInt(stream);
            item.size = getInt(stream);

            /*
               4.3.0 added floating toolbars, but failed to add the ability to restore them.
               We need to store there geometry (four ints). We cannot change the format in a
               patch release (4.3.1) by adding ToolBarStateMarkerEx2 to signal extra data. So
               for now we'll pack it in the two legacy ints we no longer used in Qt4.3.0.
               In 4.4, we should add ToolBarStateMarkerEx2 and fix this properly.
            */

            QRect rect;
            bool floating = false;
            uint geom0, geom1;
            geom0 = getInt(stream);
            if (tmarker == ToolBarStateMarkerEx) {
                geom1 = getInt(stream);
                rect = unpackRect(geom0, geom1, &floating);
            }

            QToolBar *toolBar = 0;
            for (int x = 0; x < toolBars.count(); ++x) {
                if (toolBars.at(x)->objectName() == objectName) {
                    toolBar = toolBars.takeAt(x);
                    break;
                }
            }
            if (toolBar == 0) {
                continue;
            }

            if (applyingLayout) {
                item.widgetItem = new QWidgetItemV2(toolBar);
                toolBar->setOrientation(floating ? ((shown & 2) ? Qt::Vertical : Qt::Horizontal) : dock.o);
                toolBar->setVisible(shown & 1);
                toolBar->d_func()->setWindowState(floating, true, rect);

                item.preferredSize = item.size;
                line.toolBarItems.append(item);
            }
        }

        if (applyingLayout) {
            dock.lines.append(line);
        }
    }


    return stream.status() == QDataStream::Ok;
}
void MyScene::update()
{
  this->clear();

  QPen linePen;
  linePen.setWidth(2);


  QPen linePenOven;
  linePenOven.setColor(Qt::green);
  linePenOven.setWidth(3);

  // Draw oven temperature history
  if (dotListOven.count() > 2) {
    for (int i=1; i<dotListOven.count(); i++) {
      addLine(((QWidget *)this->parent())->width() * dotListOven.at(i).x() / maxTime,
              ((QWidget *)this->parent())->height() * dotListOven.at(i).y(),
              ((QWidget *)this->parent())->width() * dotListOven.at(i-1).x() / maxTime,
              ((QWidget *)this->parent())->height() * dotListOven.at(i-1).y(),
              linePenOven);
    }
  }

  if (dotList.count() >= 1) {
    // Reorder Dots from left to right

    qDebug() << "Printing unordered list";

    for (int i=0; i<dotList.count(); i++) {
      qDebug() << "[" << dotList.at(i).x() << "," << dotList.at(i).y() << "]";
    }

    for (int i=0; i<dotList.count(); i++) {
      for (int j=0; j<dotList.count()-1; j++) {
        if (dotList.at(j).x() > dotList.at(j+1).x()) {
          dotList.insert(j, dotList.takeAt(j+1));
        }
      }
    }

    qDebug() << "Printing ordered list";

    for (int i=0; i<dotList.count(); i++) {
      qDebug() << "[" << dotList.at(i).x() << "," << dotList.at(i).y() << "]";
    }

    // Normalize dots "x" with the maximum one
    double maxX = dotList.last().x();
    double scale = 1 / maxX;

    for (int i=0; i<dotList.count(); i++) {
      Dot d = dotList.takeFirst();
      d.x(d.x() * scale);
      dotList.append(d);
    }

    qDebug() << "Printing normalized list";

    for (int i=0; i<dotList.count(); i++) {
      qDebug() << "[" << dotList.at(i).x() << "," << dotList.at(i).y() << "]";
    }


    QPen dotPen;
    dotPen.setWidth(2);

    // Draw dots
    for (int i=0; i<dotList.count(); i++) {

      if (dotList.at(i).selected())
        dotPen.setColor(Qt::red);
      else
        dotPen.setColor(Qt::darkGreen);

      int posX = ((QWidget *)this->parent())->width() * dotList.at(i).x();
      int posY = ((QWidget *)this->parent())->height() * dotList.at(i).y();
      addEllipse(posX,
                 posY,
                 10,
                 10,
                 dotPen)->setPos(-5,-5);
      QString txt1, txt2;
      txt1.append(QString::number((int)(dotList.at(i).x() * (double)maxTime)));
      txt1.append(" s, ");
      txt2.append(QString::number((int)((1.0 - dotList.at(i).y()) * (double)maxTemp)));
      txt2.append(" 'C");
      addSimpleText(txt1)->setPos(posX - 30,
                                  posY - 32);
      addSimpleText(txt2)->setPos(posX - 30,
                                  posY - 20);
    }

    // Draw lines
    addLine(((QWidget *)this->parent())->width() * 0,
            ((QWidget *)this->parent())->height() * 1,
            ((QWidget *)this->parent())->width() * dotList.at(0).x(),
            ((QWidget *)this->parent())->height() * dotList.at(0).y(),
            linePen);

    for (int i=1; i<dotList.count(); i++) {
      addLine(((QWidget *)this->parent())->width() * dotList.at(i).x(),
              ((QWidget *)this->parent())->height() * dotList.at(i).y(),
              ((QWidget *)this->parent())->width() * dotList.at(i-1).x(),
              ((QWidget *)this->parent())->height() * dotList.at(i-1).y(),
              linePen);
    }
  } else {

    double val1 = 1.0 - (double)currentTemperature / maxTemp;
    int y = ((QWidget *)this->parent())->height() * val1;

    addLine(0,
            y,
            ((QWidget *)this->parent())->width(),
            y,
            linePen);
  }
}
Example #18
0
bool FileManager::exportToXML( QString path, QList<TrackModel *>* trackModels, const CategoryData* categoryData, ImageData* const imageData, float bpm, float fps )
{
    qDebug() << "bpm:" << bpm;
    qDebug() << "fps:" << fps;

    QString xmlOutput;
    int     imgCount = 0;

    QXmlStreamWriter stream(&xmlOutput);
    stream.setAutoFormatting(true);
    stream.writeStartDocument();

    // Make XML...
    stream.writeDTD("<!DOCTYPE xmeml>");
    stream.writeStartElement("xmeml");
    stream.writeAttribute("version", "4");
    stream.writeStartElement("project");
    stream.writeTextElement("name", "Chakra_Test");
    stream.writeStartElement("children");
    stream.writeStartElement("bin");
    stream.writeTextElement("name", "FROM PRISM");
    stream.writeStartElement("children");
    stream.writeStartElement("bin");
    stream.writeTextElement("name", "STILLS");
    stream.writeStartElement("children");

    // Organize images into category bins
    for ( int i = 0; i < categoryData->categoryList->size(); i++ )
    {
        CategoryModel* catModel = categoryData->categoryList->at(i);

        stream.writeStartElement("bin");
        stream.writeTextElement("name", catModel->name);
        stream.writeStartElement("children");

        // Get category images
        QueryMap query;
        query.insert(CATEGORY, QVariant(catModel->name));
        QList<ImageModel> imageResults = imageData->makeQuery(query);

        // Write clip data
        for ( int j = 0; j < imageResults.size(); j++ )
        {
            ImageModel img = imageResults.at(j);
            QString clipID = "clipitem-" + QString::number(imgCount + 1);

            stream.writeStartElement("clip");
            stream.writeAttribute("id", img.masterID);

            QString uuidString = QUuid::createUuid().toString();
            uuidString.remove(0, 1);
            uuidString.remove(uuidString.length() - 1, 1);
            stream.writeTextElement("uuid", uuidString);

            stream.writeTextElement("masterclipid", img.masterID);
            stream.writeTextElement("ismasterclip", "TRUE");
            stream.writeTextElement("duration", "150");
            stream.writeStartElement("rate");
            stream.writeTextElement("timebase", "30");
            stream.writeTextElement("ntsc", "TRUE");
            stream.writeEndElement(); // rate
            stream.writeTextElement("in", "0");
            stream.writeTextElement("out", "0");
            stream.writeTextElement("name", img.name);
            stream.writeStartElement("media");
            stream.writeStartElement("video");
            stream.writeStartElement("track");
            stream.writeStartElement("clipitem");
            stream.writeAttribute("id", clipID);

            stream.writeTextElement("masterclipid", img.masterID);
            stream.writeTextElement("name", img.name);
            stream.writeTextElement("alphatype", "none");
            stream.writeStartElement("file");
            stream.writeAttribute("id", img.fileID);

            stream.writeTextElement("name", img.name);
            stream.writeTextElement("pathurl", img.path);
            stream.writeStartElement("rate");
            stream.writeTextElement("timebase", "30");
            stream.writeTextElement("ntsc", "TRUE");
            stream.writeEndElement(); // rate

            stream.writeStartElement("timecode");
            stream.writeStartElement("rate");
            stream.writeTextElement("timebase", "30");
            stream.writeTextElement("ntsc", "TRUE");
            stream.writeEndElement(); // rate
            stream.writeTextElement("string", "00;00;00;00");
            stream.writeTextElement("frame", "0");
            stream.writeTextElement("displayformat", "DF");
            stream.writeStartElement("reel");
            stream.writeEmptyElement("name");
            stream.writeEndElement(); // reel
            stream.writeEndElement(); // timecode

            stream.writeStartElement("media");
            stream.writeStartElement("video");
            stream.writeTextElement("duration", "18000");
            stream.writeStartElement("samplecharacteristics");
            stream.writeStartElement("rate");
            stream.writeTextElement("timebase", "30");
            stream.writeTextElement("ntsc", "TRUE");
            stream.writeEndElement(); // rate
            stream.writeTextElement("width", "1024");
            stream.writeTextElement("height", "768");
            stream.writeTextElement("anamorphic", "FALSE");
            stream.writeTextElement("pixelaspectratio", "square");
            stream.writeTextElement("fielddominance", "none");
            stream.writeEndElement(); // samplecharacteristics
            stream.writeEndElement(); // video
            stream.writeEndElement(); // media

            stream.writeEndElement(); // file

            stream.writeStartElement("link");
            stream.writeTextElement("linkclipref", clipID);
            stream.writeTextElement("mediatype", "video");
            stream.writeTextElement("trackindex", "1");
            stream.writeTextElement("clipindex", "1");
            stream.writeEndElement(); // link

            stream.writeEndElement(); // clipitem
            stream.writeEndElement(); // track
            stream.writeEndElement(); // video
            stream.writeEndElement(); // media

            stream.writeStartElement("logginginfo");
            stream.writeEmptyElement("description");
            stream.writeEmptyElement("scene");
            stream.writeEmptyElement("shottake");
            stream.writeEmptyElement("lognote");
            stream.writeEndElement(); // logginginfo

            stream.writeEndElement(); // clip

            imgCount++;
        } // images

        stream.writeEndElement(); // children
        stream.writeEndElement(); // bin - category

    } // categories

    // ...Sequence time!!
    stream.writeStartElement("sequence");
    stream.writeAttribute("id", "sequence-1");

    QString uuidString = QUuid::createUuid().toString();
    uuidString.remove(0, 1);
    uuidString.remove(uuidString.length() - 1, 1);
    stream.writeTextElement("uuid", uuidString);

    // TODO: Put stuff here
    stream.writeTextElement("duration", "150");
    stream.writeStartElement("rate");
    stream.writeTextElement("timebase", QString::number(lroundf(fps)));
    stream.writeTextElement("ntsc", "FALSE");
    stream.writeEndElement(); // rate
    stream.writeTextElement("name", "prism-sequence-1");

    stream.writeStartElement("media");
    stream.writeStartElement("video");

    // Format data
    stream.writeStartElement("format");
    stream.writeStartElement("samplecharacteristics");
    stream.writeStartElement("rate");
    stream.writeTextElement("timebase", QString::number(lroundf(fps)));
    stream.writeTextElement("ntsc", "FALSE");
    stream.writeEndElement(); // rate
    stream.writeTextElement("width", "1920");
    stream.writeTextElement("height", "1080");
    stream.writeTextElement("anamorphic", "FALSE");
    stream.writeTextElement("pixelaspectratio", "square");
    stream.writeTextElement("fielddominance", "none");
    stream.writeTextElement("colordepth", "24");
    stream.writeEndElement(); // samplecharacteristics
    stream.writeEndElement(); // format

    // Set random seed
    qsrand((uint)QTime::currentTime().msec());

    // Insert track data
    for ( int i = 0; i < trackModels->size(); i++ )
    {
        stream.writeStartElement("track");
        stream.writeTextElement("enabled", "TRUE");
        stream.writeTextElement("locked", "FALSE");

        const TrackModel* trackModel = trackModels->at(i);

        // Insert clip data
        for ( int j = 0; j < trackModel->pClips.size(); j++ )
        {
            ClipModel* clipModel        = trackModel->pClips.at(j);
            QList<ImageModel> images    = imageData->makeQuery( clipModel->getImageQuery(), true );
            int invDiv                  = 16 / clipModel->distro16th;

            // One clip for each image
            for ( int k = 0; k < clipModel->length16th / invDiv; k++ )
            {
                // Mark all query images as unused if we've used them up already
                if ( images.size() <= 0 )
                {
                    imageData->setQueryAsUnused( clipModel->getImageQuery() );
                    images = imageData->makeQuery( clipModel->getImageQuery(), true );
                }

                ImageModel imgModel = images.takeAt(qrand() % images.size());
                imageData->setImageUsedState( imgModel, true );

                // Convert 16th notes to frames
                int imgStart16th    = clipModel->starting16th + k * invDiv;
                int imgEnd16th      = imgStart16th + invDiv;
                int imgStartFrame   = ClipModel::getFrameFrom16th(imgStart16th, bpm, fps);
                int imgEndFrame     = ClipModel::getFrameFrom16th(imgEnd16th,   bpm, fps);

                stream.writeStartElement("clipitem");
                stream.writeAttribute("id", "clipitem-" + QString::number(i * 100 + j * 10 + k));
                stream.writeTextElement("masterclipid", imgModel.masterID);
                stream.writeTextElement("name",         imgModel.name);
                stream.writeTextElement("enabled",      "TRUE");
                stream.writeTextElement("duration",     "2589410");
                stream.writeTextElement("start",        QString::number(imgStartFrame));
                stream.writeTextElement("end",          QString::number(imgEndFrame));
                stream.writeTextElement("in",           "0");
                stream.writeTextElement("out",          QString::number(imgEndFrame - imgStartFrame));
                stream.writeTextElement("alphatype",    "none");
                stream.writeEmptyElement("file");
                stream.writeAttribute("id",             imgModel.fileID);
                stream.writeEndElement(); // clipitem
            }
        }

        stream.writeEndElement(); // track
    }

    stream.writeEndElement(); // video

    // Timecode data
    stream.writeStartElement("timecode");
    stream.writeStartElement("rate");
    stream.writeTextElement("timebase", QString::number(lroundf(fps)));
    stream.writeTextElement("ntsc", "FALSE");
    stream.writeEndElement(); // rate
    stream.writeTextElement("string", "00:00:00:00");
    stream.writeTextElement("frame", "0");
    stream.writeTextElement("displayformat", "NDF");
    stream.writeEndElement(); // timecode

    stream.writeEndElement(); // media

    stream.writeEndElement(); // sequence

    stream.writeEndElement(); // children
    stream.writeEndElement(); // bin - STILLS
    stream.writeEndElement(); // children
    stream.writeEndElement(); // bin - FROM PRISM
    stream.writeEndElement(); // children
    stream.writeEndElement(); // project
    stream.writeEndElement(); // xmeml

    stream.writeEndDocument();

    // Prep file
    QFile file;
    file.setFileName( path );

    // Open
    if ( !file.open( QIODevice::WriteOnly | QIODevice::Text ) )
        return false;

    // Write
    int result = file.write( xmlOutput.toLocal8Bit() );
    qDebug() << "...wrote" << result << "bytes to" << path;

    return result != -1;
}