<commit_before>#include "wts_version.h"

#include "Project.h"
#include "Common.h"
#include "SoundBuffer.h"
#include "Rainbow.h"
#include "ScoreSymbol.h"
#include "ScoreEditor.h"

#include "ThumbsSpread.h"

#include <QPainter>
#include <QPrinter>

using namespace WTS;

const float MM_PER_INCH = 0.0393700787;

Project::Project(QObject * parent)
    : QObject(parent)
{
    setup();
}

/* initialization common across constructors */
void Project::setup()
{
    m_duration = 0;
    m_loading = false;
    m_finalTension = 0.5;
    m_videoFile = NULL;
    m_lastSampleNameNum = 0;
    m_msPerPage = 15000;

    // connect to itself...
    connect(this,SIGNAL(saveSection(QXmlStreamWriter&)),
            SLOT(saveSequence(QXmlStreamWriter&)));
    connect(this,SIGNAL(saveSection(QXmlStreamWriter&)),
            SLOT(saveStoryboard(QXmlStreamWriter&)));
    connect(this,SIGNAL(loadSection(QXmlStreamReader&)),
            SLOT(loadSequence(QXmlStreamReader&)));
    connect(this,SIGNAL(loadSection(QXmlStreamReader&)),
            SLOT(loadStoryboard(QXmlStreamReader&)));

}

Project::Project(const QString& path, QObject * parent)
    : QObject(parent)
{
    setup();

    m_videoFile = new VideoFile(path, this);

    QDir movieDir = QFileInfo(path).dir();
    m_dataDir = QDir( movieDir.filePath( QFileInfo(path).completeBaseName()
                + ".data") );
    if (! m_dataDir.exists() )
        movieDir.mkdir( m_dataDir.dirName() );
}

void Project::saveStoryboard(QXmlStreamWriter& xml)
{
    xml.writeStartElement("storyboard");
    xml.writeAttribute("final_tension", QString("%1").arg(m_finalTension));
    foreach(Marker * m, m_markers) {
        xml.writeStartElement("marker");
        QString ms;
        ms.setNum(m->at());
        xml.writeAttribute("ms",ms);
        xml.writeAttribute("type", m->type() == SCENE ? "scene" : "event");
        xml.writeAttribute("tension", QString("%1").arg(m->tension()));
        xml.writeEndElement();
    }
    xml.writeEndElement();
}

bool Project::loadStoryboard(QXmlStreamReader& xml)
{
    if (xml.name() != "storyboard")
        return false;

    m_finalTension = xml.attributes().hasAttribute("final_tension")
        ? xml.attributes().value("final_tension").toString().toFloat()
        : 0.5;

    while(xml.readNextStartElement()) {
        float tension = xml.attributes().hasAttribute("tension")
            ? xml.attributes().value("tension").toString().toFloat()
            : 0.5;

        addMarker(xml.attributes().value("type") == "scene" ? SCENE : EVENT,
                xml.attributes().value("ms").toString().toLongLong(),
                tension);

        // this is one way to read a flat list of <foo/> not recursing
        xml.readElementText();
    }

    emit tensionChanged();
    return true;
}

void Project::saveSequence(QXmlStreamWriter& xml)
{
    xml.writeStartElement("sequence");
    xml.writeAttribute("counter",QString("%1").arg(m_lastSampleNameNum));
    foreach(WtsAudio::BufferAt * buffer, m_sequence) {
        xml.writeStartElement("sample");
        qint64 at_int = buffer->at();
        QString at_s = QString("%1").arg(at_int);
        xml.writeAttribute("ms",at_s);
        xml.writeAttribute("id",buffer->buffer()->name());
        // FIXME: this shouldn't be here, but in a separate samples chunk
        xml.writeAttribute("range_start", QString("%1").arg(buffer->buffer()->rangeStart()));
        xml.writeAttribute("range_end", QString("%1").arg(buffer->buffer()->rangeEnd()));
        xml.writeAttribute("gain", QString("%1").arg( buffer->buffer()->gain() ));
        xml.writeEndElement();

        buffer->buffer()->save( m_dataDir );
    }
    xml.writeEndElement();
}

