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.
818 lines
27 KiB
818 lines
27 KiB
/***************************************************************************
|
|
ksmatrixeditor.cpp
|
|
-------------------
|
|
begin :
|
|
copyright : (C) 2001 by Kamil Dobkowski
|
|
email : kamildbk@friko.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 "ksmatrixeditor.h"
|
|
#include "formula/mpformula.h"
|
|
#include "widgets/qsconsole.h"
|
|
#include "dialogs/kssheetdlgs.h"
|
|
#include "kscommands.h"
|
|
#include "ksworkbook.h"
|
|
#include "ksobjectfactory.h"
|
|
#include "ksdatasymbolfactory.h"
|
|
#include <qlineedit.h>
|
|
#include <qspinbox.h>
|
|
#include <qradiobutton.h>
|
|
#include <qstring.h>
|
|
#include <qcombobox.h>
|
|
#include <qmultilineedit.h>
|
|
#include <qapplication.h>
|
|
#include <qpopupmenu.h>
|
|
#include <qinputdialog.h>
|
|
#include <qmessagebox.h>
|
|
#include <qpainter.h>
|
|
#include <qcursor.h>
|
|
|
|
|
|
//--------------------------------------------------------------------//
|
|
//--------------------------------------------------------------------//
|
|
//--------------------------------------------------------------------//
|
|
//--------------------------------------------------------------------//
|
|
|
|
KSMatrixEditor::KSMatrixEditor( KSWorkbook *workbook, QSMatrix *matrix, QWidget *parent )
|
|
: QTable( matrix->rows(), matrix->cols(), parent ), KSMatrixEditorInterf()
|
|
{
|
|
m_workbook = workbook;
|
|
m_buffer = matrix;
|
|
m_editable = matrix->isEditable();
|
|
m_reference = matrix->isReference();
|
|
m_applying = false;
|
|
setSelectionMode( Single );
|
|
//updateContents();
|
|
|
|
connect( this, SIGNAL(pressed(int,int,int,const QPoint&)), this, SLOT(slot_button_pressed(int,int,int,const QPoint&)) );
|
|
}
|
|
|
|
//--------------------------------------------------------------------//
|
|
|
|
KSMatrixEditor::~KSMatrixEditor()
|
|
{
|
|
}
|
|
|
|
//--------------------------------------------------------------------//
|
|
|
|
void KSMatrixEditor::setSelectionRange( const QRect& rect )
|
|
{
|
|
QTableSelection selection;
|
|
selection.init( rect.top(), rect.left() );
|
|
selection.expandTo( rect.bottom(), rect.right() );
|
|
clearSelection();
|
|
if ( !rect.isEmpty() ) addSelection( selection );
|
|
}
|
|
|
|
//--------------------------------------------------------------------//
|
|
|
|
QRect KSMatrixEditor::selectionRange()
|
|
{
|
|
QRect result;
|
|
if ( numSelections() ) {
|
|
QTableSelection sel = selection(0);
|
|
result.setLeft( QMAX( sel.leftCol(), 0 ) );
|
|
result.setRight( QMIN( sel.rightCol(), m_buffer->cols()-1 ) );
|
|
result.setTop( QMAX( sel.topRow(), 0 ) );
|
|
result.setBottom( QMIN( sel.bottomRow(), m_buffer->rows()-1 ) );
|
|
}
|
|
return result;
|
|
}
|
|
|
|
//--------------------------------------------------------------------//
|
|
|
|
void KSMatrixEditor::updateContents()
|
|
{
|
|
if ( m_applying ) return;
|
|
|
|
setNumRows( m_buffer->rows() );
|
|
setNumCols( m_buffer->cols() );
|
|
QHeader *hh = horizontalHeader();
|
|
QHeader *vh = verticalHeader();
|
|
if ( m_buffer->rows() > 5000 ) vh->hide();
|
|
if ( m_buffer->cols() > 5000 ) hh->hide();
|
|
|
|
if ( numRows() > 5000 ) vh->hide();
|
|
else for ( int crow=0; crow<numRows(); crow++ ) if ( vh ) vh->setLabel( crow, QString::number(crow) );
|
|
if ( numCols() > 5000 ) hh->hide();
|
|
else for ( int ccol=0; ccol<numCols(); ccol++ ) if ( hh ) hh->setLabel( ccol, QString::number(ccol) );
|
|
|
|
//viewport()->update();
|
|
}
|
|
|
|
//--------------------------------------------------------------------//
|
|
|
|
QPoint KSMatrixEditor::editorContentsPos()
|
|
{
|
|
return QPoint( contentsX(), contentsY() );
|
|
}
|
|
|
|
//--------------------------------------------------------------------//
|
|
|
|
void KSMatrixEditor::setEditorContentsPos( const QPoint& pos )
|
|
{
|
|
setContentsPos( pos.x(), pos.y() );
|
|
}
|
|
|
|
//--------------------------------------------------------------------//
|
|
|
|
void KSMatrixEditor::setColumnTitles( const QStringList& list )
|
|
{
|
|
QHeader *hh = horizontalHeader();
|
|
for ( int ccol=0; ccol<(int )list.count(); ccol++ )
|
|
if ( hh && ccol<numCols() ) hh->setLabel( ccol, hh->label(ccol)+" ("+list[ccol]+")" );
|
|
}
|
|
|
|
//--------------------------------------------------------------------//
|
|
|
|
bool KSMatrixEditor::isValidCell( int row, int col ) const
|
|
{
|
|
return row < m_buffer->rows() && col < m_buffer->cols() && row >= 0 && col >= 0;
|
|
}
|
|
|
|
//--------------------------------------------------------------------//
|
|
|
|
QRect KSMatrixEditor::cellGeometry ( int row, int col ) const
|
|
{
|
|
return QTable::cellGeometry( row, col );
|
|
}
|
|
|
|
//--------------------------------------------------------------------//
|
|
|
|
void KSMatrixEditor::paintCell( QPainter *p, int row, int col, const QRect & cr, bool selected )
|
|
{
|
|
if ( isValidCell(row,col) ) {
|
|
QColor background = white;
|
|
QColor foreground = gray;
|
|
if ( m_editable ) foreground = black;
|
|
if ( m_reference ) foreground = blue;
|
|
if ( selected ) {
|
|
background = black;
|
|
foreground = white;
|
|
}
|
|
|
|
QRect r = cr;
|
|
r.moveBy( -cr.x(), -cr.y() );
|
|
p->fillRect( r, background );
|
|
p->setPen( gray );
|
|
p->drawLine( r.bottomLeft(), r.bottomRight() );
|
|
p->drawLine( r.bottomRight(), r.topRight() );
|
|
p->setPen( foreground );
|
|
p->drawText( r, AlignRight | AlignVCenter, m_buffer->string(row,col)+" " );
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------//
|
|
|
|
QWidget* KSMatrixEditor::createEditor ( int row, int col, bool initFromCell ) const
|
|
{
|
|
if ( isValidCell(row,col) && m_editable ) {
|
|
return new QLineEdit( initFromCell ? m_buffer->string(row,col) : QString::null, const_cast<KSMatrixEditor*>(this) );
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
//--------------------------------------------------------------------//
|
|
|
|
void KSMatrixEditor::setCellContentFromEditor ( int row, int col )
|
|
{;
|
|
if ( isValidCell(row,col) ) {
|
|
QLineEdit *e = dynamic_cast<QLineEdit*>(cellWidget(row,col));
|
|
if ( e && e->text() != m_buffer->string(row,col) ) {
|
|
m_applying = true;
|
|
m_workbook->execute( new KSCmdChangeValue( m_buffer,row,col,e->text() ) );
|
|
m_applying = false;
|
|
}
|
|
}
|
|
updateCell( row, col );
|
|
}
|
|
|
|
//--------------------------------------------------------------------//
|
|
|
|
void KSMatrixEditor::endEdit ( int row, int col, bool accept, bool )
|
|
{
|
|
QTable::endEdit ( row, col, accept, FALSE );
|
|
}
|
|
|
|
//--------------------------------------------------------------------//
|
|
|
|
void KSMatrixEditor::setItem ( int , int , QTableItem * )
|
|
{
|
|
}
|
|
|
|
//--------------------------------------------------------------------//
|
|
|
|
QTableItem* KSMatrixEditor::item( int, int ) const
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
//--------------------------------------------------------------------//
|
|
|
|
void KSMatrixEditor::resizeData ( int )
|
|
{
|
|
}
|
|
|
|
//--------------------------------------------------------------------//
|
|
|
|
QWidget *KSMatrixEditor::widget()
|
|
{
|
|
return this;
|
|
}
|
|
|
|
//--------------------------------------------------------------------//
|
|
|
|
void KSMatrixEditor::insertWidget( int row, int col, QWidget *w )
|
|
{
|
|
QTable::insertWidget(row,col,w);
|
|
}
|
|
|
|
//--------------------------------------------------------------------//
|
|
|
|
QWidget *KSMatrixEditor::cellWidget( int row, int col ) const
|
|
{
|
|
return QTable::cellWidget(row,col);
|
|
}
|
|
|
|
//--------------------------------------------------------------------//
|
|
|
|
void KSMatrixEditor::clearCellWidget( int row, int col )
|
|
{
|
|
QTable::clearCellWidget(row,col);
|
|
}
|
|
|
|
//--------------------------------------------------------------------//
|
|
|
|
void KSMatrixEditor::paintEmptyArea ( QPainter *, int, int, int, int )
|
|
{
|
|
}
|
|
//--------------------------------------------------------------------//
|
|
|
|
void KSMatrixEditor::slot_button_pressed( int, int, int button, const QPoint& )
|
|
{
|
|
if ( button == RightButton ) {
|
|
QPopupMenu *menu = new QPopupMenu( this );
|
|
int copy_id = menu->insertItem( tr("Copy") );
|
|
int paste_id = menu->insertItem( tr("Paste") );
|
|
menu->insertSeparator();
|
|
|
|
int select_range_id = menu->insertItem( tr("Select range") );
|
|
int statistics_id = menu->insertItem( tr("Statistics") );
|
|
menu->insertSeparator();
|
|
|
|
QPopupMenu *range_menu = new QPopupMenu( menu );
|
|
int menu_fill_range_id = menu->insertItem( tr("Fill selected range"), range_menu );
|
|
int range_value_id = range_menu->insertItem( tr("Value") );
|
|
int range_formula_id = range_menu->insertItem( tr("Formula") );
|
|
int range_uniform_id = range_menu->insertItem( tr("Uniform deviated random numbers") );
|
|
int rows_sequence_id = range_menu->insertItem( tr("Fill rows by monotone sequence") );
|
|
int cols_sequence_id = range_menu->insertItem( tr("Fill cols by monotone sequence") );
|
|
|
|
QPopupMenu *insert_menu = new QPopupMenu( menu );
|
|
int menu_insert_id = menu->insertItem( tr("Insert"), insert_menu );
|
|
int insert_row_before_id = insert_menu->insertItem( tr("Insert row before") );
|
|
int insert_row_after_id = insert_menu->insertItem( tr("Insert row after") );
|
|
int insert_col_before_id = insert_menu->insertItem( tr("Insert column before") );
|
|
int insert_col_after_id = insert_menu->insertItem( tr("Insert column after") );
|
|
|
|
QPopupMenu *remove_menu = new QPopupMenu( menu );
|
|
int menu_remove_id = menu->insertItem( tr("Remove"), remove_menu );
|
|
int remove_rows_id = remove_menu->insertItem( tr("Selected rows") );
|
|
int remove_cols_id = remove_menu->insertItem( tr("Selected cols") );
|
|
|
|
if ( selectionRange().isEmpty() ) {
|
|
menu->setItemEnabled( copy_id, false );
|
|
menu->setItemEnabled( paste_id, false );
|
|
menu->setItemEnabled( statistics_id, false );
|
|
menu->setItemEnabled( menu_fill_range_id, false );
|
|
menu->setItemEnabled( rows_sequence_id, false );
|
|
menu->setItemEnabled( cols_sequence_id, false );
|
|
menu->setItemEnabled( menu_insert_id, false );
|
|
menu->setItemEnabled( menu_remove_id, false );
|
|
}
|
|
|
|
int item_id = menu->exec(QCursor::pos());
|
|
delete menu;
|
|
|
|
if ( item_id == copy_id ) {
|
|
slotCopy();
|
|
}
|
|
else if ( item_id == paste_id ) {
|
|
slotPaste();
|
|
}
|
|
else if ( item_id == statistics_id ) {
|
|
slotStatistics();
|
|
}
|
|
else if ( item_id == select_range_id ) {
|
|
slotSelectRange();
|
|
}
|
|
else if ( item_id == range_value_id ) {
|
|
slotFillRangeWithValue();
|
|
}
|
|
else if ( item_id == range_formula_id ) {
|
|
slotFillRangeWithFormula();
|
|
}
|
|
else if ( item_id == range_uniform_id ) {
|
|
slotFillRangeWithUniformNoise();
|
|
}
|
|
else if ( item_id == rows_sequence_id ) {
|
|
slotFillRowsMonotone();
|
|
}
|
|
else if ( item_id == cols_sequence_id ) {
|
|
slotFillColsMonotone();
|
|
}
|
|
else if ( item_id == insert_row_before_id ) {
|
|
slotInsertRowBefore();
|
|
}
|
|
else if ( item_id == insert_row_after_id ) {
|
|
slotInsertRowAfter();
|
|
}
|
|
else if ( item_id == insert_col_before_id ) {
|
|
slotInsertColBefore();
|
|
}
|
|
else if ( item_id == insert_col_after_id ) {
|
|
slotInsertColAfter();
|
|
}
|
|
else if ( item_id == remove_rows_id ) {
|
|
slotRemoveRows();
|
|
}
|
|
else if ( item_id == remove_cols_id ) {
|
|
slotRemoveCols();
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------//
|
|
|
|
void KSMatrixEditor::slotCopy()
|
|
{
|
|
QRect sel = selectionRange();
|
|
if ( !sel.isEmpty() ) {
|
|
KSObjectFactory factory( m_workbook );
|
|
QSMatrix *selection = factory.cloneMatrix( m_buffer, false );
|
|
selection->resize( sel.height(), sel.width() );
|
|
selection->copyRange( 0, 0, m_buffer, sel.top(), sel.left(), sel.bottom(), sel.right() );
|
|
factory.copyQSMatrixToClipboard( selection );
|
|
delete selection;
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------//
|
|
|
|
void KSMatrixEditor::slotPaste()
|
|
{
|
|
QRect sel = selectionRange();
|
|
if ( !sel.isEmpty() ) {
|
|
KSObjectFactory factory( m_workbook );
|
|
QSMatrix *clipboard_data = factory.pasteQSMatrixFromClipboard();
|
|
if ( clipboard_data ) {
|
|
KSCmdChangeData *cmd = new KSCmdChangeData( m_buffer, sel.top(), sel.left(), sel.bottom(), sel.right() );
|
|
m_buffer->copyRange( sel.top(), sel.left(), clipboard_data, 0, 0, QMIN(clipboard_data->rows()-1,sel.height()-1), QMIN(clipboard_data->cols()-1,sel.width()-1) );
|
|
delete clipboard_data;
|
|
m_workbook->execute( cmd );
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
//--------------------------------------------------------------------//
|
|
|
|
bool KSMatrixEditor::isFilledSelectedCell( int row, int col )
|
|
{
|
|
return isSelected(row,col) && ( !m_buffer->isString() || !m_buffer->string(row,col).isEmpty() );
|
|
}
|
|
|
|
//--------------------------------------------------------------------//
|
|
|
|
void KSMatrixEditor::slotStatistics()
|
|
// put statistics into a separate class some day
|
|
{
|
|
int p_cells = 0;
|
|
|
|
QRect sel = selectionRange();
|
|
if ( sel.isEmpty() ) return;
|
|
|
|
////////////////////////////////////////////
|
|
// find min, max, mean, geometrical mean //
|
|
////////////////////////////////////////////
|
|
double p_min;
|
|
double p_max;
|
|
double p_sum = 0.0;
|
|
double p_product = 1.0;
|
|
for( int row=sel.top(); row<=sel.bottom(); row++ )
|
|
for( int col=sel.left(); col<=sel.right(); col ++ ) if ( isFilledSelectedCell(row,col) ) {
|
|
double value = m_buffer->value(row,col);
|
|
p_cells = p_cells+1;
|
|
if ( p_cells == 1 ) p_min = p_max = value;
|
|
p_product *= value;
|
|
p_sum = p_sum + value;
|
|
p_min = QMIN( p_min, value );
|
|
p_max = QMAX( p_max, value );
|
|
}
|
|
double p_mean = p_sum/p_cells;
|
|
double p_geom_mean = pow( p_product, 1.0/p_cells );
|
|
|
|
//////////////////////////////////////////////////////////
|
|
// find variance, standard deviation, average deviation //
|
|
//////////////////////////////////////////////////////////
|
|
double p_dev_sum_sqrt = 0.0;
|
|
double p_dev_sum_abs = 0.0;
|
|
for( int row=sel.top(); row<=sel.bottom(); row++ )
|
|
for( int col=sel.left(); col<=sel.right(); col ++ ) if ( isFilledSelectedCell(row,col) ) {
|
|
double value = m_buffer->value(row,col);
|
|
p_dev_sum_sqrt += (value-p_mean)*(value-p_mean);
|
|
p_dev_sum_abs += fabs(value-p_mean);
|
|
}
|
|
|
|
double p_variance = p_dev_sum_sqrt / QMAX(p_cells-1.0,1.0);
|
|
double p_avg_dev = p_dev_sum_abs / p_cells;
|
|
double p_std_dev = sqrt(p_variance);
|
|
|
|
//////////////////////////////////////////////////////////
|
|
// find skewness //
|
|
//////////////////////////////////////////////////////////
|
|
double p_dev_sum_third = 0.0;
|
|
if ( p_std_dev != 0.0 )
|
|
for( int row=sel.top(); row<=sel.bottom(); row++ )
|
|
for( int col=sel.left(); col<=sel.right(); col ++ ) if ( isFilledSelectedCell(row,col) ) {
|
|
double value = m_buffer->value(row,col);
|
|
p_dev_sum_third += pow( (value-p_mean)/p_std_dev, 3.0 );
|
|
}
|
|
double p_skewness = p_dev_sum_third/p_cells;
|
|
|
|
if ( p_cells > 0 ) {
|
|
QString info;
|
|
info += "<table border=1 cellspacing=1>";
|
|
info += tr("<tr><td> Numbers count </td><td>%1</td></tr>").arg(p_cells);
|
|
info += tr("<tr><td> Minimum </td><td> %1 </td></tr> ").arg(p_min,0,'g',9);
|
|
info += tr("<tr><td> Maximum </td><td> %1 </td></tr>").arg(p_max,0,'g',9);
|
|
info += tr("<tr><td> Sum </td><td> %1 </td></tr>").arg(p_sum,0,'g',9);
|
|
info += tr("<tr><td> Product </td><td> %1 </td></tr>").arg(p_product,0,'g',9);
|
|
info += tr("<tr><td> Geometrical mean </td><td> %1 </td></tr>").arg(p_geom_mean,0,'g',9);
|
|
info += tr("<tr><td> Mean </td><td> %1 </td></tr>").arg(p_mean,0,'g',9);
|
|
info += tr("<tr><td> Variance </td><td> %1 </td></tr>").arg(p_variance,0,'g',9);
|
|
info += tr("<tr><td> Standard deviation </td><td> %1 </td></tr>").arg(p_std_dev,0,'g',9);
|
|
info += tr("<tr><td> Average deviation = 1/N * SUM[ABS(Xn-Xmean)] </td><td> %1 </td></tr>").arg(p_avg_dev,0,'g',9);
|
|
info += tr("<tr><td> Skewness </td><td> %1 </td></tr>").arg(p_skewness,0,'g',9);
|
|
info += "</table>";
|
|
|
|
QMessageBox::information( NULL, " Statistics of selected cells : ", info );
|
|
QSConsole::write( info );
|
|
}
|
|
}
|
|
|
|
/*
|
|
info += tr(" Numbers count: %1 \n").arg(p_cells);
|
|
info += tr(" Minimum : %1 \n").arg(p_min,0,'g',9);
|
|
info += tr(" Maximum : %1 \n").arg(p_max,0,'g',9);
|
|
info += tr(" Sum : %1 \n").arg(p_sum,0,'g',9);
|
|
info += tr(" Product : %1 \n").arg(p_product,0,'g',9);
|
|
info += tr(" Geometrical mean : %1 \n").arg(p_geom_mean,0,'g',9);
|
|
info += "\n";
|
|
info += tr(" Mean : %1 \n").arg(p_mean,0,'g',9);
|
|
info += tr(" Variance : %1 \n").arg(p_variance,0,'g',9);
|
|
info += tr(" Standard deviation : %1 \n").arg(p_std_dev,0,'g',9);
|
|
info += tr(" Average deviation = 1/N * SUM[ABS(Xn-Xmean)] : %1 \n").arg(p_avg_dev,0,'g',9);
|
|
info += tr(" Skewness : %1 \n").arg(p_skewness,0,'g',9);
|
|
QMessageBox::information( NULL, " Statistics of selected cells : ", info );
|
|
*/
|
|
//--------------------------------------------------------------------//
|
|
|
|
void KSMatrixEditor::slotSelectRange()
|
|
{
|
|
KSSheetDlgCellRange dlg( this );
|
|
if ( dlg.exec() == QDialog::Accepted ) {
|
|
QTableSelection selection;
|
|
selection.init( dlg.rowFrom->value(), dlg.colFrom->value() );
|
|
selection.expandTo( dlg.rowTo->value(), dlg.colTo->value() );
|
|
addSelection( selection );
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------//
|
|
|
|
void KSMatrixEditor::slotFillRangeWithValue()
|
|
{
|
|
bool isOK = false;
|
|
QString value = QInputDialog::getText( tr( "Fill selection with value" ), tr( "Enter value: " ), QLineEdit::Normal, QString::null, &isOK, this );
|
|
QRect sel = selectionRange();
|
|
if ( isOK && !sel.isEmpty() ) {
|
|
KSCmdChangeData *cmd = new KSCmdChangeData( m_buffer, sel.top(), sel.left(), sel.bottom(), sel.right() );
|
|
for( int row=sel.top(); row<=sel.bottom(); row++ )
|
|
for( int col=sel.left(); col<=sel.right(); col++ ) {
|
|
m_buffer->setString( row, col, value );
|
|
}
|
|
m_applying = true;
|
|
m_workbook->execute( cmd );
|
|
m_applying = false;
|
|
//viewport()->update();
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------//
|
|
|
|
void KSMatrixEditor::slotFillRangeWithFormula()
|
|
{
|
|
bool isOK = false;
|
|
QString formula_string = QInputDialog::getText( tr( "Fill selection with formula" ), "selection=", QLineEdit::Normal, QString::null, &isOK, this );
|
|
QRect sel = selectionRange();
|
|
if ( isOK && !sel.isEmpty() ) {
|
|
|
|
// local variables
|
|
KSDataSymbolFactory *locals = new KSDataSymbolFactory( m_workbook, m_buffer->dataObject() );
|
|
locals->setSelection( m_buffer, sel );
|
|
|
|
MPFormula f;
|
|
MPFormulaError error;
|
|
MPFactoryList factory( locals );
|
|
MPSymbol *expr = f.parse( formula_string, error, &factory );
|
|
if ( expr ) {
|
|
KSCmdChangeData *cmd = new KSCmdChangeData( m_buffer, sel.top(), sel.left(), sel.bottom(), sel.right() );
|
|
for( int row=sel.top(); row<=sel.bottom(); row++ )
|
|
for( int col=sel.left(); col<=sel.right(); col++ ) {
|
|
int expr_row = row - sel.top();
|
|
int expr_col = col - sel.left();
|
|
if ( expr_col < expr->cols() &&
|
|
expr_row < expr->rows() ||
|
|
expr->isScalar() ) {
|
|
m_buffer->setValue( row, col, expr->value( expr_row, expr_col ) );
|
|
}
|
|
}
|
|
m_applying = true;
|
|
m_workbook->execute( cmd );
|
|
m_applying = false;
|
|
//viewport()->update();
|
|
delete expr;
|
|
} else {
|
|
QMessageBox::critical( NULL, tr("Error"), error.message(), QMessageBox::Ok, 0 );
|
|
}
|
|
}
|
|
}
|
|
//--------------------------------------------------------------------//
|
|
|
|
void KSMatrixEditor::slotFillRangeWithUniformNoise()
|
|
{
|
|
KSSheetDlgValueRange dlg( this );
|
|
dlg.setMinValue( 0.0 );
|
|
dlg.setMaxValue( 1.0 );
|
|
QRect sel = selectionRange();
|
|
if ( dlg.exec() == QDialog::Accepted && !sel.isEmpty() ) {
|
|
double min_value = dlg.minValue();
|
|
double max_value = dlg.maxValue();
|
|
KSCmdChangeData *cmd = new KSCmdChangeData( m_buffer, sel.top(), sel.left(), sel.bottom(), sel.right() );
|
|
for( int row=sel.top(); row<=sel.bottom(); row++ )
|
|
for( int col=sel.left(); col<=sel.right(); col++ ) {
|
|
m_buffer->setValue(row,col,min_value+double(rand())/(RAND_MAX+1.0)*(max_value-min_value));
|
|
}
|
|
m_applying = true;
|
|
m_workbook->execute( cmd );
|
|
m_applying = false;
|
|
//viewport()->update();
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------//
|
|
|
|
void KSMatrixEditor::slotFillRowsMonotone()
|
|
{
|
|
KSSheetDlgSequence dlg( this );
|
|
QRect sel = selectionRange();
|
|
if ( dlg.exec() == QDialog::Accepted && !sel.isEmpty() ) {
|
|
int elements = sel.right() - sel.left() + 1;
|
|
double start_value = dlg.from();
|
|
double step_value = dlg.useStep() ? dlg.to() : (dlg.to()-dlg.from())/(elements-1.0);
|
|
|
|
KSCmdChangeData *cmd = new KSCmdChangeData( m_buffer, sel.top(), sel.left(), sel.bottom(), sel.right() );
|
|
|
|
for( int row=sel.top(); row<=sel.bottom(); row++ ) {
|
|
double curr_value = start_value;
|
|
if ( !dlg.reversedDirection() ) {
|
|
for( int col=sel.left(); col<=sel.right(); col++, curr_value+=step_value )
|
|
if ( isValidCell(row,col) ) m_buffer->setValue(row,col,curr_value);
|
|
} else {
|
|
for( int col=sel.right(); col>=sel.left(); col--, curr_value+=step_value )
|
|
if ( isValidCell(row,col) ) m_buffer->setValue(row,col,curr_value);
|
|
}
|
|
}
|
|
m_applying = true;
|
|
m_workbook->execute( cmd );
|
|
m_applying = false;
|
|
//viewport()->update();
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------//
|
|
|
|
void KSMatrixEditor::slotFillColsMonotone()
|
|
{
|
|
KSSheetDlgSequence dlg( this );
|
|
QRect sel = selectionRange();
|
|
if ( dlg.exec() == QDialog::Accepted && !sel.isEmpty() ) {
|
|
KSCmdChangeData *cmd = new KSCmdChangeData( m_buffer, sel.top(), sel.left(), sel.bottom(), sel.right() );
|
|
int elements = sel.bottom() - sel.top() + 1;
|
|
double start_value = dlg.from();
|
|
double step_value = dlg.useStep() ? dlg.to() : (dlg.to()-dlg.from())/(elements-1.0);
|
|
for( int col=sel.left(); col<=sel.right(); col++ ) {
|
|
double curr_value = start_value;
|
|
if ( !dlg.reversedDirection() ) {
|
|
for( int row=sel.top(); row<=sel.bottom(); row++, curr_value+=step_value )
|
|
if ( isValidCell(row,col) ) m_buffer->setValue(row,col,curr_value);
|
|
} else {
|
|
for( int row=sel.bottom(); row>=sel.top(); row--, curr_value+=step_value )
|
|
if ( isValidCell(row,col) ) m_buffer->setValue(row,col,curr_value);
|
|
}
|
|
}
|
|
m_applying = true;
|
|
m_workbook->execute( cmd );
|
|
m_applying = false;
|
|
//viewport()->update();
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------//
|
|
|
|
void KSMatrixEditor::slotInsertRowBefore()
|
|
{
|
|
QRect sel = selectionRange();
|
|
if ( sel.width() == m_buffer->cols() ) {
|
|
m_workbook->execute( new KSCmdInsertRow( m_buffer, sel.top() ) );
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------//
|
|
|
|
void KSMatrixEditor::slotInsertRowAfter()
|
|
{
|
|
QRect sel = selectionRange();
|
|
if ( sel.width() == m_buffer->cols() ) {
|
|
m_workbook->execute( new KSCmdInsertRow( m_buffer, sel.bottom()+1 ) );
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------//
|
|
|
|
void KSMatrixEditor::slotInsertColBefore()
|
|
{
|
|
QRect sel = selectionRange();
|
|
if ( sel.height() == m_buffer->rows() ) {
|
|
m_workbook->execute( new KSCmdInsertCol( m_buffer, sel.left() ) );
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------//
|
|
|
|
void KSMatrixEditor::slotInsertColAfter()
|
|
{
|
|
QRect sel = selectionRange();
|
|
if ( sel.height() == m_buffer->rows() ) {
|
|
m_workbook->execute( new KSCmdInsertCol( m_buffer, sel.right()+1 ) );
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------//
|
|
|
|
void KSMatrixEditor::slotRemoveRows()
|
|
// TODO : end edit
|
|
{
|
|
QRect sel = selectionRange();
|
|
if ( sel.width() == m_buffer->cols() ) {
|
|
m_workbook->execute( new KSCmdRemoveRows( m_buffer, sel.top(), sel.bottom() ) );
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------//
|
|
|
|
void KSMatrixEditor::slotRemoveCols()
|
|
// TODO :: end edit
|
|
{
|
|
QRect sel = selectionRange();
|
|
if ( sel.height() == m_buffer->rows() ) {
|
|
m_workbook->execute( new KSCmdRemoveCols( m_buffer, sel.left(), sel.right() ) );
|
|
}
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------//
|
|
//--------------------------------------------------------------------//
|
|
//--------------------------------------------------------------------//
|
|
//--------------------------------------------------------------------//
|
|
//--------------------------------------------------------------------//
|
|
//--------------------------------------------------------------------//
|
|
|
|
|
|
KSMatrixSheetEditor::KSMatrixSheetEditor( KSWorkbook *workbook, KSSheet *sheet, QWidget *parent )
|
|
: KSMatrixEditor( workbook, sheet->matrix(0), parent )
|
|
{
|
|
m_sheet = sheet;
|
|
horizontalHeader()->installEventFilter( this );
|
|
}
|
|
|
|
//--------------------------------------------------------------------//
|
|
|
|
KSMatrixSheetEditor::~KSMatrixSheetEditor()
|
|
{
|
|
}
|
|
|
|
//--------------------------------------------------------------------//
|
|
|
|
void KSMatrixSheetEditor::updateContents()
|
|
{
|
|
if ( m_applying ) return;
|
|
KSMatrixEditor::updateContents();
|
|
makeHeaders();
|
|
}
|
|
|
|
//--------------------------------------------------------------------//
|
|
|
|
bool KSMatrixSheetEditor::eventFilter ( QObject *o, QEvent *e )
|
|
{
|
|
if ( o == horizontalHeader() && e->type() == QEvent::MouseButtonDblClick ) {
|
|
int x = static_cast<QMouseEvent*>(e)->pos().x()+contentsX();
|
|
headerDoubleClick( columnAt(x) );
|
|
return TRUE;
|
|
}
|
|
return KSMatrixEditor::eventFilter( o, e );
|
|
}
|
|
|
|
//--------------------------------------------------------------------//
|
|
|
|
void KSMatrixSheetEditor::headerDoubleClick( int column )
|
|
{
|
|
KSSheetDlgColData dlg( this, m_sheet, column, 1, column );
|
|
if ( dlg.exec() == QDialog::Accepted ) {
|
|
dlg.apply();
|
|
makeHeaders();
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------//
|
|
|
|
void KSMatrixSheetEditor::makeHeaders()
|
|
{
|
|
QHeader *hh = horizontalHeader();
|
|
if ( numCols() > 5000 ) hh->hide(); else for ( int ccol=0; ccol<numCols(); ccol++ ) if ( hh ) hh->setLabel( ccol, QString::number(ccol) );
|
|
const KSSheet::ColumnInfo *headers;
|
|
KSSheet::ColumnInfo::ConstIterator curr;
|
|
headers = m_sheet->columnInfo();
|
|
for( curr = headers->begin(); curr != headers->end(); ++curr ) {
|
|
QString col_type;
|
|
switch( curr.data().type ) {
|
|
case KSSheet::ColumnX: col_type=" (X)"; break;
|
|
case KSSheet::ColumnY: col_type=" (Y)"; break;
|
|
case KSSheet::ColumnZ: col_type=" (Z)"; break;
|
|
case KSSheet::ColumnV: col_type=" (V)"; break;
|
|
case KSSheet::ColumnDX: col_type=" (DX)"; break;
|
|
case KSSheet::ColumnDY: col_type=" (DY)"; break;
|
|
default: break;
|
|
}
|
|
QString title = hh->label(curr.key())+col_type;
|
|
if ( !curr.data().title.isEmpty() ) title += " - "+curr.data().title;
|
|
hh->setLabel( curr.key(), title );
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------//
|
|
|
|
void KSMatrixSheetEditor::slotInsertColBefore()
|
|
{
|
|
QRect sel = selectionRange();
|
|
if ( sel.height() == m_buffer->rows() ) {
|
|
m_workbook->execute( new KSCmdInsertSheetCol( m_sheet, sel.left() ) );
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------//
|
|
|
|
void KSMatrixSheetEditor::slotInsertColAfter()
|
|
{
|
|
QRect sel = selectionRange();
|
|
if ( sel.height() == m_buffer->rows() ) {
|
|
m_workbook->execute( new KSCmdInsertSheetCol( m_sheet, sel.right()+1 ) );
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------//
|
|
|
|
void KSMatrixSheetEditor::slotRemoveCols()
|
|
// TODO :: end edit
|
|
{
|
|
QRect sel = selectionRange();
|
|
if ( sel.height() == m_buffer->rows() ) {
|
|
m_workbook->execute( new KSCmdRemoveSheetCols( m_sheet, sel.left(), sel.right() ) );
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|