/*! reads the content of the file \c fileName to the data source \c dataSource or return as string for preview. Uses the settings defined in the data source. */ QString AsciiFilterPrivate::readData(const QString & fileName, AbstractDataSource* dataSource, AbstractFileFilter::ImportMode mode, int lines){ QStringList dataString; QIODevice *device = KFilterDev::deviceForFile(fileName); if (!device->open(QIODevice::ReadOnly)) return QString(); QTextStream in(device); //TODO implement // if (transposed) //... //skip rows, if required for (int i=0; i<startRow-1; i++){ //if the number of rows to skip is bigger then the actual number //of the rows in the file, then quit the function. if( in.atEnd() ) { if (mode==AbstractFileFilter::Replace) { //file with no data to be imported. In replace-mode clear the data source if(dataSource != NULL) dataSource->clear(); } return QString(); } in.readLine(); } //parse the first row: //use the first row to determine the number of columns, //create the columns and use (optionaly) the first row to name them if( in.atEnd() ) { if (mode==AbstractFileFilter::Replace) { //file with no data to be imported. In replace-mode clear the data source if(dataSource != NULL) dataSource->clear(); } return QString(); } QString line = in.readLine(); if( simplifyWhitespacesEnabled) line = line.simplified(); // determine separator QString separator; QStringList lineStringList; if( separatingCharacter == "auto" ){ QRegExp regExp("(\\s+)|(,\\s+)|(;\\s+)|(:\\s+)"); lineStringList = line.split( regExp, QString::SplitBehavior(skipEmptyParts) ); //determine the separator if (lineStringList.size()){ int length1 = lineStringList.at(0).length(); if (lineStringList.size()>1){ int pos2 = line.indexOf(lineStringList.at(1),length1); separator = line.mid(length1, pos2-length1); }else { separator = line.right(line.length()-length1); } } }else { separator = separatingCharacter.replace(QLatin1String("TAB"), QLatin1String("\t"), Qt::CaseInsensitive); separator = separatingCharacter.replace(QLatin1String("SPACE"), QLatin1String(" "), Qt::CaseInsensitive); lineStringList = line.split( separator, QString::SplitBehavior(skipEmptyParts) ); } #ifdef QT_DEBUG qDebug() << "separator '"<<separator << "'"; #endif if (endColumn == -1) endColumn = lineStringList.size(); //use the last available column index QStringList vectorNameList; if ( headerEnabled ){ vectorNameList = lineStringList; }else{ //create vector names out of the space separated vectorNames-string, if not empty if (!vectorNames.isEmpty()){ vectorNameList = vectorNames.split(' '); } } //qDebug()<<" vector names ="<<vectorNameList; int actualRows = AsciiFilter::lineNumber(fileName); // data rows int actualEndRow; if (endRow == -1) actualEndRow = actualRows; else if (endRow > actualRows-1) actualEndRow = actualRows-1; else actualEndRow = endRow; int actualCols=endColumn-startColumn+1; if (headerEnabled) actualRows = actualEndRow-startRow; else actualRows = actualEndRow-startRow+1; if (lines == -1) lines=actualRows; #ifdef QT_DEBUG qDebug()<<" start column ="<<startColumn; qDebug()<<" end column ="<<endColumn; qDebug()<<" actual cols ="<<actualCols; qDebug()<<" start row ="<<startRow; qDebug()<<" end row ="<<actualEndRow; qDebug()<<" actual rows ="<<actualRows; qDebug()<<" lines ="<<lines; #endif int currentRow=0; //indexes the position in the vector(column) int columnOffset=0; //indexes the "start column" in the spreadsheet. Starting from this column the data will be imported. //pointers to the actual data containers QVector<QVector<double>*> dataPointers; if(dataSource != NULL) columnOffset = dataSource->create(dataPointers, mode, actualRows, actualCols, vectorNameList); //header: import the values in the first line, if they were not used as the header (as the names for the columns) bool isNumber; if (!headerEnabled){ for ( int n=0; n<actualCols; n++ ){ if (n<lineStringList.size()) { const double value = lineStringList.at(n).toDouble(&isNumber); if (dataSource != NULL) isNumber ? dataPointers[n]->operator[](0) = value : dataPointers[n]->operator[](0) = NAN; else isNumber ? dataString<<QString::number(value)<<" " : dataString<<QLatin1String("NAN "); } else { if (dataSource != NULL) dataPointers[n]->operator[](0) = NAN; else dataString<<QLatin1String("NAN "); } } dataString<<"\n"; currentRow++; } //Read the remainder of the file. for (int i=currentRow; i<qMin(lines,actualRows); i++){ line = in.readLine(); if(simplifyWhitespacesEnabled) line = line.simplified(); //skip empty lines if (line.isEmpty()) continue; if( line.startsWith(commentCharacter) == true ){ currentRow++; continue; } lineStringList = line.split( separator, QString::SplitBehavior(skipEmptyParts) ); // TODO : read strings (comments) or datetime too for ( int n=0; n<actualCols; n++ ){ if (n<lineStringList.size()) { const double value = lineStringList.at(n).toDouble(&isNumber); if (dataSource != NULL) isNumber ? dataPointers[n]->operator[](currentRow) = value : dataPointers[n]->operator[](currentRow) = NAN; else isNumber ? dataString<<QString::number(value)<<" " : dataString<<QString("NAN "); } else { if (dataSource != NULL) dataPointers[n]->operator[](currentRow) = NAN; else dataString<<QLatin1String("NAN "); } } dataString<<"\n"; currentRow++; emit q->completed(100*currentRow/actualRows); } if (!dataSource) return dataString.join(""); //make everything undo/redo-able again //set the comments for each of the columns Spreadsheet* spreadsheet = dynamic_cast<Spreadsheet*>(dataSource); if (spreadsheet) { //TODO: generalize to different data types QString comment = i18np("numerical data, %1 element", "numerical data, %1 elements", headerEnabled ? currentRow : currentRow+1); for ( int n=startColumn; n<=endColumn; n++ ){ Column* column = spreadsheet->column(columnOffset+n-startColumn); column->setComment(comment); column->setUndoAware(true); if (mode==AbstractFileFilter::Replace) { column->setSuppressDataChangedSignal(false); column->setChanged(); } } spreadsheet->setUndoAware(true); return dataString.join(""); } Matrix* matrix = dynamic_cast<Matrix*>(dataSource); if (matrix) { matrix->setSuppressDataChangedSignal(false); matrix->setChanged(); matrix->setUndoAware(true); } return dataString.join(""); }
/*! reads the content of the file \c fileName to the data source \c dataSource. Uses the settings defined in the data source. */ void ImageFilterPrivate::read(const QString & fileName, AbstractDataSource* dataSource, AbstractFileFilter::ImportMode mode) { QImage image = QImage(fileName); if (image.isNull() || image.format() == QImage::Format_Invalid) { qDebug()<<"failed to read image"<<fileName<<"or invalid image format"; return; } int cols = image.width(); int rows = image.height(); // set range of rows if (endColumn == -1) endColumn = cols; if (endRow == -1) endRow = rows; int actualCols=0, actualRows=0; switch (importFormat) { case ImageFilter::MATRIX: { actualCols = endColumn-startColumn+1; actualRows = endRow-startRow+1; break; } case ImageFilter::XYZ: { actualCols = 3; actualRows = (endColumn-startColumn+1)*(endRow-startRow+1); break; } case ImageFilter::XYRGB: { actualCols = 5; actualRows = (endColumn-startColumn+1)*(endRow-startRow+1); break; } } #ifdef QT_DEBUG qDebug()<<"image format ="<<image.format(); qDebug()<<"image w/h ="<<cols<<rows; qDebug()<<"actual rows/cols ="<<actualRows<<actualCols; #endif //make sure we have enough columns in the data source. int columnOffset = 0; QVector<QVector<double>*> dataPointers; if (dataSource != 0) columnOffset = dataSource->create(dataPointers, mode, actualRows, actualCols); else { qDebug()<<"data source in image import not defined! Giving up."; return; } // read data switch (importFormat) { case ImageFilter::MATRIX: { for (int i=0; i<actualRows; i++) { for ( int j=0; j<actualCols; j++ ) { double value=qGray(image.pixel(j+startColumn-1,i+startRow-1)); dataPointers[j]->operator[](i) = value; } emit q->completed(100*i/actualRows); } break; } case ImageFilter::XYZ: { int currentRow=0; for (int i=startRow-1; i<endRow; i++) { for ( int j=startColumn-1; j<endColumn; j++ ) { QRgb color=image.pixel(j, i); dataPointers[0]->operator[](currentRow) = i+1; dataPointers[1]->operator[](currentRow) = j+1; dataPointers[2]->operator[](currentRow) = qGray(color); currentRow++; } emit q->completed(100*i/actualRows); } break; } case ImageFilter::XYRGB: { int currentRow=0; for (int i=startRow-1; i<endRow; i++) { for ( int j=startColumn-1; j<endColumn; j++ ) { QRgb color=image.pixel(j, i); dataPointers[0]->operator[](currentRow) = i+1; dataPointers[1]->operator[](currentRow) = j+1; dataPointers[2]->operator[](currentRow) = qRed(color); dataPointers[3]->operator[](currentRow) = qGreen(color); dataPointers[4]->operator[](currentRow) = qBlue(color); currentRow++; } emit q->completed(100*i/actualRows); } break; } } Spreadsheet* spreadsheet = dynamic_cast<Spreadsheet*>(dataSource); if (spreadsheet) { QString comment = i18np("numerical data, %1 element", "numerical data, %1 elements", rows); for ( int n=0; n<actualCols; n++ ) { Column* column = spreadsheet->column(columnOffset+n); column->setComment(comment); column->setUndoAware(true); if (mode==AbstractFileFilter::Replace) { column->setSuppressDataChangedSignal(false); column->setChanged(); } } spreadsheet->setUndoAware(true); return; } Matrix* matrix = dynamic_cast<Matrix*>(dataSource); if (matrix) { matrix->setSuppressDataChangedSignal(false); matrix->setChanged(); matrix->setUndoAware(true); } }
/*! reads the content of the file \c fileName to the data source \c dataSource or return as string for preview. Uses the settings defined in the data source. */ QString BinaryFilterPrivate::readData(const QString & fileName, AbstractDataSource* dataSource, AbstractFileFilter::ImportMode mode, int lines){ QStringList dataString; QIODevice *device = KFilterDev::deviceForFile(fileName); if (! device->open(QIODevice::ReadOnly)) return QString(); QDataStream in(device); if (byteOrder == BinaryFilter::BigEndian) in.setByteOrder(QDataStream::BigEndian); else if (byteOrder == BinaryFilter::LittleEndian) in.setByteOrder(QDataStream::LittleEndian); int numRows=BinaryFilter::rowNumber(fileName,vectors,dataType); // catch case that skipStartBytes or startRow is bigger than file if(skipStartBytes >= BinaryFilter::dataSize(dataType)*vectors*numRows || startRow > numRows) { if(dataSource != NULL) dataSource->clear(); return QString(); } // skip bytes at start for (int i=0; i<skipStartBytes; i++){ qint8 tmp; in >> tmp; } // skip until start row for (int i=0; i<(startRow-1)*vectors; ++i){ for(int j=0;j<BinaryFilter::dataSize(dataType);++j) { qint8 tmp; in >> tmp; } } // set range of rows int actualRows; if (endRow == -1) actualRows = numRows-startRow+1; else if (endRow > numRows-startRow+1) actualRows = numRows; else actualRows = endRow-startRow+1; int actualCols=vectors; if (lines == -1) lines=actualRows; #ifdef QT_DEBUG qDebug()<<" numRows ="<<numRows; qDebug()<<" startRow ="<<startRow; qDebug()<<" endRow ="<<endRow; qDebug()<<" actualRows ="<<actualRows; qDebug()<<" actualCols ="<<actualCols; qDebug()<<" lines ="<<lines; #endif QVector<QVector<double>*> dataPointers; int columnOffset = 0; if(dataSource != NULL) columnOffset = dataSource->create(dataPointers, mode, actualRows, actualCols); // read data for (int i=0; i<qMin(actualRows,lines); i++){ for ( int n=0; n<actualCols; n++ ){ switch(dataType) { case BinaryFilter::INT8: { qint8 value; in >> value; if (dataSource != NULL) dataPointers[n]->operator[](i) = value; else dataString<<QString::number(value)<<" "; break; } case BinaryFilter::INT16: { qint16 value; in >> value; if (dataSource != NULL) dataPointers[n]->operator[](i) = value; else dataString<<QString::number(value)<<" "; break; } case BinaryFilter::INT32: { qint32 value; in >> value; if (dataSource != NULL) dataPointers[n]->operator[](i) = value; else dataString<<QString::number(value)<<" "; break; } case BinaryFilter::INT64: { qint64 value; in >> value; if (dataSource != NULL) dataPointers[n]->operator[](i) = value; else dataString<<QString::number(value)<<" "; break; } case BinaryFilter::UINT8: { quint8 value; in >> value; if (dataSource != NULL) dataPointers[n]->operator[](i) = value; else dataString<<QString::number(value)<<" "; break; } case BinaryFilter::UINT16: { quint16 value; in >> value; if (dataSource != NULL) dataPointers[n]->operator[](i) = value; else dataString<<QString::number(value)<<" "; break; } case BinaryFilter::UINT32: { quint32 value; in >> value; if (dataSource != NULL) dataPointers[n]->operator[](i) = value; else dataString<<QString::number(value)<<" "; break; } case BinaryFilter::UINT64: { quint64 value; in >> value; if (dataSource != NULL) dataPointers[n]->operator[](i) = value; else dataString<<QString::number(value)<<" "; break; } case BinaryFilter::REAL32: { float value; in >> value; if (dataSource != NULL) dataPointers[n]->operator[](i) = value; else dataString<<QString::number(value)<<" "; break; } case BinaryFilter::REAL64: { double value; in >> value; if (dataSource != NULL) dataPointers[n]->operator[](i) = value; else dataString<<QString::number(value)<<" "; break; } } } dataString<<"\n"; emit q->completed(100*i/actualRows); } if (!dataSource) return dataString.join(""); //make everything undo/redo-able again //set the comments for each of the columns Spreadsheet* spreadsheet = dynamic_cast<Spreadsheet*>(dataSource); if (spreadsheet) { Spreadsheet* spreadsheet = dynamic_cast<Spreadsheet*>(dataSource); QString comment = i18np("numerical data, %1 element", "numerical data, %1 elements", actualRows); for ( int n=0; n<actualCols; n++ ){ Column* column = spreadsheet->column(columnOffset+n); column->setComment(comment); column->setUndoAware(true); if (mode==AbstractFileFilter::Replace) { column->setSuppressDataChangedSignal(false); column->setChanged(); } } spreadsheet->setUndoAware(true); return dataString.join(""); } Matrix* matrix = dynamic_cast<Matrix*>(dataSource); if (matrix) { matrix->setSuppressDataChangedSignal(false); matrix->setChanged(); matrix->setUndoAware(true); } return dataString.join(""); }