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

/***************************************************************************
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() ) );
}
}