/*************************************************************************** ksgraphwizard.cpp - description ------------------- begin : Thu Mar 14 2002 copyright : (C) 2002 by kamil email : kamil@localhost.localdomain ***************************************************************************/ /*************************************************************************** * * * 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 "ksgraphwizard.h" #include "../ksmatrix.h" #include "../ksworkbook.h" #include "../ksglobalmatrixlist.h" #include "../ksglobalsettings.h" #include "../ksmatrixeditor.h" #include "../ksdatasymbolfactory.h" #include "../kscommands.h" #include "../widgets/qsplotview.h" #include "../widgets/qscurve.h" #include "../widgets/qsimage.h" #include "../widgets/qscontour.h" #include "../widgets/qssurface.h" #include "../widgets/qsfigure.h" #include "../widgets/qsconsole.h" #include "../widgets/qsaxes2d.h" #include "../widgets/qsaxes3d.h" #include "../formula/mpformula.h" #include "kschannellist.h" #include #include #include #include #include #include #include #include #include //-------------------------------------------------------------------------// KSGraphSubtypeItem::KSGraphSubtypeItem( QIconView *parent, KSDataObjectFactory::DataObject objectType, const QString& title, const QString& icon ) : QIconViewItem( parent, title, QPixmap( KSGlobalSettings::picturePath()+"/"+icon ) ) { m_object_type = objectType; } //-------------------------------------------------------------------------// KSGraphSubtypeItem::~KSGraphSubtypeItem() { } //-------------------------------------------------------------------------// QWidget *KSGraphSubtypeItem::additionalPage( QWidget *parent ) // not implemented { return NULL; } //-------------------------------------------------------------------------// void KSGraphSubtypeItem::initChannels( KSGraphInfo *info ) { int channels = KSDataObjectFactory::channelNumber( m_object_type ); info->resize( channels ); for( int i=0; iat(i).m_name = KSDataObjectFactory::channelNameFactory( m_object_type, i ); info->at(i).m_description = KSDataObjectFactory::channelDescFactory( m_object_type, i ); } } //-------------------------------------------------------------------------// QSAxesChild *KSGraphSubtypeItem::createObject( QSAxes *parent ) // it must be reimplemented { return NULL; } //-------------------------------------------------------------------------// //-------------------------------------------------------------------------// //-------------------------------------------------------------------------// //-------------------------------------------------------------------------// //-------------------------------------------------------------------------// class KSGraphCurveItem : public KSGraphSubtypeItem { public: KSGraphCurveItem( QIconView *parent ) : KSGraphSubtypeItem( parent, KSDataObjectFactory::ObjectCurve, QObject::tr("Curve"), "graph_xyplot.png" ) {} ~KSGraphCurveItem() {} virtual QSAxesChild *createObject( QSAxes *parent ) { QSCurve *result = new QSCurve(parent); return result; } }; //-------------------------------------------------------------------------// class KSGraphImageItem : public KSGraphSubtypeItem { public: KSGraphImageItem( QIconView *parent ) : KSGraphSubtypeItem( parent, KSDataObjectFactory::ObjectImage, QObject::tr("Pixmap"), "graph_image.png" ) {} ~KSGraphImageItem() {} virtual QSAxesChild *createObject( QSAxes *parent ) { QSImage *result = new QSImage(parent); return result; } }; //-------------------------------------------------------------------------// class KSGraphGriddedContourItem : public KSGraphSubtypeItem { public: KSGraphGriddedContourItem( QIconView *parent ) : KSGraphSubtypeItem( parent, KSDataObjectFactory::ObjectGriddedContour, QObject::tr("Gridded contour"), "graph_contour.png" ) {} ~KSGraphGriddedContourItem() {} virtual QSAxesChild *createObject( QSAxes *parent ) { QSGriddedContour *result = new QSGriddedContour(parent); return result; } }; //-------------------------------------------------------------------------// class KSGraphNonGriddedContourItem : public KSGraphSubtypeItem { public: KSGraphNonGriddedContourItem( QIconView *parent ) : KSGraphSubtypeItem( parent, KSDataObjectFactory::ObjectNonGriddedContour, QObject::tr("Non-gridded contour"), "graph_ngcontour.png" ) {} ~KSGraphNonGriddedContourItem() {} virtual QSAxesChild *createObject( QSAxes *parent ) { QSNonGriddedContour *result = new QSNonGriddedContour(parent); return result; } virtual void initChannels( KSGraphInfo *info ) { KSGraphSubtypeItem::initChannels( info ); info->at(QSNonGriddedContour::Triangles).m_use_formula=true; info->at(QSNonGriddedContour::Triangles).m_formula="delunay(x,y)"; } }; //-------------------------------------------------------------------------// class KSGraphSurfaceItem : public KSGraphSubtypeItem { public: KSGraphSurfaceItem( QIconView *parent ) : KSGraphSubtypeItem( parent, KSDataObjectFactory::ObjectSurface, QObject::tr("Surface"), "graph_surface.png" ) {} ~KSGraphSurfaceItem() {} virtual QSAxesChild *createObject( QSAxes *parent ) { QSSurface *result = new QSSurface(parent); return result; } }; //-------------------------------------------------------------------------// class KSGraphNonGriddedSurfaceItem : public KSGraphSubtypeItem { public: KSGraphNonGriddedSurfaceItem( QIconView *parent ) : KSGraphSubtypeItem( parent, KSDataObjectFactory::ObjectFigure, QObject::tr("Non-gridded surface"), "graph_ngsurface.png" ) {} ~KSGraphNonGriddedSurfaceItem() {} virtual QSAxesChild *createObject( QSAxes *parent ) { QSFigure *result = new QSFigure(parent); return result; } virtual void initChannels( KSGraphInfo *info ) { KSGraphSubtypeItem::initChannels( info ); info->at(QSFigure::VTableI).m_use_formula=true; info->at(QSFigure::VTableI).m_formula="delunay(x,y)"; } }; //-------------------------------------------------------------------------// class KSGraphFigureItem : public KSGraphSubtypeItem { public: KSGraphFigureItem( QIconView *parent ) : KSGraphSubtypeItem( parent, KSDataObjectFactory::ObjectFigure, QObject::tr("Figure"), "graph_figure.png" ) {} ~KSGraphFigureItem() {} virtual QSAxesChild *createObject( QSAxes *parent ) { QSFigure *result = new QSFigure(parent); return result; } }; //-------------------------------------------------------------------------// //-------------------------------------------------------------------------// //-------------------------------------------------------------------------// //-------------------------------------------------------------------------// //-------------------------------------------------------------------------// KSGraphWizard::KSGraphWizard( QSPlotView *view, KSWorkbook *workbook, QWidget *parent, const char *name ) : KSGraphWizardInterf(parent,name,true) { m_view = view; m_workbook = workbook; m_sheet_editor = NULL; // select data range on it m_preview_axes = NULL; m_new_axes = NULL; m_new_dataset = NULL; m_watch_data_page = true; for ( int i=0; iactiveAxes() ) selectedAxes->setChecked( TRUE ); else { newAxes2D->setChecked( TRUE ); selectedAxes->setEnabled( false ); } worksheetList->addColumn( tr("Sheets"), 95 ); worksheetList->addColumn( tr(""), 95 ); worksheetList->addColumn( tr(""), 50 ); worksheetList->setDataObject( m_workbook->sheets(), false, 0, false ); connect( graphType, SIGNAL(highlighted(int)), this, SLOT(slot_graph_type_changed(int)) ); connect( graphType, SIGNAL(selectionChanged()), this, SLOT(slot_page_type_changed()) ); connect( graphSubtype, SIGNAL(selectionChanged()), this, SLOT(slot_page_type_changed()) ); connect( worksheetList, SIGNAL(selectionChanged()), this, SLOT(slot_page_type_changed()) ); connect( channelList, SIGNAL(highlighted(int)), this, SLOT(slot_channel_selected(int)) ); connect( clearChannel, SIGNAL(clicked()), this, SLOT(slot_clear_channel()) ); connect( useFormula, SIGNAL(stateChanged(int)), this, SLOT(slot_channel_data_changed()) ); connect( formulaString, SIGNAL(textChanged()), this, SLOT(slot_channel_data_changed()) ); graphSubtype->clear(); setNextEnabled( QWizard::page(1), false ); setFinishEnabled( QWizard::page(3), true ); sheetEditorPlace->installEventFilter( this ); previewPlace->installEventFilter( this ); } //-------------------------------------------------------------------------// KSGraphWizard::~KSGraphWizard() { delete m_sheet_editor; clear_preview(); } //-------------------------------------------------------------------------// bool KSGraphWizard::eventFilter( QObject *object, QEvent *e ) { if ( object == sheetEditorPlace && e->type() == QEvent::Resize ) { if ( m_sheet_editor && m_sheet_editor->widget() ) m_sheet_editor->widget()->resize( sheetEditorPlace->size() ); } else if ( object == previewPlace && e->type() == QEvent::Paint ) { if ( m_preview_axes ) { QPainter painter( previewPlace ); m_preview_axes->stop(); m_preview_axes->setCanvasRect( QSRectf(60,40,previewPlace->width()-120,previewPlace->height()-80) ); m_preview_axes->paintPlot( &painter, 72.0, false ); return true; } } return false; } //-------------------------------------------------------------------------// void KSGraphWizard::showPage( QWidget *page ) { switch( indexOf(page) ) { // case 0: show_page_into(); break; // case 1: show_page_type(); break; case 2: show_page_data(); break; case 3: show_page_finish(); break; } QWizard::showPage( page ); } //-------------------------------------------------------------------------// void KSGraphWizard::slot_page_type_changed() // state of the widgets on the type page has changed // check if we can enable the next button { if ( graphType->currentItem() >= 0 && graphSubtype->currentItem() && worksheetList->selectedItem() ) setNextEnabled( QWizard::page(1), true ); else setNextEnabled( QWizard::page(1), false ); } //-------------------------------------------------------------------------// void KSGraphWizard::slot_graph_type_changed( int index ) // type of the graph has changed - show all available subtypes for this type { graphSubtype->clear(); switch( index ) { // XY plot case 0: (void )new KSGraphCurveItem( graphSubtype ); break; // Pixmap case 1: (void )new KSGraphImageItem( graphSubtype ); break; // Contour case 2: (void )new KSGraphGriddedContourItem( graphSubtype ); (void )new KSGraphNonGriddedContourItem( graphSubtype ); break; // Surface case 3: (void )new KSGraphSurfaceItem( graphSubtype ); (void )new KSGraphNonGriddedSurfaceItem( graphSubtype ); break; // Figure case 4: (void )new KSGraphFigureItem( graphSubtype ); break; } slot_page_type_changed(); } //-------------------------------------------------------------------------// void KSGraphWizard::show_page_data() { // delete preview object ( if back was clicked and we moved from the finish page ) clear_preview(); // create channel list KSGraphSubtypeItem *m_graph_subtype = dynamic_cast(graphSubtype->currentItem()); m_graph_subtype->initChannels( &m_graph_info ); channelList->clear(); for( int i=0; iinsertItem( m_graph_info.at(i).m_name ); slot_channel_selected( -1 ); } //-------------------------------------------------------------------------// void KSGraphWizard::slot_channel_selected( int index ) { set_watch_data_page( false ); // channel was selected - show the editor with the worksheet and allow user to select a data range if ( index >= 0 ) { KSGraphChannelInfo channel = m_graph_info.at(index); // fill all fields channelDescription->setText( channel.m_description ); formulaString->setText( channel.m_formula ); useFormula->setChecked( channel.m_use_formula ); // create editor QSData *data_object = channel.m_sheet ? channel.m_sheet : worksheetList->selected()->dataObject(); if ( m_sheet_editor == NULL || m_sheet_editor->editedMatrix() != data_object->matrix(0) ) { delete m_sheet_editor; m_sheet_editor = NULL; m_sheet_editor = KSDataObjectFactory::createEditor( m_workbook, data_object, 0, sheetEditorPlace ); // // this is a little trick ! // connect( m_sheet_editor->widget(), SIGNAL(selectionChanged()), this, SLOT(slot_channel_data_changed()) ); } // initialize editor m_sheet_editor->setSelectionRange( channel.m_selection ); m_sheet_editor->setEditorContentsPos( channel.m_editor_pos ); m_sheet_editor->widget()->resize( sheetEditorPlace->size() ); m_sheet_editor->widget()->show(); } else { channelDescription->setText( QString::null ); formulaString->setText( QString::null ); useFormula->setChecked( false ); delete m_sheet_editor; m_sheet_editor = NULL; } set_watch_data_page( true ); } //-------------------------------------------------------------------------// void KSGraphWizard::slot_clear_channel() // clear channel data button was clicked { int curr_channel = channelList->currentItem(); if ( curr_channel >= 0 ) { m_graph_info.at(curr_channel).m_use_formula = false; m_graph_info.at(curr_channel).m_sheet = NULL; m_graph_info.at(curr_channel).m_selection = QRect(); m_graph_info.at(curr_channel).m_editor_pos = QPoint(); slot_channel_selected( curr_channel ); } } //-------------------------------------------------------------------------// void KSGraphWizard::slot_channel_data_changed() // state of the data panel was changed ( button clicked, text entered, selection changed etc... ) // remembercurrent settings for the selected channel { if ( !m_watch_data_page ) return; int curr_channel = channelList->currentItem(); if ( curr_channel >= 0 ) { if ( m_sheet_editor && !m_sheet_editor->selectionRange().isEmpty() ) { if ( !m_graph_info.at(curr_channel).m_sheet ) m_graph_info.at(curr_channel).m_sheet = dynamic_cast(worksheetList->selected()->dataObject()); m_graph_info.at(curr_channel).m_selection = m_sheet_editor->selectionRange(); } if ( m_sheet_editor ) m_graph_info.at(curr_channel).m_editor_pos = m_sheet_editor->editorContentsPos(); m_graph_info.at(curr_channel).m_formula = formulaString->text(); m_graph_info.at(curr_channel).m_use_formula = useFormula->isChecked(); } } //-------------------------------------------------------------------------// void KSGraphWizard::show_page_finish() // user clicked next and we enter the finish page - show the preview { clear_preview(); // create preview KSGraphSubtypeItem *m_graph_subtype = dynamic_cast(graphSubtype->currentItem()); if ( selectedAxes->isChecked() ) { m_preview_axes = m_view->activeAxes(); } else if ( newAxes2D->isChecked() ) { m_new_axes = new QSAxes2D(); m_preview_axes = m_new_axes; } else if ( newAxes3D->isChecked() ) { m_new_axes = new QSAxes3D(); m_preview_axes = m_new_axes; } m_new_dataset = m_graph_subtype->createObject( m_preview_axes ); create_data( m_new_dataset ); m_preview_axes->plotAdd( dynamic_cast(m_new_dataset) ); } //-------------------------------------------------------------------------// void KSGraphWizard::create_data( QSData *new_object ) // create dataset from channel data { for( int i=0; ichannelCount(); i++ ) { KSGraphChannelInfo channel = m_graph_info.at(i); if ( channel.m_use_formula ) { KSMatrixFormula *new_matrix = new KSMatrixFormula(); new_matrix->setFormula( channel.m_formula ); new_object->setMatrix( i, new_matrix ); } else if ( !channel.m_selection.isEmpty() ) { KSSheet *sheet = channel.m_sheet ? channel.m_sheet : dynamic_cast(worksheetList->selected()->dataObject()); KSMatrixWorksheetCellRange *new_matrix = new KSMatrixWorksheetCellRange( m_workbook ); new_matrix->setWorksheet( m_workbook->sheets()->sheetFind( sheet ) ); new_matrix->setRowFrom( channel.m_selection.top() ); new_matrix->setColFrom( channel.m_selection.left() ); if ( channel.m_selection.bottom() == sheet->matrix(0)->rows()-1 ) new_matrix->setRowTo( -1 ); else new_matrix->setRowTo( channel.m_selection.bottom() ); if ( channel.m_selection.right() == sheet->matrix(0)->cols()-1 ) new_matrix->setColTo( -1 ); else new_matrix->setColTo( channel.m_selection.right() ); new_object->setMatrix( i, new_matrix ); } } // recalculate all formulas for( int i=0; ichannelCount(); i++ ) { KSMatrixFormula *formula_matrix = dynamic_cast(new_object->matrix(i)); if ( formula_matrix ) { MPFactoryList factory( new KSDataSymbolFactory( m_workbook, formula_matrix->dataObject() ) ); MPFormulaError error; formula_matrix->init( error, &factory ); if ( error.hasError() ) QSConsole::write( QObject::tr("Error parsing formula :")+formula_matrix->formula()+"
"+error.message() ); } } } //-------------------------------------------------------------------------// void KSGraphWizard::accept() // user clicked ok - add objects to the workbook. { apply_dataset(); QWizard::accept(); } //-------------------------------------------------------------------------// void KSGraphWizard::clear_preview() // delete object ( which was created for a preview ) { if ( m_new_dataset ) m_new_dataset->parentAxes()->plotRemove( dynamic_cast(m_new_dataset) ); m_preview_axes = NULL; delete m_new_dataset; m_new_dataset = NULL; delete m_new_axes; m_new_axes = NULL; } //-------------------------------------------------------------------------// void KSGraphWizard::apply_dataset() // add object to the workbook { m_preview_axes = NULL; if ( m_new_axes ) { m_workbook->execute( new KSCmdAddCObject( m_new_axes->shadowObject(), m_view->currentPage()->objects() ) ); m_new_axes = NULL; m_new_dataset = NULL; } else if ( m_new_dataset ) { m_new_dataset->parentAxes()->plotRemove( dynamic_cast(m_new_dataset) ); m_workbook->execute( new KSCmdAddDataset(dynamic_cast(m_new_dataset)) ); m_new_dataset = NULL; } } //-------------------------------------------------------------------------// void KSGraphWizard::set_watch_data_page( bool enabled ) { m_watch_data_page = enabled; }