bool Project::loadSequence(QXmlStreamReader& xml)
{
    if (xml.name() != "sequence")
        return false;

    QRegExp idRe = QRegExp("sample_(\\d+)");
    m_lastSampleNameNum =
        xml.attributes().value("counter").toString().toInt();
    while(xml.readNextStartElement()) {
        QString id = xml.attributes().value("id").toString();

        id.replace(".wav","");

        SoundBuffer * sb = new SoundBuffer( id );
        try {
            sb->load( m_dataDir );
            sb->setRange(xml.attributes().value("range_start").toString().toLongLong(),
                    xml.attributes().value("range_end").toString().toLongLong());

            QString at_s =  xml.attributes().value("ms").toString();
            qint64 at_int = at_s.toLongLong();
            WtsAudio::BufferAt * buffer =
                new WtsAudio::BufferAt(sb,
                        at_int,
                        this);
            m_sequence.append( buffer );

            // find out original number / color
            if (idRe.indexIn(id) > -1) {
                int color_index = idRe.cap(1).toInt();
                buffer->buffer()->setColor( Rainbow::getColor( color_index ) );
            } else {
                qDebug() << "Color index didn't parse...";
            }<commit_msg>save / load sample color<commit_after>#include "wts_version.h"

#include "Project.h"
#include "Common.h"
#include "SoundBuffer.h"
#include "Rainbow.h"
#include "ScoreSymbol.h"
#include "ScoreEditor.h"

#include "ThumbsSpread.h"

#include <QPainter>
#include <QPrinter>

using namespace WTS;

const float MM_PER_INCH = 0.0393700787;

Project::Project(QObject * parent)
    : QObject(parent)
{
    setup();
}

/* initialization common across constructors */
void Project::setup()
{
    m_duration = 0;
    m_loading = false;
    m_finalTension = 0.5;
    m_videoFile = NULL;
    m_lastSampleNameNum = 0;
    m_msPerPage = 15000;

    // connect to itself...
    connect(this,SIGNAL(saveSection(QXmlStreamWriter&)),
            SLOT(saveSequence(QXmlStreamWriter&)));
    connect(this,SIGNAL(saveSection(QXmlStreamWriter&)),
            SLOT(saveStoryboard(QXmlStreamWriter&)));
    connect(this,SIGNAL(loadSection(QXmlStreamReader&)),
            SLOT(loadSequence(QXmlStreamReader&)));
    connect(this,SIGNAL(loadSection(QXmlStreamReader&)),
            SLOT(loadStoryboard(QXmlStreamReader&)));

}

Project::Project(const QString& path, QObject * parent)
    : QObject(parent)
{
    setup();

    m_videoFile = new VideoFile(path, this);

    QDir movieDir = QFileInfo(path).dir();
    m_dataDir = QDir( movieDir.filePath( QFileInfo(path).completeBaseName()
                + ".data") );
    if (! m_dataDir.exists() )
        movieDir.mkdir( m_dataDir.dirName() );
}

void Project::saveStoryboard(QXmlStreamWriter& xml)
{
    xml.writeStartElement("storyboard");
    xml.writeAttribute("final_tension", QString("%1").arg(m_finalTension));
    foreach(Marker * m, m_markers) {
        xml.writeStartElement("marker");
        QString ms;
        ms.setNum(m->at());
        xml.writeAttribute("ms",ms);
        xml.writeAttribute("type", m->type() == SCENE ? "scene" : "event");
        xml.writeAttribute("tension", QString("%1").arg(m->tension()));
        xml.writeEndElement();
    }
    xml.writeEndElement();
}

bool Project::loadStoryboard(QXmlStreamReader& xml)
{
    if (xml.name() != "storyboard")
        return false;

    m_finalTension = xml.attributes().hasAttribute("final_tension")
        ? xml.attributes().value("final_tension").toString().toFloat()
        : 0.5;

    while(xml.readNextStartElement()) {
        float tension = xml.attributes().hasAttribute("tension")
            ? xml.attributes().value("tension").toString().toFloat()
            : 0.5;

        addMarker(xml.attributes().value("type") == "scene" ? SCENE : EVENT,
                xml.attributes().value("ms").toString().toLongLong(),
                tension);

        // this is one way to read a flat list of <foo/> not recursing
        xml.readElementText();
    }

    emit tensionChanged();
    return true;
}

void Project::saveSequence(QXmlStreamWriter& xml)
{
    xml.writeStartElement("sequence");
    xml.writeAttribute("counter",QString("%1").arg(m_lastSampleNameNum));
    foreach(WtsAudio::BufferAt * buffer, m_sequence) {
        xml.writeStartElement("sample");
        qint64 at_int = buffer->at();
        QString at_s = QString("%1").arg(at_int);
        xml.writeAttribute("ms",at_s);
        xml.writeAttribute("id",buffer->buffer()->name());
        // FIXME: this shouldn't be here, but in a separate samples chunk
        xml.writeAttribute("range_start", QString("%1").arg(buffer->buffer()->rangeStart()));
        xml.writeAttribute("range_end", QString("%1").arg(buffer->buffer()->rangeEnd()));
        xml.writeAttribute("gain", QString("%1").arg( buffer->buffer()->gain() ));
        xml.writeAttribute("color", QString("%1").arg(buffer->buffer()->color().name() ));
        xml.writeEndElement();

        buffer->buffer()->save( m_dataDir );
    }
    xml.writeEndElement();
}

bool Project::loadSequence(QXmlStreamReader& xml)
{
    if (xml.name() != "sequence")
        return false;

    QRegExp idRe = QRegExp("sample_(\\d+)");
    m_lastSampleNameNum =
        xml.attributes().value("counter").toString().toInt();
    while(xml.readNextStartElement()) {
        QString id = xml.attributes().value("id").toString();

        id.replace(".wav","");

        SoundBuffer * sb = new SoundBuffer( id );
        try {
            sb->load( m_dataDir );
            sb->setRange(xml.attributes().value("range_start").toString().toLongLong(),
                    xml.attributes().value("range_end").toString().toLongLong());

            QString at_s =  xml.attributes().value("ms").toString();
            qint64 at_int = at_s.toLongLong();
            WtsAudio::BufferAt * buffer =
                new WtsAudio::BufferAt(sb,
                        at_int,
                        this);
            m_sequence.append( buffer );

            // find out original number / color
            if (xml.attributes().hasAttribute("color")) {
                buffer->buffer()->setColor( QColor( xml.attributes().value("color").toString() ) );
            } else if (idRe.indexIn(id) > -1) {
                int color_index = idRe.cap(1).toInt();
                buffer->buffer()->setColor( Rainbow::getColor( color_index ) );
            } else {
                buffer->buffer()->setColor( Rainbow::getColor( rand() ) );
            }
{'fraction_non_alphanumeric': 0.16185819070904645, 'fraction_numerical': 0.007334963325183374, 'mean_word_length': 2.8956190476190478, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 53, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 79}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '44206', 'n_tokens_mistral': 3151, 'n_tokens_neox': 3050, 'n_words': 507}