Beispiel #1
0
void MeshGenerator::fillNeighborStructures()
{
    QList<QSet<int> > vertexElements;
    vertexElements.reserve(nodeList.count());
    for (int i = 0; i < nodeList.count(); i++)
        vertexElements.push_back(QSet<int>());

    for (int i = 0; i < elementList.count(); i++)
        if (elementList[i].isUsed)
            for (int elemNode = 0; elemNode < (elementList[i].isTriangle() ? 3 : 4); elemNode++)
                vertexElements[elementList[i].node[elemNode]].insert(i);

    for (int i = 0; i < edgeList.count(); i++)
    {
        if (edgeList[i].isUsed && edgeList[i].marker != -1)
        {
            QSet<int> neighbours = vertexElements[edgeList[i].node[0]];
            neighbours.intersect(vertexElements[edgeList[i].node[1]]);
            assert((neighbours.size() > 0) && (neighbours.size() <= 2));
            edgeList[i].neighElem[0] = neighbours.values()[0];
            if (neighbours.size() == 2)
                edgeList[i].neighElem[1] = neighbours.values()[1];
        }
    }
}
Beispiel #2
0
Cell* Grid::getSafestCell() const
{
	QSet<Cell*> remainingCells;

	// find the most constrained cells (fewest options in domain)
	int minimumDomainSize = 100;
	for( auto cellIter=cells.begin(); cellIter!=cells.end(); ++cellIter )
	{
		Cell* cell = *cellIter;
		if( cell->value() != Cell::UNKNOWN )
			continue;

		if( cell->domain().size() < minimumDomainSize ){
			minimumDomainSize = cell->domain().size();
			remainingCells.clear();
		}
		if( cell->domain().size() == minimumDomainSize ){
			remainingCells.insert(cell);
		}
	}

	// if there are no cells return null, otherwise return a minimum cell
	if( remainingCells.size() == 0 )
		return nullptr;
	else
		return remainingCells.values()[0];
}
Beispiel #3
0
void IndicatorDataView::initView(const QString& indicator)
{
  if(!mPainter->mIndicator) return;

  mIndicator = indicator;

  // Delete old entries

  // Insert new entries
  QStringList var;
  //mPainter->mData->getVariableNames(var);
  QSet<QString> varList;
  mPainter->mIndicator->getVariableNames(&varList);
  var = varList.values();
  //qDebug() << "IndicatorDataView::initView()" << var << varList.size();

  // Sort the variable list, but place the bardata as block in front
  var.removeAt(var.indexOf("OPEN"));
  var.removeAt(var.indexOf("HIGH"));
  var.removeAt(var.indexOf("LOW"));
  var.removeAt(var.indexOf("CLOSE"));
  var.removeAt(var.indexOf("VOLUME"));
  var.removeAt(var.indexOf("OPINT"));
  var.sort();
  var.prepend("OPINT");
  var.prepend("VOLUME");
  var.prepend("CLOSE");
  var.prepend("LOW");
  var.prepend("HIGH");
  var.prepend("OPEN");
  var.prepend("Date"); // Should not be a variable but is also interesting

  // And now insert entries
  int row = 0;
  QString name;
  QCheckBox* cb;

  mFilterView.setColumnCount(1);
  mFilterView.setRowCount(var.size());

  // Restore saved settings, if some
  QString filterPath;
  filterPath = mRcFile->getPath("FiluHome");
  filterPath.append("IndicatorFilterSettings/");
  SettingsFile sfile(filterPath + mIndicator);

  foreach(name, var)
  {
    cb = new QCheckBox(name);
    if(sfile.getBL(name))
    {
      cb->setCheckState(Qt::Checked);
    }
    else
    {
      cb->setCheckState(Qt::Unchecked);
    }
    connect(cb, SIGNAL(stateChanged(int)), this, SLOT(filterChanged(int)));
    mFilterView.setCellWidget(row++, 0, cb);
  }
Beispiel #4
0
QString PlaylistManager::GetNameForNewPlaylist(const SongList& songs) {
  if (songs.isEmpty()) {
    return tr("Playlist");
  }

  QSet<QString> artists;
  QSet<QString> albums;

  for (const Song& song : songs) {
    artists << (song.artist().isEmpty() ? tr("Unknown") : song.artist());
    albums << (song.album().isEmpty() ? tr("Unknown") : song.album());

    if (artists.size() > 1) {
      break;
    }
  }

  bool various_artists = artists.size() > 1;

  QString result;
  if (various_artists) {
    result = tr("Various artists");
  } else {
    result = artists.values().first();
  }

  if (!various_artists && albums.size() == 1) {
    result += " - " + albums.toList().first();
  }

  return result;
}
Beispiel #5
0
void PlayersListModel::saveSet(const QSet<QString> & set, const QString & suffix)
{
    qDebug("saving set");

    QString fileName = QString("%1/%2_%3.txt").arg(cfgdir->absolutePath(), m_nickname.toLower(), suffix);

    QFile txt(fileName);

    // list empty? => rather have no file for the list than an empty one
    if (set.isEmpty())
    {
        if (txt.exists())
        {
            // try to remove file, if successful we're done here.
            if (txt.remove())
                return;
        }
        else
            // there is no file
            return;
    }

    if(!txt.open(QIODevice::WriteOnly | QIODevice::Truncate))
        return;

    QTextStream stream(&txt);
    stream.setCodec("UTF-8");

    stream << "; this list is used by Hedgewars - do not edit it unless you know what you're doing!" << endl;

    foreach(const QString & nick, set.values())
        stream << nick << endl;

    txt.close();
}
Beispiel #6
0
void MeshOctTree::getRelevantTriangles(QList<Triangle> &list, glm::vec3 pt, glm::vec3 dir){

    QSet<Triangle> tris;

    QList<OctTreeNode*> queue;
    queue.append(m_root);

    while (!queue.isEmpty()){
        OctTreeNode *current = queue.takeFirst();

        if (rayIntersectsCube(pt, dir, current->min, current->max)){
            if (current->children == NULL){
                for (int i = 0; i < current->triangles.size(); i++){
                    tris.insert(current->triangles.at(i));
                }
            } else {
                for (int i = 0; i < 8; i++){
                    queue.append(current->children[i]);
                }
            }
        }
    }

    list = tris.values();
}
Beispiel #7
0
QList<kint> VertexBuffer::mergeVerticesIndices(const QList<kint>& v1, const QList<kint>& v2) const
{
	QSet<kint> set = QSet<kint>::fromList(v1);
	set.unite(QSet<kint>::fromList(v2));

	QList<kint> result = set.values();
	qSort(result);
	return result;
}
static QString optionsToString(int options)
{
    QSet<QString> set;
    if (options & 1)
        set.insert("strict");
    if (options & 2)
        set.insert("werror");
    if (options & 4)
        set.insert("atline");
    if (options & 8)
        set.insert("xml");
    return QStringList(set.values()).join(",");
}
Beispiel #9
0
void QgsValueMapConfigDlg::removeSelectedButtonPushed()
{
  QList<QTableWidgetItem *> list = tableWidget->selectedItems();
  QSet<int> rowsToRemove;
  int removed = 0;
  int i;
  for ( i = 0; i < list.size(); i++ )
  {
    if ( list[i]->column() == 0 )
    {
      int row = list[i]->row();
      if ( !rowsToRemove.contains( row ) )
      {
        rowsToRemove.insert( row );
      }
    }
  }
  for ( i = 0; i < rowsToRemove.values().size(); i++ )
  {
    tableWidget->removeRow( rowsToRemove.values().at( i ) - removed );
    removed++;
  }
}
QList<QString> QgsRuleBasedRendererV2::usedAttributes()
{
  QSet<QString> attrs;
  for ( QList<Rule>::iterator it = mRules.begin(); it != mRules.end(); ++it )
  {
    Rule& rule = *it;
    attrs.unite( rule.needsFields().toSet() );
    if ( rule.symbol() )
    {
      attrs.unite( rule.symbol()->usedAttributes() );
    }
  }
  return attrs.values();
}
void QgsAttributeTypeDialog::removeSelectedButtonPushed()
{
  QList<QTableWidgetItem *> list = tableWidget->selectedItems();
  QList<QTableWidgetItem *>::iterator it = list.begin();
  QSet<int> rowsToRemove;
  int removed = 0;
  int i = 0;
  for ( ; i < list.size(); i++ )
  {
    if ( list[i]->column() == 0 )
    {
      int row = list[i]->row();
      if ( !rowsToRemove.contains( row ) )
      {
        rowsToRemove.insert( row );
      }
    }
  }
  for ( i = 0; i < rowsToRemove.values().size(); i++ )
  {
    tableWidget->removeRow( rowsToRemove.values()[i] - removed );
    removed++;
  }
}
Beispiel #12
0
QString OsmAnd::Utilities::stringifyZoomLevels(const QSet<ZoomLevel>& zoomLevels)
{
    QString result;

    auto sortedZoomLevels = zoomLevels.values();
    std::sort(sortedZoomLevels);
    bool previousCaptured = false;
    ZoomLevel previousZoomLevel = sortedZoomLevels.first();
    bool range = false;
    ZoomLevel rangeStart;
    for (const auto zoomLevel : sortedZoomLevels)
    {
        if (previousCaptured && static_cast<int>(zoomLevel) == static_cast<int>(previousZoomLevel)+1)
        {
            if (!range)
                rangeStart = previousZoomLevel;
            range = true;
            previousZoomLevel = zoomLevel;
            previousCaptured = true;
        }
        else if (range)
        {
            range = false;
            previousZoomLevel = zoomLevel;
            previousCaptured = true;

            result += QString::fromLatin1("%1-%2, %3, ").arg(rangeStart).arg(previousZoomLevel).arg(zoomLevel);
        }
        else
        {
            previousZoomLevel = zoomLevel;
            previousCaptured = true;

            result += QString::fromLatin1("%1, ").arg(zoomLevel);
        }
    }

    // Process last range
    if (range)
        result += QString::fromLatin1("%1-%2, ").arg(rangeStart).arg(sortedZoomLevels.last());

    if (result.length() > 2)
        result.truncate(result.length() - 2);

    return result;
}
void RepositoryProfile::threadFinished()
{
  repositoryContent = lister->getRepoPackageInformations();
  localContent = lister->getLocalPackageInformations();

  // create a list of provided packages for faster access later
  QSet<QString> c;
  foreach ( const QString &arch, repositoryContent.keys() ) {
    foreach ( const QString &name, repositoryContent.value ( arch ).keys() ) {
      c << name;
    }
  }

  repoContent = c.values();

  updatePackagesStatus();
  computeProfileStatus();
  emit ( statusRefreshed() );
}
Beispiel #14
0
void IncludeFileDataProvider::reset()
{
  m_lastSearchedPrefix = QString();
  m_duContext = TopDUContextPointer();
  m_baseUrl = KUrl();
  m_importers.clear();
  
  IDocument* doc = ICore::self()->documentController()->activeDocument();

  if( doc )
  {
    m_baseUrl = doc->url();

    {
      DUChainReadLocker lock( DUChain::lock() );
      m_duContext = TopDUContextPointer( ICore::self()->languageController()->language("C++")->languageSupport()->standardContext( doc->url() )  );

      if( m_allowImporters && m_duContext ) {
        QSet<IndexedString> importers;

        collectImporters( importers, m_duContext.data() );

        m_importers = importers.values();
      }
    }
  }
  
  QList<IncludeItem> allIncludeItems;

  if( m_allowPossibleImports )
    allIncludeItems += CppUtils::allFilesInIncludePath( m_baseUrl, true, QString(), KUrl::List(), false, true, true );

  if( m_allowImports )
    allIncludeItems += getAllIncludedItems( m_duContext );
  
  foreach( const IndexedString &u, m_importers ) {
    IncludeItem i;
    i.isDirectory = false;
    i.name = u.str();
    i.pathNumber = -1; //We mark this as an importer by putting pathNumber to -1
    allIncludeItems << i;
  }
Beispiel #15
0
void VertexBuffer::bindVertices(const QList<kint>& verticesIndices, kbool doCleanList)
{
	QList<kint> vertices;
	if(doCleanList)
	{
		QSet<kint> set = QSet<kint>::fromList(verticesIndices);
		vertices = set.values();
		qSort(vertices);
	}
	else
	{
		vertices = verticesIndices; // No deep copy (implicitly shared classes !).
	}

	for(kint i = 0; i < vertices.size(); i++)
	{
		kint nextIndex = (i + 1) % vertices.size();
		_verticesData[i].nextSharedVertex = vertices.at(nextIndex);
	}
}
Beispiel #16
0
int main()
{
    QSet<QString *> s;
    qDeleteAll(s);
    qDeleteAll(s.begin(), s.end());
    qDeleteAll(s.values()); // warning

    QHash<int, QString *> h;
    qDeleteAll(h);
    qDeleteAll(h.begin(), h.end());
    qDeleteAll(h.values()); // warning

    QMap<int*, QString *> m;
    qDeleteAll(m);
    qDeleteAll(m.begin(), m.end());
    qDeleteAll(m.values()); // warning

    QMultiHash<int, QString *> mh;
    qDeleteAll(mh);
    qDeleteAll(mh.begin(), mh.end());
    qDeleteAll(mh.values()); // warning

    QMultiMap<int, QString *> mm;
    qDeleteAll(mm);
    qDeleteAll(mm.begin(), mm.end());
    qDeleteAll(mm.values()); // warning

    qDeleteAll(values());  // ok

    Foo foo;
    qDeleteAll(foo.values());  // ok
    qDeleteAll(foo.doSomethingWithValues(h.values()));  // ok

    qDeleteAll(m.keys()); // warning
    qDeleteAll(keys()); // ok

    qDeleteAll(h.values(1)); // warning

}
Beispiel #17
0
bool MeshGenerator::writeToHermes()
{
    // edges
    XMLSubdomains::edges_type edges;
    for (int i = 0; i < edgeList.count(); i++)
        if (edgeList[i].isUsed && edgeList[i].marker != -1)
            edges.ed().push_back(XMLSubdomains::ed(edgeList[i].node[0], edgeList[i].node[1],
                    QString::number(edgeList[i].marker).toStdString(), i));

    // curved edges
    XMLMesh::curves_type curves;
    for (int i = 0; i<edgeList.count(); i++)
    {
        if (edgeList[i].marker != -1)
        {
            // curve
            if (Agros2D::scene()->edges->at(edgeList[i].marker)->angle() > 0.0 &&
                    Agros2D::scene()->edges->at(edgeList[i].marker)->isCurvilinear())
            {
                int segments = Agros2D::scene()->edges->at(edgeList[i].marker)->segments();

                // subdivision angle and chord
                double theta = deg2rad(Agros2D::scene()->edges->at(edgeList[i].marker)->angle()) / double(segments);
                double chord = 2 * Agros2D::scene()->edges->at(edgeList[i].marker)->radius() * sin(theta / 2.0);

                // length of short chord
                double chordShort = (nodeList[edgeList[i].node[1]] - nodeList[edgeList[i].node[0]]).magnitude();

                // direction
                Point center = Agros2D::scene()->edges->at(edgeList[i].marker)->center();
                int direction = (((nodeList[edgeList[i].node[0]].x-center.x)*(nodeList[edgeList[i].node[1]].y-center.y) -
                        (nodeList[edgeList[i].node[0]].y-center.y)*(nodeList[edgeList[i].node[1]].x-center.x)) > 0) ? 1 : -1;

                double angle = direction * theta * chordShort / chord;

                curves.arc().push_back(XMLMesh::arc(edgeList[i].node[0], edgeList[i].node[1], rad2deg(angle)));
            }
        }
    }

    // move nodes (arcs)
    for (int i = 0; i<edgeList.count(); i++)
    {
        // assert(edgeList[i].marker >= 0); // markers changed to marker - 1, check...
        if (edgeList[i].marker != -1)
        {
            // curve
            if (Agros2D::scene()->edges->at(edgeList[i].marker)->angle() > 0.0 &&
                    Agros2D::scene()->edges->at(edgeList[i].marker)->isCurvilinear())
            {
                // angle
                Point center = Agros2D::scene()->edges->at(edgeList[i].marker)->center();
                double pointAngle1 = atan2(center.y - nodeList[edgeList[i].node[0]].y,
                        center.x - nodeList[edgeList[i].node[0]].x) - M_PI;

                double pointAngle2 = atan2(center.y - nodeList[edgeList[i].node[1]].y,
                        center.x - nodeList[edgeList[i].node[1]].x) - M_PI;

                nodeList[edgeList[i].node[0]].x = center.x + Agros2D::scene()->edges->at(edgeList[i].marker)->radius() * cos(pointAngle1);
                nodeList[edgeList[i].node[0]].y = center.y + Agros2D::scene()->edges->at(edgeList[i].marker)->radius() * sin(pointAngle1);

                nodeList[edgeList[i].node[1]].x = center.x + Agros2D::scene()->edges->at(edgeList[i].marker)->radius() * cos(pointAngle2);
                nodeList[edgeList[i].node[1]].y = center.y + Agros2D::scene()->edges->at(edgeList[i].marker)->radius() * sin(pointAngle2);
            }
        }
    }

    // vertices
    XMLMesh::vertices_type vertices;
    for (int i = 0; i<nodeList.count(); i++)
        vertices.v().push_back(std::auto_ptr<XMLMesh::v>(new XMLMesh::v(QString::number(nodeList[i].x).toStdString(),
                                                                        QString::number(nodeList[i].y).toStdString(), i)));

    // elements
    XMLSubdomains::elements_type elements;
    for (int i = 0; i<elementList.count(); i++)
        if (elementList[i].isUsed)
            if (elementList[i].isTriangle())
                elements.el().push_back(XMLSubdomains::t_t(elementList[i].node[0], elementList[i].node[1], elementList[i].node[2],
                        QString::number(elementList[i].marker).toStdString(), i));
            else
                elements.el().push_back(XMLSubdomains::q_t(elementList[i].node[0], elementList[i].node[1], elementList[i].node[2],
                        QString::number(elementList[i].marker).toStdString(), i,
                        elementList[i].node[3]));

    // find edge neighbours
    // for each vertex list elements that it belogns to
    QList<QSet<int> > vertexElements;
    vertexElements.reserve(nodeList.count());
    for (int i = 0; i < nodeList.count(); i++)
        vertexElements.push_back(QSet<int>());

    for (int i = 0; i < elementList.count(); i++)
        if (elementList[i].isUsed)
            for(int elemNode = 0; elemNode < (elementList[i].isTriangle() ? 3 : 4); elemNode++)
                vertexElements[elementList[i].node[elemNode]].insert(i);

    for (int i = 0; i < edgeList.count(); i++)
    {
        if (edgeList[i].isUsed && edgeList[i].marker != -1)
        {
            QSet<int> neighbours = vertexElements[edgeList[i].node[0]];
            neighbours.intersect(vertexElements[edgeList[i].node[1]]);
            assert((neighbours.size() > 0) && (neighbours.size() <= 2));
            edgeList[i].neighElem[0] = neighbours.values()[0];
            if(neighbours.size() == 2)
                edgeList[i].neighElem[1] = neighbours.values()[1];
        }
    }

    // subdomains
    XMLSubdomains::subdomains subdomains;

    if (Agros2D::problem()->fieldInfos().isEmpty())
    {
        // one domain
        XMLSubdomains::subdomain subdomain(Agros2D::problem()->fieldInfos().begin().value()->fieldId().toStdString());
        subdomains.subdomain().push_back(subdomain);
    }
    else
    {
        // more subdomains
        foreach (FieldInfo* fieldInfo, Agros2D::problem()->fieldInfos())
        {
            XMLSubdomains::subdomain subdomain(fieldInfo->fieldId().toStdString());
            subdomain.elements().set(XMLSubdomains::subdomain::elements_type());
            subdomain.boundary_edges().set(XMLSubdomains::subdomain::boundary_edges_type());
            subdomain.inner_edges().set(XMLSubdomains::subdomain::inner_edges_type());

            for (int i = 0; i<elementList.count(); i++)
                if (elementList[i].isUsed && (Agros2D::scene()->labels->at(elementList[i].marker)->marker(fieldInfo) != SceneMaterialContainer::getNone(fieldInfo)))
                    subdomain.elements()->i().push_back(i);

            QList<int> unassignedEdges;
            for (int i = 0; i < edgeList.count(); i++)
            {
                if (edgeList[i].isUsed && edgeList[i].marker != -1)
                {
                    int numNeighWithField = 0;
                    for (int neigh_i = 0; neigh_i < 2; neigh_i++)
                    {
                        int neigh = edgeList[i].neighElem[neigh_i];
                        if (neigh != -1)
                        {
                            if (Agros2D::scene()->labels->at(elementList[neigh].marker)->marker(fieldInfo)
                                    != SceneMaterialContainer::getNone(fieldInfo))
                                numNeighWithField++;
                        }
                    }

                    // edge has boundary condition prescribed for this field
                    bool hasFieldBoundaryCondition = (Agros2D::scene()->edges->at(edgeList[i].marker)->hasMarker(fieldInfo)
                                                      && (Agros2D::scene()->edges->at(edgeList[i].marker)->marker(fieldInfo) != SceneBoundaryContainer::getNone(fieldInfo)));

                    if (numNeighWithField == 1)
                    {
                        // edge is on "boundary" of the field, should have boundary condition prescribed

                        if (!hasFieldBoundaryCondition)
                            if (!unassignedEdges.contains(edgeList[i].marker))
                                unassignedEdges.append(edgeList[i].marker);

                        subdomain.boundary_edges()->i().push_back(i);
                    }
                    else if (numNeighWithField == 2)
                    {
                        // todo: we could enforce not to have boundary conditions prescribed inside:
                        // assert(!hasFieldBoundaryCondition);
                        subdomain.inner_edges()->i().push_back(i);
                    }
                }
            }

            // not assigned boundary
            if (unassignedEdges.count() > 0)
            {
                QString list;
                foreach (int index, unassignedEdges)
                    list += QString::number(index) + ", ";

                Agros2D::log()->printError(tr("Mesh generator"), tr("Boundary condition for %1 is not assigned on following edges: %2").arg(fieldInfo->name()).arg(list.left(list.count() - 2)));

                return false;
            }

            subdomains.subdomain().push_back(subdomain);
        }
Beispiel #18
0
/* They look like this:
0,7,"7"
185220,4,"4"
361620,10,"10"
917280,9,"9"
1102500,6,"6"
1984500,1,"1"
2293200,5,"5"
2628360,3,"3"
2937060,9,"9"
3148740,7,"7"
4057200,6,"6"
4886280,2,"2"
5106780,4,"4"
5583060,9,"9"
Start, segment, "segment"
*/
void SegmentController::loadFileQM(QString filename)
{
    _segmentation.m_segments.clear();
    _segmentation.m_segmentIndices.clear();

    QSet<int> segmentIndexSet;
    QSet<QString> segmentStringSet;

    std::ifstream filestream;
    filestream.open(filename.toStdString(), std::ios::in);
    double conversion = 1000. / Dispatch::Singleton()->getEngine()->format().sampleRate();

    if (! filestream.is_open())
        return; // ErrorHandling

    // XXX This assumes the startTimes are strictly increasing and
    // the durations add up.
    std::string line;
    while ( getline (filestream,line) ) {
        Segment seg;

        // Split line at commas
        std::istringstream ss(line);
        std::string token;
        getline(ss, token, ',');

        // Starting time
        int startTime = std::atoi(token.c_str());
        startTime  *= conversion;
        seg.startTime = startTime;

        // Segment "index" -- an integer
        getline(ss, token, ',');
        int index = std::atoi(token.c_str());
        seg.segmentIndex = index;
        segmentIndexSet << index;

        // segment "variant" -- a string
        // (for these files, always the same as the integer)
        getline(ss, token);
        QString variant=QString::fromStdString(token);
        variant.remove(QChar('"'));
        seg.segmentVariant = variant;
        segmentStringSet << variant;

        _segmentation.m_segments << seg;
    }
    filestream.close();


    // Calculate total duration from last segment start & duration
    _segmentation.m_duration =    Dispatch::Singleton()->getEngine()->bufferLengthMS();

    // Calculate durations:

    QList<Segment>::iterator seg = _segmentation.m_segments.begin();
    QList<Segment>::iterator end = _segmentation.m_segments.end();
    for (; seg < (end-1); ++seg) {
        seg->duration = (seg+1)->startTime - seg->startTime;
    }
    seg->duration = _segmentation.m_duration - seg->startTime;

    // Find all indices used by the segmenter.
    // (Presumably, will be all integers from 1-|segmentSet|, but you
    // can never be too careful about these things.)
    _segmentation.m_segmentIndices = segmentIndexSet.values();
    qSort(_segmentation.m_segmentIndices);
    _segmentation.m_nSegments = _segmentation.m_segmentIndices.count();
}
Beispiel #19
0
void SegmentController::loadFile(QString filename)
{
    _segmentation.m_segments.clear();
    _segmentation.m_segmentIndices.clear();

    QSet<int> segmentSet;

    std::ifstream filestream;
    filestream.open(filename.toStdString(), std::ios::in);
    double conversion = 1000. / Dispatch::Singleton()->getEngine()->format().sampleRate();

    if (! filestream.is_open())
        return; // ErrorHandling

    // XXX This assumes the startTimes are strictly increasing and
    // the durations add up.
    std::string line;
    while ( getline (filestream,line) ) {
        Segment seg;

        // Split line at commas
        std::istringstream ss(line);
        std::string token;
        getline(ss, token, ',');

        // Starting time
        int startTime = std::atoi(token.c_str());
        startTime  *= conversion;
        seg.startTime = startTime;

        // Duration
        getline(ss, token, ',');
        int duration = std::atoi(token.c_str());
        duration  *= conversion;
        seg.duration = duration;

        // Segment "index" -- an integer
        getline(ss, token, ',');
        int index = std::atoi(token.c_str());
        seg.segmentIndex = index;
        segmentSet << index;

        // segment "variant" -- a string
        getline(ss, token);
        QString variant=QString::fromStdString(token);
        variant.remove(QChar('"'));
        seg.segmentVariant = variant;

        _segmentation.m_segments << seg;
    }
    filestream.close();

    // Calculate total duration from last segment start & duration
    _segmentation.m_duration =   _segmentation.m_segments.last().startTime +
                                _segmentation.m_segments.last().duration;

    // Find all indices used by the segmenter.
    _segmentation.m_segmentIndices = segmentSet.values();
    qSort(_segmentation.m_segmentIndices);
    _segmentation.m_nSegments = _segmentation.m_segmentIndices.count();
}
void QgsMapRendererParallelJob::renderLayerStatic( LayerRenderJob& job )
{
  if ( job.context.renderingStopped() )
    return;

  if ( job.cached )
    return;

#ifdef QGISDEBUG
  static QSet<QString> running;
  static QMultiMap<int, QString> elapsed;

  QSettings settings;
  bool log = settings.value( "/Map/logCanvasRefreshEvent", false ).toBool();

  QTime t;
  t.start();
  QgsDebugMsg( QString( "job %1 start" ).arg( reinterpret_cast< ulong >( &job ), 0, 16 ) );
  if ( log )
  {
    QgsMessageLog::logMessage( tr( "Layer %1 job started" ).arg( job.layerId ), tr( "Rendering" ) );
    Q_ASSERT( !running.contains( job.layerId ) );
    running << job.layerId;
  }
#endif

  try
  {
    job.renderer->render();
  }
  catch ( QgsException & e )
  {
    QgsDebugMsg( "Caught unhandled QgsException: " + e.what() );
  }
  catch ( std::exception & e )
  {
    QgsDebugMsg( "Caught unhandled std::exception: " + QString::fromAscii( e.what() ) );
  }
  catch ( ... )
  {
    QgsDebugMsg( "Caught unhandled unknown exception" );
  }

#ifdef QGISDEBUG
  int tt = t.elapsed();

  QgsDebugMsg( QString( "job %1 end [%2 ms]" ).arg( reinterpret_cast< ulong >( &job ), 0, 16 ).arg( tt ) );

  if ( log )
  {
    running.remove( job.layerId );
    elapsed.insert( tt, job.layerId );

    QgsMessageLog::logMessage( tr( "Layer %1 job ended (%2 ms; still running:%3)" ).arg( job.layerId ).arg( tt ).arg( QStringList( running.values() ).join( ", " ) ), tr( "Rendering" ) );
    if ( running.isEmpty() )
    {
      QList<int> tt( elapsed.keys() );
      qSort( tt.begin(), tt.end(), qGreater<int>() );
      Q_FOREACH ( int t, tt )
      {
        QgsMessageLog::logMessage( tr( "%1 ms: %2" ).arg( t ).arg( QStringList( elapsed.values( t ) ).join( ", " ) ), tr( "Rendering" ) );
      }
      QgsMessageLog::logMessage( "---", tr( "Rendering" ) );
      elapsed.clear();
    }