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.
838 lines
24 KiB
838 lines
24 KiB
/***************************************************************************
|
|
ksmatrix.cpp
|
|
-------------------
|
|
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. *
|
|
* *
|
|
***************************************************************************/
|
|
|
|
#include"ksmatrix.h"
|
|
#include"widgets/qsdata.h"
|
|
#include"widgets/qsconsole.h"
|
|
#include"formula/mpformula.h"
|
|
#include"ksworkbook.h"
|
|
#include"ksglobalmatrixlist.h"
|
|
#include<qstrlist.h>
|
|
#include<qmetaobject.h>
|
|
|
|
#include<iostream>
|
|
|
|
|
|
/**
|
|
* Reference points to QSData::channel !
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
KSMatrix *KSMatrix::create( EType elementType )
|
|
{
|
|
switch( elementType ) {
|
|
case EUChar: return new KSMatrixImpl<unsigned char>(EUChar);
|
|
case EUShort: return new KSMatrixImpl<unsigned short>(EUShort);
|
|
case EShort: return new KSMatrixImpl<short>(EShort);
|
|
case ELong: return new KSMatrixImpl<long>(ELong);
|
|
case EFloat: return new KSMatrixImpl<float>(EFloat);
|
|
case EDouble: return new KSMatrixImpl<double>(EDouble);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
//
|
|
// Flexible, but too much complicated
|
|
// Drop line_offset and pixel_offset and make some template specializations with '<<' instead of '*' ( used in DDE with Octave )
|
|
//
|
|
KSMatrix::KSMatrix( EType elementType )
|
|
:QSMatrix()
|
|
{
|
|
m_type = elementType;
|
|
m_rows = 0;
|
|
m_cols = 0;
|
|
m_ptr = NULL;
|
|
m_lo = 0;
|
|
m_po = 0;
|
|
m_delete = true;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
EType KSMatrix::detectType()
|
|
{
|
|
double max = 0.0;
|
|
double min = 0.0;
|
|
|
|
EType type = EUChar;
|
|
for( int r=0; r<rows(); r++ )
|
|
for( int c=0; c<cols(); c++ ) {
|
|
double val = value(r,c);
|
|
if ( type == EUChar && val != double((unsigned char)val) ) type = EShort;
|
|
if ( type == EShort && val != double((short)val) ) type = ELong;
|
|
if ( type == ELong && val != double((long)val) ) type = EFloat;
|
|
if ( type == EFloat && val != double((float)val) ) type = EDouble;
|
|
if ( type == EDouble ) break;
|
|
|
|
if ( r == 0 && c == 0 ) max = min = val; else { max = max<val?val:max; min = min>val?val:min; }
|
|
}
|
|
|
|
if ( type == ELong && min >= 0x0 && max <= 0xffff ) type = EUShort;
|
|
return type;
|
|
}
|
|
//-------------------------------------------------------------//
|
|
|
|
KSMatrix::~KSMatrix()
|
|
{
|
|
if ( m_delete ) delete m_ptr;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
bool KSMatrix::isEditable() const
|
|
{
|
|
return true;
|
|
}
|
|
|
|
//-------------------------------------------------------------/
|
|
|
|
EType KSMatrix::type() const
|
|
{
|
|
return m_type;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
KSMatrix *KSMatrix::convertType( EType newType )
|
|
{
|
|
KSMatrix *result = KSMatrix::create( newType );
|
|
result->setName( name() );
|
|
result->setDataObject( dataObject(), channel() );
|
|
result->setRawData( new char[m_rows*m_cols*result->elementSize()], m_rows, m_cols, true );
|
|
for ( int crow=0; crow<m_rows; crow++ )
|
|
for ( int ccol=0; ccol<m_cols; ccol++ )
|
|
result->setValue( crow, ccol, value(crow,ccol) );
|
|
return result;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
bool KSMatrix::resize( int rows, int cols )
|
|
{
|
|
if ( rows <= 0 || cols <= 0 ) {
|
|
setRawData( NULL, 0, 0 );
|
|
} else {
|
|
KSMatrix *new_data = KSMatrix::create( m_type );
|
|
new_data->setRawData( new char[rows*cols*new_data->elementSize()], rows, cols, false );
|
|
for ( int crow=0; crow<new_data->rows(); crow++ )
|
|
for ( int ccol=0; ccol<new_data->cols(); ccol++ )
|
|
if ( crow<m_rows && ccol<m_cols ) new_data->setValue( crow, ccol, value(crow,ccol) );
|
|
else new_data->setValue( crow, ccol, 0.0 );
|
|
setRawData( new_data->ptr(), new_data->rows(), new_data->cols(), true );
|
|
delete new_data;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
bool KSMatrix::transpose()
|
|
{
|
|
int temp;
|
|
temp = m_rows; m_rows = m_cols; m_cols = temp;
|
|
temp = m_lo; m_lo = m_po; m_po = temp;
|
|
return true;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void KSMatrix::setRawData( void *ptr, int rows, int cols, bool deleteData, int lineOffset, int pixelOffset )
|
|
{
|
|
if ( m_delete ) delete m_ptr;
|
|
m_ptr = (char *)ptr;
|
|
m_rows = rows;
|
|
m_cols = cols;
|
|
m_delete = deleteData;
|
|
m_po = pixelOffset ? pixelOffset : elementSize();
|
|
m_lo = lineOffset ? lineOffset : m_po*cols;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void KSMatrix::setMatrix( QSMatrix *matrix )
|
|
{
|
|
setRawData( new char[matrix->rows()*matrix->cols()*elementSize()], matrix->rows(), matrix->cols(), true );
|
|
for ( int crow=0; crow<m_rows; crow++ )
|
|
for ( int ccol=0; ccol<m_cols; ccol++ )
|
|
setValue( crow, ccol, matrix->value(crow,ccol) );
|
|
}
|
|
|
|
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
|
|
|
|
KSMatrixString::KSMatrixString()
|
|
{
|
|
m_rows = 0;
|
|
m_cols = 0;
|
|
m_transposed = false;
|
|
m_string_table = NULL;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
KSMatrixString::~KSMatrixString()
|
|
{
|
|
delete[] m_string_table;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
bool KSMatrixString::isEditable() const
|
|
{
|
|
return true;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
bool KSMatrixString::isString() const
|
|
{
|
|
return true;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void KSMatrixString::setValue( int row, int col, double value )
|
|
{
|
|
setString( row, col, QString::number(value,'g',9) );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
double KSMatrixString::value( int row, int col )
|
|
{
|
|
return string(row,col).toDouble();
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
int KSMatrixString::cols() const
|
|
{
|
|
return m_transposed ? m_rows : m_cols;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
int KSMatrixString::rows() const
|
|
{
|
|
return m_transposed ? m_cols : m_rows;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void KSMatrixString::setString( int row, int col, const QString& string )
|
|
{
|
|
if ( m_transposed ) m_string_table[ col*m_cols+row ] = string;
|
|
else m_string_table[ row*m_cols+col ] = string;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
QString KSMatrixString::string( int row, int col )
|
|
{
|
|
return m_transposed ? m_string_table[col*m_cols+row] : m_string_table[row*m_cols+col];
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
bool KSMatrixString::resize( int new_rows, int new_cols )
|
|
{
|
|
QString *new_string_table = new QString[new_rows*new_cols];
|
|
|
|
for( int curr_row=0; curr_row<QMIN(new_rows,rows()); curr_row++ )
|
|
for( int curr_col=0; curr_col<QMIN(new_cols,cols()); curr_col++ ) {
|
|
new_string_table[curr_row*new_cols+curr_col] = string(curr_row,curr_col);
|
|
}
|
|
|
|
delete[] m_string_table; m_string_table = new_string_table;
|
|
m_rows = new_rows;
|
|
m_cols = new_cols;
|
|
m_transposed = false;
|
|
return true;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
bool KSMatrixString::transpose()
|
|
{
|
|
m_transposed = !m_transposed;
|
|
return true;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void KSMatrixString::setMatrix( QSMatrix *matrix )
|
|
{
|
|
delete[] m_string_table;
|
|
m_rows = matrix->rows();
|
|
m_cols = matrix->cols();
|
|
m_transposed = false;
|
|
m_string_table = new QString[m_rows*m_cols];
|
|
for ( int crow=0; crow<m_rows; crow++ )
|
|
for ( int ccol=0; ccol<m_cols; ccol++ )
|
|
setString( crow, ccol, matrix->string(crow,ccol) );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void KSMatrixString::loadStateFromStream( QDataStream& stream, QSObjectFactory *factory )
|
|
{
|
|
QSMatrix::loadStateFromStream( stream, factory );
|
|
int new_rows; stream >> new_rows;
|
|
int new_cols; stream >> new_cols;
|
|
resize( new_rows, new_cols );
|
|
for( int row=0; row<rows(); row++ )
|
|
for( int col=0; col<cols(); col++ ) {
|
|
QString element; stream >> element;
|
|
setString( row, col, element );
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void KSMatrixString::saveStateToStream( QDataStream& stream, QSObjectFactory *factory )
|
|
{
|
|
QSMatrix::saveStateToStream( stream, factory );
|
|
stream << (int )rows();
|
|
stream << (int )cols();
|
|
for( int row=0; row<rows(); row++ )
|
|
for( int col=0; col<cols(); col++ ) {
|
|
QString element = string(row,col);
|
|
stream << element;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
|
|
|
|
|
|
|
|
KSMatrixRef::KSMatrixRef()
|
|
{
|
|
m_rows = 0;
|
|
m_cols = 0;
|
|
m_ref_matrix = NULL;
|
|
m_ref_object = NULL;
|
|
m_ref_channel = 0;
|
|
m_ref_col_from = 0;
|
|
m_ref_col_to = -1;
|
|
m_ref_col_step = 1;
|
|
m_ref_row_from = 0;
|
|
m_ref_row_to = -1;
|
|
m_ref_row_step = 1;
|
|
m_start_row = 0;
|
|
m_start_col = 0;
|
|
m_transposition = false;
|
|
m_ref_editable = false;
|
|
m_ref_string = false;
|
|
m_in_loop = false; // desn't allow circular references
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
KSMatrixRef::~KSMatrixRef()
|
|
{
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void KSMatrixRef::setRefObject( QSData *dataObject, int channel,
|
|
int rowFrom, int rowStep, int rowTo,
|
|
int colFrom, int colStep, int colTo,
|
|
bool transposition )
|
|
{
|
|
if ( dataObject != m_data_object || channel != m_channel ) {
|
|
if ( channel < 0 ) dataObject = NULL;
|
|
m_ref_row_from = rowFrom;
|
|
m_ref_row_to = rowTo;
|
|
m_ref_row_step = rowStep ? rowStep : 1;
|
|
m_ref_col_from = colFrom;
|
|
m_ref_col_to = colTo;
|
|
m_ref_col_step = colStep ? colStep : 1;
|
|
m_transposition = transposition;
|
|
if ( dataObject ) {
|
|
m_ref_object = dataObject;
|
|
m_ref_channel = channel;
|
|
connect ( dataObject, SIGNAL(sigDataChanged(QSData*,int)), this, SLOT(reconnect(QSData*,int)) );
|
|
connect ( dataObject, SIGNAL(sigDeleted(QSData*)), this, SLOT(break_connection(QSData*)) );
|
|
reconnect();
|
|
} else {
|
|
break_connection( m_ref_object );
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void KSMatrixRef::setValue( int row, int col, double value )
|
|
{
|
|
if ( !m_in_loop ) {
|
|
m_in_loop = true;
|
|
if ( m_transposition ) m_ref_matrix->setValue( m_start_col+col*m_ref_col_step, m_start_row+row*m_ref_row_step, value );
|
|
else m_ref_matrix->setValue( m_start_row+row*m_ref_row_step, m_start_col+col*m_ref_col_step, value );
|
|
m_in_loop = false;
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
double KSMatrixRef::value( int row, int col )
|
|
{
|
|
double result;
|
|
if ( !m_in_loop ) {
|
|
m_in_loop = true;
|
|
if ( m_transposition ) result = m_ref_matrix->value( m_start_col+col*m_ref_col_step, m_start_row+row*m_ref_row_step );
|
|
else result = m_ref_matrix->value( m_start_row+row*m_ref_row_step, m_start_col+col*m_ref_col_step );
|
|
m_in_loop = false;
|
|
} else {
|
|
result = sqrt(-1.0);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void KSMatrixRef::setString( int row, int col, const QString& string )
|
|
{
|
|
if ( !m_in_loop ) {
|
|
m_in_loop = true;
|
|
if ( m_transposition ) m_ref_matrix->setString( m_start_col+col*m_ref_col_step, m_start_row+row*m_ref_row_step, string );
|
|
else m_ref_matrix->setString( m_start_row+row*m_ref_row_step, m_start_col+col*m_ref_col_step, string );
|
|
m_in_loop = false;
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
QString KSMatrixRef::string( int row, int col )
|
|
{
|
|
QString result;
|
|
if ( !m_in_loop ) {
|
|
m_in_loop = true;
|
|
if ( m_transposition ) result = m_ref_matrix->string( m_start_col+col*m_ref_col_step, m_start_row+row*m_ref_row_step );
|
|
else result = m_ref_matrix->string( m_start_row+row*m_ref_row_step, m_start_col+col*m_ref_col_step );
|
|
m_in_loop = false;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void KSMatrixRef::reconnect( QSData *dataObject, int channel )
|
|
{
|
|
if ( m_in_loop ) QSConsole::write( "Kmatplot: Circular reference !" );
|
|
else
|
|
if ( m_ref_object && m_ref_object == dataObject && (m_ref_channel == channel || channel == -1) ) // our referenced object changed
|
|
{
|
|
m_in_loop = true;
|
|
dataChanging();
|
|
reconnect();
|
|
dataChanged();
|
|
m_in_loop = false;
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void KSMatrixRef::reconnect()
|
|
{
|
|
m_ref_matrix = m_ref_object->matrix( m_ref_channel );
|
|
int ref_rows = m_ref_matrix ? m_ref_matrix->rows() : 0;
|
|
int ref_cols = m_ref_matrix ? m_ref_matrix->cols() : 0;
|
|
m_start_row = ( m_ref_row_from == -1 ) ? ref_rows-1 : m_ref_row_from;
|
|
m_start_col = ( m_ref_col_from == -1 ) ? ref_cols-1 : m_ref_col_from;
|
|
int end_row = ( m_ref_row_to == -1 ) ? ref_rows-1 : m_ref_row_to;
|
|
int end_col = ( m_ref_col_to == -1 ) ? ref_cols-1 : m_ref_col_to;
|
|
|
|
if ( m_ref_row_step > 0 ) {
|
|
m_start_row = QMAX( m_start_row, 0 );
|
|
end_row = QMIN( end_row, ref_rows-1 );
|
|
m_rows = ( end_row - m_start_row ) / m_ref_row_step + 1;
|
|
} else {
|
|
m_start_row = QMIN( m_start_row, ref_rows-1 );
|
|
end_row = QMAX( end_row, 0 );
|
|
m_rows = ( end_row - m_start_row ) / m_ref_row_step + 1;
|
|
}
|
|
|
|
if ( m_ref_col_step > 0 ) {
|
|
m_start_col = QMAX( m_start_col, 0 );
|
|
end_col = QMIN( end_col, ref_cols-1 );
|
|
m_cols = ( end_col - m_start_col ) / m_ref_col_step + 1;
|
|
} else {
|
|
m_start_col = QMIN( m_start_col, ref_cols-1 );
|
|
end_col = QMAX( end_col, 0 );
|
|
m_cols = ( end_col - m_start_col ) / m_ref_col_step + 1;
|
|
}
|
|
|
|
m_rows = QMAX( m_rows, 0 );
|
|
m_cols = QMAX( m_cols, 0 );
|
|
|
|
if ( m_transposition ) {
|
|
int temp = m_cols;
|
|
m_cols = m_rows;
|
|
m_rows = temp;
|
|
}
|
|
|
|
if ( m_rows*m_cols == 0 ) m_rows = m_cols = 0;
|
|
m_ref_editable = m_ref_matrix ? m_ref_matrix->isEditable() : false;
|
|
m_ref_string = m_ref_matrix ? m_ref_matrix->isString() : false;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void KSMatrixRef::break_connection( QSData *dataObject )
|
|
{
|
|
if ( m_in_loop ) QSConsole::write( "Kmatplot: Circular reference !" );
|
|
else
|
|
if ( m_ref_object && m_ref_object == dataObject ) {
|
|
m_in_loop = true;
|
|
dataChanging();
|
|
m_rows = 0;
|
|
m_cols = 0;
|
|
m_start_row = 0;
|
|
m_start_col = 0;
|
|
m_ref_matrix = NULL;
|
|
m_ref_object = NULL;
|
|
m_ref_channel = 0;
|
|
m_in_loop = false;
|
|
m_ref_editable = false;
|
|
m_ref_string = false;
|
|
dataChanged();
|
|
m_in_loop = false;
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
|
|
|
|
KSMatrixWorksheetCellRange::KSMatrixWorksheetCellRange( KSWorkbook *workbook )
|
|
: KSMatrixRef()
|
|
{
|
|
m_workbook = workbook;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
KSMatrixWorksheetCellRange::~KSMatrixWorksheetCellRange()
|
|
{
|
|
// unregister
|
|
KSSheet *curr_sheet = dynamic_cast<KSSheet*>(refObject());
|
|
if ( curr_sheet ) curr_sheet->cellRangeRemove( this );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void KSMatrixWorksheetCellRange::setWorksheet( int index )
|
|
{
|
|
KSSheet *sheet = m_workbook->sheets()->child(index);
|
|
if ( sheet != refObject() ) {
|
|
KSSheet *curr_sheet = dynamic_cast<KSSheet*>(refObject());
|
|
KSSheet *new_sheet = m_workbook->sheets()->child(index);
|
|
if ( curr_sheet ) curr_sheet->cellRangeRemove( this );
|
|
setRefObject( new_sheet, 0,
|
|
rowFrom(), rowStep(), rowTo(),
|
|
colFrom(), colStep(), colTo(),
|
|
transposition() );
|
|
if ( new_sheet ) new_sheet->cellRangeAdd( this );
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
int KSMatrixWorksheetCellRange::worksheet() const
|
|
{
|
|
return m_workbook->sheets()->childIndex(refObject());
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void KSMatrixWorksheetCellRange::setColumn( int column )
|
|
{
|
|
setRefObject( refObject(), 0,
|
|
0, 1, -1,
|
|
column, 1, column,
|
|
transposition() );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void KSMatrixWorksheetCellRange::setRowFrom( int row )
|
|
{
|
|
setRefObject( refObject(), 0,
|
|
row, rowStep(), rowTo(),
|
|
colFrom(), colStep(), colTo(),
|
|
transposition() );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void KSMatrixWorksheetCellRange::setColFrom( int col )
|
|
{
|
|
setRefObject( refObject(), 0,
|
|
rowFrom(), rowStep(), rowTo(),
|
|
col, colStep(), colTo(),
|
|
transposition() );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void KSMatrixWorksheetCellRange::setRowStep( int step )
|
|
{
|
|
setRefObject( refObject(), 0,
|
|
rowFrom(), step, rowTo(),
|
|
colFrom(), colStep(), colTo(),
|
|
transposition() );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void KSMatrixWorksheetCellRange::setColStep( int step )
|
|
{
|
|
setRefObject( refObject(), 0,
|
|
rowFrom(), rowStep(), rowTo(),
|
|
colFrom(), step, colTo(),
|
|
transposition() );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void KSMatrixWorksheetCellRange::setRowTo( int row )
|
|
{
|
|
setRefObject( refObject(), 0,
|
|
rowFrom(), rowStep(), row,
|
|
colFrom(), colStep(), colTo(),
|
|
transposition() );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void KSMatrixWorksheetCellRange::setColTo( int col )
|
|
{
|
|
setRefObject( refObject(), 0,
|
|
rowFrom(), rowStep(), rowTo(),
|
|
colFrom(), colStep(), col,
|
|
transposition() );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void KSMatrixWorksheetCellRange::setTransposition( bool enabled )
|
|
{
|
|
setRefObject( refObject(), 0,
|
|
rowFrom(), rowStep(), rowTo(),
|
|
colFrom(), colStep(), colTo(),
|
|
enabled );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void KSMatrixWorksheetCellRange::loadStateFromStream( QDataStream& stream, QSObjectFactory *factory )
|
|
{
|
|
KSMatrixRef::loadStateFromStream( stream, factory );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void KSMatrixWorksheetCellRange::saveStateToStream( QDataStream& stream, QSObjectFactory *factory )
|
|
{
|
|
KSMatrixRef::saveStateToStream( stream, factory );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
|
|
KSMatrixFormula::KSMatrixFormula()
|
|
:QSMatrix()
|
|
{
|
|
m_formula = "0:1:10";
|
|
m_rows = 0;
|
|
m_cols = 0;
|
|
m_data = NULL;
|
|
m_row_offset = 0;
|
|
m_col_offset = 0;
|
|
m_transposition = false;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
KSMatrixFormula::~KSMatrixFormula()
|
|
{
|
|
delete m_data;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void KSMatrixFormula::setFormula( const QString& formula )
|
|
{
|
|
m_formula = formula;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
bool KSMatrixFormula::init( MPError& error, MPFactoryList *locals )
|
|
{
|
|
delete m_data;
|
|
m_rows = 0;
|
|
m_cols = 0;
|
|
m_data = NULL;
|
|
m_row_offset = 0;
|
|
m_col_offset = 0;
|
|
|
|
MPFormula f;
|
|
MPSymbol *s = f.parse( m_formula, error, locals );
|
|
if ( s ) {
|
|
m_cols = s->cols();
|
|
m_rows = s->rows();
|
|
m_row_offset = m_cols;
|
|
m_col_offset = 1;
|
|
m_data = new double[m_rows*m_cols];
|
|
for( int row=0; row<m_rows; row++ )
|
|
for( int col=0; col<m_cols; col++ )
|
|
m_data[row*m_cols+col] = s->value(row,col);
|
|
if ( m_transposition ) { transpose(); m_transposition = true; }
|
|
delete s;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
double KSMatrixFormula::value( int row, int col )
|
|
{
|
|
return *(m_data + m_row_offset*row + m_col_offset*col);
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
bool KSMatrixFormula::transpose()
|
|
{
|
|
int temp;
|
|
temp = m_rows; m_rows = m_cols; m_cols = temp;
|
|
temp = m_row_offset; m_row_offset = m_col_offset; m_col_offset = temp;
|
|
m_transposition = !m_transposition;
|
|
return true;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void KSMatrixFormula::setTransposition( bool enabled )
|
|
{
|
|
if ( enabled != m_transposition ) {
|
|
transpose();
|
|
}
|
|
}
|
|
//-------------------------------------------------------------------------//
|
|
//-------------------------------------------------------------------------//
|
|
//-------------------------------------------------------------------------//
|
|
//-------------------------------------------------------------------------//
|
|
//-------------------------------------------------------------------------//
|
|
|
|
MPSymQSMatrix::MPSymQSMatrix( QSMatrix *matrix, MPSymbolList *args, int columnFrom, int columnTo, const char *id )
|
|
: MPSymbol( args, columnFrom, columnTo, id )
|
|
{
|
|
m_matrix = matrix;
|
|
m_range = QRect(0,0,-1,-1);
|
|
}
|
|
|
|
//-------------------------------------------------------------------------//
|
|
|
|
MPSymQSMatrix::MPSymQSMatrix( QSMatrix *matrix, const QRect& range, MPSymbolList *args, int columnFrom, int columnTo, const char *id )
|
|
: MPSymbol( args, columnFrom, columnTo, id )
|
|
{
|
|
m_matrix = matrix;
|
|
m_range = range;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------//
|
|
|
|
MPSymQSMatrix::~MPSymQSMatrix()
|
|
{
|
|
}
|
|
|
|
//-------------------------------------------------------------------------//
|
|
|
|
void MPSymQSMatrix::checkArgs( MPError& )
|
|
{
|
|
m_matrix_row_max = m_matrix->rows()-1;
|
|
m_matrix_col_max = m_matrix->cols()-1;
|
|
if ( m_range.isEmpty() ) {
|
|
m_rows = m_matrix->rows();
|
|
m_cols = m_matrix->cols();
|
|
} else {
|
|
m_rows = m_range.height();
|
|
m_cols = m_range.width();
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------------------//
|
|
|
|
double MPSymQSMatrix::value( int row, int col )
|
|
{
|
|
return m_matrix->value( QMIN(row+m_range.top(), m_matrix_row_max ),
|
|
QMIN(col+m_range.left(), m_matrix_col_max ) );
|
|
}
|
|
|
|
//-------------------------------------------------------------------------//
|
|
|
|
|
|
|
|
|
|
|