You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

417 lines
13 KiB

/***************************************************************************
ksmatrix.h
-------------------
begin : 01-January-2000
copyright : (C) 2000 by Kamil Dobkowski
email : kamildobk@poczta.onet.pl
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef KSMATRIX_H
#define KSMATRIX_H
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "widgets/qsmatrix.h"
#include "interface/etype.h"
#include "formula/mpsymbol.h"
#include <qstring.h>
#include <assert.h>
#include <qobject.h>
class QSData;
class QWidget;
class KSProjectXML;
//---------------------------------------------------------------------------------------------//
/**
* Ordinary matrix.
*/
class KSMatrix : public QSMatrix {
Q_OBJECT
public:
static KSMatrix *create( EType elementType );
/**
* Constructor
*/
KSMatrix( EType elementType );
/**
* Destructor
*/
virtual ~KSMatrix();
/**
* Reimplemented QSMatrix::editable
*/
virtual bool isEditable() const;
/**
* Reimplemented QSMatrix::
*/
virtual EType type() const;
/**
* Check using what element type the matrix can be the most effectively stored.
*/
EType detectType();
/**
* Sets the raw data. The arguments are not checked. Call it only if you know what you are doing.
*/
void setRawData( void *ptr, int rows, int col, bool deleteData=true, int lineOffset=0, int pixelOffset=0 );
/**
* Copies this matrix.
*/
void setMatrix( QSMatrix *matrix );
/**
* Resizes matrix ( preserves old data ).
*/
virtual bool resize( int rows, int cols );
/**
* Transposes matrix.
*/
virtual bool transpose();
/**
* Converts elements to a different type. Copies name() and dataObject() and channel() to the newly created matrix.
*/
KSMatrix *convertType( EType newType );
/**
* Returns size of an element.
*/
virtual int elementSize() const = 0;
/**
* Number of rows
*/
virtual int rows() const { return m_rows; }
/**
* Number of columns
*/
virtual int cols() const { return m_cols; }
/**
* Returns size of an element.
*/
void *ptr() const { return m_ptr; }
/**
* Return line offset in bytes
*/
int lo() const { return m_lo; }
/**
* Returns element offset in bytes
*/
int po() const { return m_po; }
protected:
int m_rows;
int m_cols;
int m_lo;
int m_po;
char *m_ptr;
bool m_delete;
EType m_type;
KSMatrix( const QSMatrix& );
void operator=(const QSMatrix& );
};
//---------------------------------------------------------------------------------------------//
/**
* Implementation of an ordinary matrix for different element types.
* It have not Q_OBJECT macro defined ( this is a tmeplate class )
*/
template<class ELEMENT_TYPE>
class KSMatrixImpl : public KSMatrix {
public:
KSMatrixImpl( EType elementType ): KSMatrix( elementType ) {}
virtual ~KSMatrixImpl() {}
virtual double value( int row, int col ) {
assert( row >= 0 );
assert( col >= 0 );
assert( col < m_cols );
assert( row < m_rows );
return double( *(reinterpret_cast<ELEMENT_TYPE *>(m_ptr+row*m_lo+col*m_po)) );
}
virtual void setValue( int row, int col, double value ) {
assert( row >= 0 );
assert( col >= 0 );
assert( col < m_cols );
assert( row < m_rows );
*(reinterpret_cast<ELEMENT_TYPE *>(m_ptr+row*m_lo+col*m_po)) = (ELEMENT_TYPE )value;
}
virtual int elementSize() const { return sizeof(ELEMENT_TYPE); }
virtual void loadStateFromStream( QDataStream& stream, QSObjectFactory *factory )
{
KSMatrix::loadStateFromStream( stream, factory );
int new_rows; stream >> new_rows;
int new_cols; stream >> new_cols;
ELEMENT_TYPE value;
resize( new_rows, new_cols );
for( int row=0; row<rows(); row++ ) for( int col=0; col<cols(); col++ ) { stream >> value; setValue( row, col, value ); }
}
virtual void saveStateToStream( QDataStream& stream, QSObjectFactory *factory )
{
KSMatrix::saveStateToStream( stream, factory );
stream << rows();
stream << cols();
for( int row=0; row<rows(); row++ ) for( int col=0; col<cols(); col++ ) stream << (ELEMENT_TYPE )value(row,col);
}
protected:
KSMatrixImpl( const QSMatrix& ) {}
void operator=(const QSMatrix& ) {}
};
//---------------------------------------------------------------------------------------------//
/**
* Class which holds its internal data as strings, not as numbers.
*/
class KSMatrixString : public QSMatrix {
Q_OBJECT
public:
KSMatrixString();
virtual ~KSMatrixString();
virtual bool isEditable() const;
virtual bool isString() const;
virtual bool transpose();
virtual void setValue( int row, int col, double value );
virtual double value( int row, int col );
virtual void setString( int row, int col, const QString& string );
virtual QString string( int row, int col );
virtual int rows() const;
virtual int cols() const;
bool resize( int rows, int cols );
void setMatrix( QSMatrix *matrix );
virtual void loadStateFromStream( QDataStream& stream, QSObjectFactory *factory );
virtual void saveStateToStream( QDataStream& stream, QSObjectFactory *factory );
protected:
int m_rows;
int m_cols;
bool m_transposed;
QString *m_string_table;
};
//---------------------------------------------------------------------------------------------//
/**
* Points to the selected submatrix of the other matrix.
* It traces changes in the parent matrix.
* It is bound to the channel of QSData object, not to QSMatrix itself, because it
* needs change and delete notify.
*/
class KSMatrixRef : public QSMatrix {
Q_OBJECT
public:
KSMatrixRef();
virtual ~KSMatrixRef();
QSData *refObject() const { return m_ref_object; }
int refChannel() const { return m_ref_channel; }
int refColFrom() const { return m_ref_col_from; }
int refColStep() const { return m_ref_col_step; }
int refColTo() const { return m_ref_col_to; }
int refRowFrom() const { return m_ref_row_from; }
int refRowStep() const { return m_ref_row_step; }
int refRowTo() const { return m_ref_row_to; }
bool refTransposition() const { return m_transposition; }
virtual bool isReference() const { return true; }
virtual bool isEditable() const { return m_ref_editable; }
virtual bool isString() const { return m_ref_string; }
virtual void setValue( int row, int col, double value );
virtual double value( int row, int col );
virtual void setString( int row, int col, const QString& string );
virtual QString string( int row, int col );
virtual int rows() const { return m_rows; }
virtual int cols() const { return m_cols; }
protected slots:
void reconnect( QSData *, int );
void break_connection( QSData * );
protected:
void reconnect();
void setRefObject( QSData *dataObject, int channel,
int rowFrom=0, int rowStep=1, int rowTo=-1,
int colFrom=0, int colStep=1, int colTo=-1,
bool transposition=false );
QSMatrix *m_ref_matrix;
QSData *m_ref_object;
int m_ref_channel;
int m_ref_col_from;
int m_ref_col_step;
int m_ref_col_to;
int m_ref_row_from;
int m_ref_row_step;
int m_ref_row_to;
bool m_transposition;
int m_rows;
int m_cols;
int m_start_row;
int m_start_col;
bool m_in_loop;
bool m_ref_editable;
bool m_ref_string;
};
//-------------------------------------------------------------//
//-------------------------------------------------------------//
//-------------------------------------------------------------//
//-------------------------------------------------------------//
class KSWorkbook;
/**
* Points to sheet cell range
*/
class KSMatrixWorksheetCellRange : public KSMatrixRef
{
Q_OBJECT
Q_PROPERTY( int worksheet READ worksheet WRITE setWorksheet )
Q_PROPERTY( int rowFrom READ rowFrom WRITE setRowFrom )
Q_PROPERTY( int colFrom READ colFrom WRITE setColFrom )
Q_PROPERTY( int rowStep READ rowStep WRITE setRowStep )
Q_PROPERTY( int colStep READ colStep WRITE setColStep )
Q_PROPERTY( int rowTo READ rowTo WRITE setRowTo )
Q_PROPERTY( int colTo READ colTo WRITE setColTo )
Q_PROPERTY( bool transposition READ transposition WRITE setTransposition )
public:
KSMatrixWorksheetCellRange( KSWorkbook *workbook );
virtual ~KSMatrixWorksheetCellRange();
virtual void setWorksheet( int index );
virtual int worksheet() const;
/**
* Sets a range to contain a single column.
*/
void setColumn( int column );
void setRowFrom( int row );
void setColFrom( int col );
void setRowStep( int step );
void setColStep( int step );
void setRowTo( int row );
void setColTo( int col );
int rowFrom() const { return refRowFrom(); }
int colFrom() const { return refColFrom(); }
int rowStep() const { return refRowStep(); }
int colStep() const { return refColStep(); }
int rowTo() const { return refRowTo(); }
int colTo() const { return refColTo(); }
void setTransposition( bool enabled );
bool transposition() const { return refTransposition(); }
virtual bool transpose() { setTransposition(!transposition()); return true; }
virtual bool isReference() const { return true; }
virtual void loadStateFromStream( QDataStream& stream, QSObjectFactory *factory );
virtual void saveStateToStream( QDataStream& stream, QSObjectFactory *factory );
protected:
KSWorkbook *m_workbook;
};
//-------------------------------------------------------------//
//-------------------------------------------------------------//
//-------------------------------------------------------------//
//-------------------------------------------------------------//
class MPError;
class MPFactoryList;
class KSMatrixFormula : public QSMatrix
{
Q_OBJECT
Q_PROPERTY( QString formula READ formula WRITE setFormula );
Q_PROPERTY( bool transposition READ transposition WRITE setTransposition );
public:
/**
* Constructor
*/
KSMatrixFormula();
/**
* Destructor
*/
virtual ~KSMatrixFormula();
/**
* Sets a formula string. This function do nothing else.
* To calculate values you must use init()
*/
void setFormula( const QString& formula );
/**
* Returns a formula string
*/
QString formula() const { return m_formula; }
/**
* Parses formula and calculates all values.
* FactoryList is not deleted in this function.
*/
bool init( MPError& error, MPFactoryList *locals = NULL );
virtual bool isEditable() const { return false; }
virtual double value( int row, int col );
virtual int rows() const { return m_rows; }
virtual int cols() const { return m_cols; }
virtual bool transpose();
void setTransposition( bool enabled );
bool transposition() const { return m_transposition; }
protected:
QString m_formula;
int m_rows;
int m_cols;
double *m_data;
int m_row_offset;
int m_col_offset;
bool m_transposition;
};
//-------------------------------------------------------------//
//-------------------------------------------------------------//
//-------------------------------------------------------------//
//-------------------------------------------------------------//
/**
* Maps parser symbol to matrix. It is only immediately use. It does
* not delete matrix in destructor..
*/
class MPSymQSMatrix : public MPSymbol
{
public:
/**
* Constructor
*/
MPSymQSMatrix( QSMatrix *matrix, MPSymbolList *args, int columnFrom, int columnTo, const char *id );
/**
* Constructor. Range can be greater than matrix range. Outer values are filled with the last matrix value
*/
MPSymQSMatrix( QSMatrix *matrix, const QRect& range, MPSymbolList *args, int columnFrom, int columnTo, const char *id );
/**
* Destructor
*/
virtual ~MPSymQSMatrix();
virtual void checkArgs( MPError& error );
virtual double value( int row, int col );
virtual bool isVariable() const { return true; }
private:
QSMatrix *m_matrix;
int m_matrix_row_max;
int m_matrix_col_max;
QRect m_range;
};
#endif