/***************************************************************************
* Copyright ( C ) 2005 by Niklas Knutsson *
* nq @ altern . org *
* *
* 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 . *
* *
* This program is distributed in the hope that it will be useful , *
* but WITHOUT ANY WARRANTY ; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the *
* GNU General Public License for more details . *
* *
* You should have received a copy of the GNU General Public License *
* along with this program ; if not , write to the *
* Free Software Foundation , Inc . , *
* 59 Temple Place - Suite 330 , Boston , MA 02111 - 1307 , USA . *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include "qalculateeditmatrixvectordialog.h"
# include "qalculate_tde_utils.h"
# include "qalculateeditnamesdialog.h"
# include <string>
# include <tqgrid.h>
# include <klineedit.h>
# include <tqpushbutton.h>
# include <kcombobox.h>
# include <tqlabel.h>
# include <tdelocale.h>
# include <tqvbox.h>
# include <tqhbox.h>
# include <tqcheckbox.h>
# include <tdemessagebox.h>
# include <tqspinbox.h>
# include <tqlayout.h>
# include <tqbuttongroup.h>
# include <tqradiobutton.h>
# include <tqtable.h>
# include <tdeapplication.h>
extern PrintOptions printops ;
extern EvaluationOptions evalops ;
extern tree_struct variable_cats ;
class QalculateEditMatrixVectorTableItem : public TQTableItem {
public :
QalculateEditMatrixVectorTableItem ( TQTable * table ) ;
QalculateEditMatrixVectorTableItem ( TQTable * table , const TQString & text ) ;
int alignment ( ) const ;
} ;
class QalculateEditMatrixTable : public TQTable {
public :
QalculateEditMatrixTable ( TQWidget * parent = 0 , const char * name = 0 ) : TQTable ( parent , name ) { }
QalculateEditMatrixTable ( int numRows , int numCols , TQWidget * parent = 0 , const char * name = 0 ) : TQTable ( numRows , numCols , parent , name ) { }
TQWidget * beginEdit ( int row , int col , bool replace ) {
TQWidget * w = TQTable : : beginEdit ( row , col , replace ) ;
( ( TQLineEdit * ) w ) - > selectAll ( ) ;
return w ;
}
} ;
QalculateEditMatrixVectorDialog : : QalculateEditMatrixVectorDialog ( TQWidget * parent , const char * name ) : KDialogBase ( parent , name , true , i18n ( " Edit Variable " ) , Ok | Cancel | Help , Ok , true ) {
names_edit_dialog = NULL ;
edited_variable = NULL ;
setMainWidget ( new TQWidget ( this ) ) ;
TQGridLayout * grid = new TQGridLayout ( mainWidget ( ) , 1 , 1 , 0 , spacingHint ( ) ) ;
grid - > addWidget ( new TQLabel ( i18n ( " Name: " ) , mainWidget ( ) ) , 0 , 0 ) ;
nameEdit = new KLineEdit ( mainWidget ( ) ) ;
grid - > addWidget ( nameEdit , 0 , 1 ) ;
TQHBoxLayout * hbox = new TQHBoxLayout ( 0 , 0 , spacingHint ( ) ) ;
grid - > addMultiCellLayout ( hbox , 1 , 1 , 0 , 1 ) ;
namesLabel = new TQLabel ( mainWidget ( ) ) ;
namesLabel - > setAlignment ( TQt : : AlignRight ) ;
namesLabel - > setSizePolicy ( TQSizePolicy : : Expanding , TQSizePolicy : : Preferred ) ;
hbox - > addWidget ( namesLabel ) ;
namesButton = new TQPushButton ( i18n ( " Names Details " ) , mainWidget ( ) ) ;
hbox - > addWidget ( namesButton ) ;
grid - > addWidget ( new TQLabel ( i18n ( " Category: " ) , mainWidget ( ) ) , 2 , 0 ) ;
categoryCombo = new KComboBox ( mainWidget ( ) ) ;
categoryCombo - > setEditable ( true ) ;
grid - > addWidget ( categoryCombo , 2 , 1 ) ;
grid - > addWidget ( new TQLabel ( i18n ( " Descriptive name: " ) , mainWidget ( ) ) , 3 , 0 ) ;
titleEdit = new KLineEdit ( mainWidget ( ) ) ;
grid - > addWidget ( titleEdit , 3 , 1 ) ;
grid - > addWidget ( new TQLabel ( i18n ( " Rows: " ) , mainWidget ( ) ) , 4 , 0 ) ;
rowsBox = new TQSpinBox ( 1 , 1000 , 1 , mainWidget ( ) ) ;
grid - > addWidget ( rowsBox , 4 , 1 ) ;
grid - > addWidget ( new TQLabel ( i18n ( " Columns: " ) , mainWidget ( ) ) , 5 , 0 ) ;
columnsBox = new TQSpinBox ( 1 , 1000 , 1 , mainWidget ( ) ) ;
grid - > addWidget ( columnsBox , 5 , 1 ) ;
hbox = new TQHBoxLayout ( 0 , 0 , spacingHint ( ) ) ;
grid - > addMultiCellLayout ( hbox , 6 , 6 , 0 , 1 ) ;
hbox - > addItem ( new TQSpacerItem ( 0 , 0 , TQSizePolicy : : Expanding , TQSizePolicy : : Minimum ) ) ;
TQButtonGroup * group = new TQButtonGroup ( ) ;
matrixButton = new TQRadioButton ( i18n ( " Matrix " ) , mainWidget ( ) ) ;
group - > insert ( matrixButton , 0 ) ;
hbox - > addWidget ( matrixButton ) ;
vectorButton = new TQRadioButton ( i18n ( " Vector " ) , mainWidget ( ) ) ;
group - > insert ( vectorButton , 1 ) ;
hbox - > addWidget ( vectorButton ) ;
elementsLabel = new TQLabel ( i18n ( " Elements: " ) , mainWidget ( ) ) ;
grid - > addMultiCellWidget ( elementsLabel , 7 , 7 , 0 , 1 ) ;
elementsTable = new QalculateEditMatrixTable ( 0 , 0 , mainWidget ( ) ) ;
grid - > addMultiCellWidget ( elementsTable , 8 , 8 , 0 , 1 ) ;
connect ( namesButton , SIGNAL ( clicked ( ) ) , this , SLOT ( editNames ( ) ) ) ;
connect ( nameEdit , SIGNAL ( textChanged ( const TQString & ) ) , this , SLOT ( nameChanged ( const TQString & ) ) ) ;
connect ( rowsBox , SIGNAL ( valueChanged ( int ) ) , this , SLOT ( rowsChanged ( int ) ) ) ;
connect ( columnsBox , SIGNAL ( valueChanged ( int ) ) , this , SLOT ( columnsChanged ( int ) ) ) ;
connect ( group , SIGNAL ( clicked ( int ) ) , this , SLOT ( typeChanged ( int ) ) ) ;
}
QalculateEditMatrixVectorDialog : : ~ QalculateEditMatrixVectorDialog ( ) { }
void QalculateEditMatrixVectorDialog : : slotHelp ( ) {
TDEApplication : : kApplication ( ) - > invokeHelp ( " qalculate-vectors-matrices " ) ;
}
void QalculateEditMatrixVectorDialog : : typeChanged ( int i ) {
if ( i = = 0 ) {
elementsLabel - > setText ( i18n ( " Elements: " ) ) ;
bool b = true ;
for ( int index_r = elementsTable - > numRows ( ) - 1 ; index_r > = 0 & & b ; index_r - - ) {
for ( int index_c = elementsTable - > numCols ( ) - 1 ; index_c > = 0 ; index_c - - ) {
if ( elementsTable - > text ( index_r , index_c ) . isEmpty ( ) ) {
elementsTable - > setText ( index_r , index_c , " 0 " ) ;
} else {
b = false ;
break ;
}
}
}
} else {
elementsLabel - > setText ( i18n ( " Elements (in horizontal order): " ) ) ;
}
}
void QalculateEditMatrixVectorDialog : : rowsChanged ( int i ) {
int r = elementsTable - > numRows ( ) ;
elementsTable - > setNumRows ( i ) ;
bool b = matrixButton - > isChecked ( ) ;
for ( int index_r = r ; index_r < i ; index_r + + ) {
for ( int index_c = 0 ; index_c < elementsTable - > numCols ( ) ; index_c + + ) {
if ( b ) elementsTable - > setItem ( index_r , index_c , new QalculateEditMatrixVectorTableItem ( elementsTable , " 0 " ) ) ;
else elementsTable - > setItem ( index_r , index_c , new QalculateEditMatrixVectorTableItem ( elementsTable ) ) ;
}
}
}
void QalculateEditMatrixVectorDialog : : columnsChanged ( int i ) {
int c = elementsTable - > numCols ( ) ;
elementsTable - > setNumCols ( i ) ;
bool b = matrixButton - > isChecked ( ) ;
for ( int index_r = 0 ; index_r < elementsTable - > numRows ( ) ; index_r + + ) {
for ( int index_c = c ; index_c < i ; index_c + + ) {
if ( b ) elementsTable - > setItem ( index_r , index_c , new QalculateEditMatrixVectorTableItem ( elementsTable , " 0 " ) ) ;
else elementsTable - > setItem ( index_r , index_c , new QalculateEditMatrixVectorTableItem ( elementsTable ) ) ;
}
}
}
KnownVariable * QalculateEditMatrixVectorDialog : : newVector ( TQString category ) {
return editVariable ( category , NULL , NULL , false , true ) ;
}
KnownVariable * QalculateEditMatrixVectorDialog : : newMatrix ( TQString category ) {
return editVariable ( category , NULL , NULL , false , false ) ;
}
void QalculateEditMatrixVectorDialog : : slotOk ( ) {
std : : string str = nameEdit - > text ( ) . ascii ( ) ;
remove_blank_ends ( str ) ;
if ( str . empty ( ) & & ( ! names_edit_dialog | | names_edit_dialog - > isEmpty ( ) ) ) {
//no name -- open dialog again
nameEdit - > setFocus ( ) ;
KMessageBox : : error ( this , i18n ( " Empty name field " ) ) ;
return ;
}
//variable with the same name exists -- overwrite or open dialog again
if ( ( ! edited_variable | | ! edited_variable - > hasName ( str ) ) & & ( ! names_edit_dialog | | names_edit_dialog - > isEmpty ( ) ) & & CALCULATOR - > variableNameTaken ( str , edited_variable ) & & KMessageBox : : questionYesNo ( this , i18n ( " An unit or variable with the same name already exists. \n Do you want to overwrite it? " ) ) = = KMessageBox : : No ) {
nameEdit - > setFocus ( ) ;
return ;
}
KnownVariable * v = edited_variable ;
if ( ! v ) {
//no need to create a new variable when a variable with the same name exists
Variable * var = CALCULATOR - > getActiveVariable ( str ) ;
if ( var & & var - > isLocal ( ) & & var - > isKnown ( ) ) v = ( KnownVariable * ) var ;
}
MathStructure mstruct_new ;
if ( ! init_value ) {
int r = rowsBox - > value ( ) ;
int c = columnsBox - > value ( ) ;
if ( vectorButton - > isChecked ( ) ) {
mstruct_new . clearVector ( ) ;
std : : string str2 ;
for ( int index_r = 0 ; index_r < r ; index_r + + ) {
for ( int index_c = 0 ; index_c < c ; index_c + + ) {
if ( ! elementsTable - > text ( index_r , index_c ) . isEmpty ( ) ) {
str2 = elementsTable - > text ( index_r , index_c ) . ascii ( ) ;
remove_blank_ends ( str2 ) ;
if ( ! str2 . empty ( ) ) {
mstruct_new . addChild ( CALCULATOR - > calculate ( CALCULATOR - > unlocalizeExpression ( str2 , evalops . parse_options ) ) ) ;
}
}
}
}
} else {
mstruct_new . clearMatrix ( ) ;
mstruct_new . resizeMatrix ( r , c , m_undefined ) ;
for ( int index_r = 0 ; index_r < r ; index_r + + ) {
for ( int index_c = 0 ; index_c < c ; index_c + + ) {
if ( elementsTable - > text ( index_r , index_c ) . isEmpty ( ) ) mstruct_new . setElement ( m_zero , index_r + 1 , index_c + 1 ) ;
else mstruct_new . setElement ( CALCULATOR - > calculate ( CALCULATOR - > unlocalizeExpression ( elementsTable - > text ( index_r , index_c ) . ascii ( ) , evalops . parse_options ) ) , index_r + 1 , index_c + 1 ) ;
}
}
}
}
bool add_var = false ;
if ( v ) {
//update existing variable
v - > setLocal ( true ) ;
if ( ! v - > isBuiltin ( ) ) {
if ( init_value ) {
v - > set ( * init_value ) ;
} else {
v - > set ( mstruct_new ) ;
}
}
} else {
//new variable
if ( force_init_value & & init_value ) {
//forced value
v = new KnownVariable ( " " , " " , * init_value , " " , true ) ;
} else {
v = new KnownVariable ( " " , " " , mstruct_new , " " , true ) ;
}
add_var = true ;
}
v - > setCategory ( categoryCombo - > lineEdit ( ) - > text ( ) . ascii ( ) ) ;
v - > setTitle ( titleEdit - > text ( ) . ascii ( ) ) ;
if ( ! v - > isBuiltin ( ) ) {
if ( names_edit_dialog ) {
names_edit_dialog - > saveNames ( v , str . c_str ( ) ) ;
} else {
if ( v - > countNames ( ) = = 0 ) {
ExpressionName ename ( str ) ;
ename . reference = true ;
v - > setName ( ename , 1 ) ;
} else {
v - > setName ( str , 1 ) ;
}
}
}
if ( add_var ) {
CALCULATOR - > addVariable ( v ) ;
}
edited_variable = v ;
accept ( ) ;
}
KnownVariable * QalculateEditMatrixVectorDialog : : editVariable ( TQString category , KnownVariable * v , MathStructure * initial_value , bool force_value , bool create_vector ) {
nameEdit - > setFocus ( ) ;
if ( ( v & & ! v - > get ( ) . isVector ( ) ) | | ( initial_value & & ! initial_value - > isVector ( ) ) ) {
return NULL ;
}
if ( names_edit_dialog ) {
delete names_edit_dialog ;
names_edit_dialog = NULL ;
}
edited_variable = v ;
if ( initial_value ) {
create_vector = ! initial_value - > isMatrix ( ) ;
} else if ( v ) {
create_vector = ! v - > get ( ) . isMatrix ( ) ;
}
if ( create_vector ) {
vectorButton - > setChecked ( true ) ;
elementsLabel - > setText ( i18n ( " Elements (in horizontal order): " ) ) ;
} else {
matrixButton - > setChecked ( true ) ;
elementsLabel - > setText ( i18n ( " Elements: " ) ) ;
}
if ( create_vector ) {
if ( v ) {
if ( v - > isLocal ( ) )
setCaption ( i18n ( " Edit Vector " ) ) ;
else
setCaption ( i18n ( " Edit Vector (global) " ) ) ;
} else {
setCaption ( i18n ( " New Vector " ) ) ;
}
} else {
if ( v ) {
if ( v - > isLocal ( ) )
setCaption ( i18n ( " Edit Matrix " ) ) ;
else
setCaption ( i18n ( " Edit Matrix (global) " ) ) ;
} else {
setCaption ( i18n ( " New Matrix " ) ) ;
}
}
actionButton ( Ok ) - > setEnabled ( true ) ;
namesLabel - > setText ( " " ) ;
//TQStringList cats;
TQString catstr ;
categoryCombo - > clear ( ) ;
tree_struct * item , * item2 ;
variable_cats . it = variable_cats . items . begin ( ) ;
if ( variable_cats . it ! = variable_cats . items . end ( ) ) {
item = & * variable_cats . it ;
+ + variable_cats . it ;
item - > it = item - > items . begin ( ) ;
} else {
item = NULL ;
}
catstr = " " ;
while ( item ) {
if ( ! catstr . isEmpty ( ) ) catstr + = " / " ;
catstr + = item - > item . c_str ( ) ;
categoryCombo - > insertItem ( catstr ) ;
while ( item & & item - > it = = item - > items . end ( ) ) {
int str_i = catstr . findRev ( " / " ) ;
if ( str_i < 0 ) {
catstr = " " ;
} else {
catstr . truncate ( str_i ) ;
}
item = item - > parent ;
}
if ( item ) {
item2 = & * item - > it ;
+ + item - > it ;
item = item2 ;
item - > it = item - > items . begin ( ) ;
}
}
int r = 4 , c = 4 ;
const MathStructure * old_vctr = NULL ;
if ( v ) {
if ( create_vector ) {
old_vctr = & v - > get ( ) ;
} else {
c = v - > get ( ) . columns ( ) ;
r = v - > get ( ) . rows ( ) ;
}
set_name_label_and_entry ( v , nameEdit , namesLabel ) ;
nameEdit - > setReadOnly ( v - > isBuiltin ( ) ) ;
rowsBox - > setEnabled ( ! v - > isBuiltin ( ) ) ;
columnsBox - > setEnabled ( ! v - > isBuiltin ( ) ) ;
matrixButton - > setEnabled ( ! v - > isBuiltin ( ) ) ;
vectorButton - > setEnabled ( ! v - > isBuiltin ( ) ) ;
elementsTable - > setReadOnly ( v - > isBuiltin ( ) ) ;
categoryCombo - > lineEdit ( ) - > setText ( v - > category ( ) . c_str ( ) ) ;
titleEdit - > setText ( v - > title ( false ) . c_str ( ) ) ;
} else {
nameEdit - > setReadOnly ( false ) ;
rowsBox - > setEnabled ( true ) ;
columnsBox - > setEnabled ( true ) ;
matrixButton - > setEnabled ( true ) ;
vectorButton - > setEnabled ( true ) ;
elementsTable - > setReadOnly ( false ) ;
//fill in default values
nameEdit - > setText ( CALCULATOR - > getName ( ) . c_str ( ) ) ;
namesLabel - > setText ( " " ) ;
categoryCombo - > lineEdit ( ) - > setText ( category ) ;
titleEdit - > setText ( " " ) ;
if ( force_value ) {
if ( create_vector ) {
old_vctr = initial_value ;
} else {
c = initial_value - > columns ( ) ;
r = initial_value - > rows ( ) ;
}
rowsBox - > setEnabled ( false ) ;
columnsBox - > setEnabled ( false ) ;
matrixButton - > setEnabled ( false ) ;
vectorButton - > setEnabled ( false ) ;
elementsTable - > setReadOnly ( true ) ;
}
}
if ( create_vector ) {
if ( old_vctr ) {
r = old_vctr - > countChildren ( ) ;
c = ( int ) : : sqrt ( r ) + 4 ;
if ( r % c > 0 ) {
r = r / c + 1 ;
} else {
r = r / c ;
}
} else {
c = 4 ;
r = 4 ;
}
}
rowsBox - > setValue ( r ) ;
columnsBox - > setValue ( c ) ;
elementsTable - > setNumRows ( r ) ;
elementsTable - > setNumCols ( c ) ;
int timeout ;
if ( force_value ) timeout = 3000 / ( r * c ) ;
else timeout = 3000 ;
PrintOptions po ;
po . number_fraction_format = FRACTION_DECIMAL_EXACT ;
for ( int index_r = 0 ; index_r < r ; index_r + + ) {
for ( int index_c = 0 ; index_c < c ; index_c + + ) {
if ( create_vector ) {
if ( old_vctr & & index_r * c + index_c < ( int ) old_vctr - > countChildren ( ) ) {
elementsTable - > setText ( index_r , index_c , old_vctr - > getChild ( index_r * c + index_c + 1 ) - > print ( po ) . c_str ( ) ) ;
} else {
elementsTable - > setText ( index_r , index_c , " " ) ;
}
} else {
if ( v ) {
elementsTable - > setText ( index_r , index_c , v - > get ( ) . getElement ( index_r + 1 , index_c + 1 ) - > print ( po ) . c_str ( ) ) ;
} else if ( initial_value ) {
elementsTable - > setText ( index_r , index_c , initial_value - > getElement ( index_r + 1 , index_c + 1 ) - > print ( po ) . c_str ( ) ) ;
} else {
elementsTable - > setText ( index_r , index_c , " 0 " ) ;
}
}
}
}
init_value = initial_value ;
force_init_value = force_value ;
if ( exec ( ) = = TQDialog : : Accepted ) {
v = edited_variable ;
edited_variable = NULL ;
return v ;
}
edited_variable = NULL ;
return NULL ;
}
void QalculateEditMatrixVectorDialog : : editNames ( ) {
if ( ! names_edit_dialog ) {
names_edit_dialog = new QalculateEditNamesDialog ( TYPE_VARIABLE , this ) ;
names_edit_dialog - > setNames ( edited_variable , nameEdit - > text ( ) , false ) ;
} else {
names_edit_dialog - > setNames ( edited_variable , nameEdit - > text ( ) , true ) ;
}
names_edit_dialog - > exec ( ) ;
names_edit_dialog - > setNamesLE ( nameEdit , namesLabel ) ;
}
void QalculateEditMatrixVectorDialog : : nameChanged ( const TQString & name ) {
if ( name . isNull ( ) ) return ;
if ( ! CALCULATOR - > variableNameIsValid ( name . ascii ( ) ) ) {
nameEdit - > blockSignals ( true ) ;
nameEdit - > setText ( CALCULATOR - > convertToValidVariableName ( name . ascii ( ) ) . c_str ( ) ) ;
nameEdit - > blockSignals ( false ) ;
}
}
# if TQT_VERSION >= 0x030200
QalculateEditMatrixVectorTableItem : : QalculateEditMatrixVectorTableItem ( TQTable * table ) : TQTableItem ( table , TQTableItem : : OnTyping ) { }
# else
QalculateEditMatrixVectorTableItem : : QalculateEditMatrixVectorTableItem ( TQTable * table ) : TQTableItem ( table , TQTableItem : : OnTyping , TQString : : null ) { }
# endif
QalculateEditMatrixVectorTableItem : : QalculateEditMatrixVectorTableItem ( TQTable * table , const TQString & text ) : TQTableItem ( table , TQTableItem : : OnTyping , text ) { }
int QalculateEditMatrixVectorTableItem : : alignment ( ) const { return TQt : : AlignRight ; }
# include "qalculateeditmatrixvectordialog.moc"