/*!
    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("");
}
Exemple #2
0
/*!
    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);
	}
}
Exemple #3
0
/*!
    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("");
}