/*************************************************************************** kspanelmanager.cpp ------------------- begin : Sat Oct 7 2000 copyright : (C) 2000 by Kamil Dobkowski email : kamildobk@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 "kspanelmanager.h" #include "dialogs/kspanels.h" #include "widgets/qsaxes2d.h" #include "widgets/qsaxes3d.h" #include "widgets/qscurve.h" #include "widgets/qscontour.h" #include "widgets/qsimage.h" #include "widgets/qssurface.h" #include "widgets/qsfigure.h" #include "widgets/qsclegend.h" #include "ksworkbook.h" #include "qscobjects.h" #include "kmatplotshell.h" #include #include #include #include #include #include #include #include #include #include #include #include //-------------------------------------------------------------// struct kspanelmanager_private_data { Qt::Orientation o; KMatplotShell *shell; KSWorkbook *workbook;; KSPanel *curr_panel; QSplitter *splitter; QWidget *buttons; QFrame *categ_area; QScrollView *panel_area; KSSimpleContainer *main_area; QPopupMenu *menu; QVButtonGroup *categ_buttons; QButtonGroup *panel_buttons; QPushButton *apply; QTimer *atimer; QTimer *rtimer; QGuardedPtr curr_view; QGuardedPtr curr_object; }; //-------------------------------------------------------------// //-------------------------------------------------------------// //-------------------------------------------------------------// //-------------------------------------------------------------// //-------------------------------------------------------------// //-------------------------------------------------------------// KSPanelManager::KSPanelManager( KMatplotShell *shell, QWidget *parent, const char *name ) : QFrame(parent,name) { ///////////////////////// // init panel manager // ///////////////////////// is_enabled = false; pr_reading = false; pr_applying = false; pr_autoset = true; resize( 355, 140 ); setFont( QFont("Arial",11) ); d = new kspanelmanager_private_data(); d->shell = shell; d->o = Horizontal; ///////////////////////// // timers // ///////////////////////// // instead of calling readProperties directly use rather rtimer->start( 250, TRUE ); // instead of calling applyProperties directly use rather atimer->start( 250, TRUE ); d->rtimer = new QTimer( this ); d->atimer = new QTimer( this ); connect( d->rtimer, SIGNAL(timeout()), this, SLOT(slot_panel_read_properties()) ); connect( d->atimer, SIGNAL(timeout()), this, SLOT(slot_panel_apply_properties()) ); ///////////////////////////////////// // place for buttons and panels // ///////////////////////////////////// d->splitter = new QSplitter( Horizontal, this ); d->buttons = new QWidget( d->splitter ); QGridLayout *l = new QGridLayout( d->buttons, 2, 2, 0, 5 ); d->categ_area = new QFrame( d->buttons ); d->categ_area->setFixedWidth( 35 ); d->panel_area = new QScrollView( d->buttons ); d->panel_area->setMinimumWidth( 50 ); d->panel_area->setMinimumHeight( 50 ); d->panel_area->setHScrollBarMode( QScrollView::AlwaysOff ); d->panel_area->setVScrollBarMode( QScrollView::Auto ); d->panel_area->viewport()->setBackgroundMode( PaletteBackground ); d->panel_area->setFrameStyle( StyledPanel | Sunken ); d->panel_area->viewport()->installEventFilter( this ); d->apply = new QPushButton( tr("Apply"), d->buttons ); d->apply->setDefault(true); connect( d->apply, SIGNAL(clicked()), this, SLOT(slot_panel_apply_properties()) ); setAutoSetProperties( true ); l->addWidget( d->categ_area, 0, 0 ); l->addWidget( d->panel_area, 0, 1 ); l->addWidget( d->apply, 1, 1 ); d->splitter->setResizeMode( d->buttons, QSplitter::Stretch ); d->main_area = new KSSimpleContainer( d->splitter, 500, 130, 1 ); d->main_area->setFrameStyle( StyledPanel | Sunken ); d->splitter->setResizeMode( d->main_area, QSplitter::Stretch ); QValueList sizes; sizes.append( 200 ); sizes.append( 500 ); d->splitter->setSizes( sizes ); d->menu = new QPopupMenu( this ); d->shell->m_cut_dataset->addTo( d->menu ); d->shell->m_copy_dataset->addTo( d->menu ); d->shell->m_copy_all_dataset->addTo( d->menu ); d->shell->m_paste_dataset->addTo( d->menu ); d->shell->m_delete_dataset->addTo( d->menu ); d->menu->insertSeparator(); d->shell->m_raise_dataset->addTo( d->menu ); d->shell->m_lower_dataset->addTo( d->menu ); d->menu->insertSeparator(); d->shell->m_bring_dataset_to_front->addTo( d->menu ); d->shell->m_send_dataset_to_back->addTo( d->menu ); /////////////////////////////// // buttons // /////////////////////////////// d->categ_buttons = NULL; d->panel_buttons = NULL; ////////////////////////////// // current state // ////////////////////////////// d->curr_view = NULL; d->curr_object = NULL; d->curr_panel = NULL; /////////////////////////////////////// // apply button ( hided by default ) // /////////////////////////////////////// } //-------------------------------------------------------------// KSPanelManager::~KSPanelManager() { // check if there is applyProperties waiting to be called if ( d->atimer->isActive() ) slot_panel_apply_properties(); emit dataObjectSelected( NULL ); delete d->categ_buttons; delete d->panel_buttons; delete d; } //-------------------------------------------------------------// void KSPanelManager::setView( QSPlotView *view ) { if ( d->curr_view ) { disconnect( d->curr_view, SIGNAL(sigActiveObjectChanged() ), this, SLOT(slot_update_panel_list()) ); disconnect( d->curr_view, SIGNAL(sigActiveAxesChanged() ), this, SLOT(slot_update_panel_list()) ); disconnect( d->curr_view, SIGNAL(sigActiveAxesDatasetsChanged()), this, SLOT(slot_update_panel_list()) ); disconnect( d->curr_view, SIGNAL(message( const QString&)), this, SLOT(slot_set_message(const QString&)) ); } d->curr_view = view; d->workbook = dynamic_cast(view->workbook()); if ( d->curr_view ) { connect( d->curr_view, SIGNAL(sigActiveObjectChanged() ), this, SLOT(slot_update_panel_list()) ); connect( d->curr_view, SIGNAL(sigActiveAxesChanged() ), this, SLOT(slot_update_panel_list()) ); connect( d->curr_view, SIGNAL(sigActiveAxesDatasetsChanged()), this, SLOT(slot_update_panel_list()) ); connect( d->curr_view, SIGNAL(message( const QString&)), this, SLOT(slot_set_message(const QString&)) ); } slot_update_panel_list(); } //-------------------------------------------------------------// QSPlotView *KSPanelManager::view() const { return (QSPlotView *)d->curr_view; } //-------------------------------------------------------------// void KSPanelManager::setEnabled( bool enabled ) { is_enabled = enabled; slot_update_panel_list(); } //-------------------------------------------------------------// void KSPanelManager::setAutoSetProperties( bool enabled ) { pr_autoset = enabled; if ( pr_autoset ) d->apply->hide(); else d->apply->show(); } //-------------------------------------------------------------// void KSPanelManager::slot_update_panel_list() // called when plot changes or active object changes { if ( !d->curr_object.isNull() ) disconnect( d->curr_object, SIGNAL(sigUpdate()), this, SLOT(slot_update_panel_contents()) ); if ( is_enabled ) { // try to preserve the currently selected category int curr_category = -1; if ( (QSCObject *)d->curr_object == get_curr_object() && d->categ_buttons ) curr_category = d->categ_buttons->id( d->categ_buttons->selected() ); d->curr_object = get_curr_object(); // create category buttons, ( and panel buttons if needed ) category_button_factory( curr_category ); } if ( !d->curr_object.isNull() ) connect( d->curr_object, SIGNAL(sigUpdate()), this, SLOT(slot_update_panel_contents()) ); } //-------------------------------------------------------------// void KSPanelManager::slot_category_selected( int category_id ) // user pressed category button { panel_button_factory( category_id ); } //-------------------------------------------------------------// void KSPanelManager::slot_panel_selected( int button_id ) // called when new panel is selected { // check if contents of the currently removed panel changed if ( d->atimer->isActive() ) { d->atimer->stop(); slot_panel_apply_properties(); } // delete a previous panel d->curr_panel = NULL; d->main_area->setWidget( NULL ); // create a new panel if ( is_enabled && panel_button(button_id) ) d->curr_panel = panel_button(button_id)->createPanel( d->main_area ); // show a new panel d->main_area->setWidget( d->curr_panel ); // watch if its properties changed if ( d->curr_panel ) { adjust_panel_orientation(); slot_panel_read_properties(); connect( d->curr_panel, SIGNAL(propertiesChanged()), this, SLOT(slot_update_graph()) ); connect( d->curr_panel, SIGNAL(message(const QString&)), this, SLOT(slot_set_message(const QString&)) ); } if ( panel_button(button_id) ) emit dataObjectSelected( panel_button(button_id)->dataObject() ); else emit dataObjectSelected( NULL ); } //-------------------------------------------------------------// KSPanelButton *KSPanelManager::panel_button( int button_id ) { if ( d->panel_buttons ) return dynamic_cast(d->panel_buttons->find(button_id)); return NULL; } //-------------------------------------------------------------// void KSPanelManager::selectPanel( int category, int element ) // show panel - called from outside { if ( get_curr_object() ) if ( category >= 0 || element >= 0 ) { // TODO: we must somehow unifu categories of buttons and categories of graph elements int button_category = KSPanelButton::BObject; switch( category ) { case QSAxes::GeneralCategory: button_category = KSPanelButton::BGeneral; break; case QSAxes::AxisCategory: button_category = KSPanelButton::BAxes; break; case QSAxes::GridCategory: button_category = KSPanelButton::BAxes; break; case QSAxes::DatasetCategory: button_category = KSPanelButton::BDatasets; break; } // select category if ( d->categ_buttons ) if ( d->categ_buttons->find(button_category) && !d->categ_buttons->find(button_category)->isOn() ) { d->categ_buttons->find(button_category)->animateClick(); } // select panel if ( d->panel_buttons ) for( int button_nr=0; button_nrpanel_buttons->count(); button_nr++ ) { KSPanelButton *button = panel_button(button_nr); if ( button ) if ( button->isButtonFor(get_curr_object(),category,element) ) { d->panel_area->ensureVisible( button->x(), button->y() ); if ( !button->isOn() ) button->animateClick(); } } } } //-------------------------------------------------------------// void KSPanelManager::slot_panel_apply_properties() { pr_applying = true; if ( d->curr_panel ) d->curr_panel->applyProperties(); pr_applying = false; } //-------------------------------------------------------------// void KSPanelManager::slot_panel_read_properties() { pr_reading = true; if ( d->curr_panel ) d->curr_panel->readProperties(); pr_reading = false; } //-------------------------------------------------------------// void KSPanelManager::slot_update_panel_contents() { if ( is_enabled && !pr_autoset || !pr_applying ) d->rtimer->start( 250, TRUE ); } //-------------------------------------------------------------// void KSPanelManager::slot_update_graph() { if ( is_enabled && pr_autoset && !pr_reading ) d->atimer->start( 1000, TRUE ); } //-------------------------------------------------------------// QSCObject *KSPanelManager::get_curr_object() { if ( d->curr_view ) if ( d->curr_view->activeObject() ) return d->curr_view->activeObject(); return NULL; } //-------------------------------------------------------------// void KSPanelManager::add_category_button( int category ) { d->categ_buttons->insert( KSPanelButton::categoryButton( (KSPanelButton::ButtonCategory )category, d->categ_buttons ), category ); } //-------------------------------------------------------------// void KSPanelManager::arrange_button_row( const QString& title, int num_buttons, QSGraphicalData *dataObject ) { // fill unused space for( int i=num_buttons; i<3; i++ ) new QWidget( d->panel_buttons ); // add title QLabel *label = new QLabel( title, d->panel_buttons ); label->setIndent( 5 ); label->setMaximumHeight( 50 ); label->setAlignment( AlignAuto | AlignVCenter | ExpandTabs ); if ( dataObject ) connect( dataObject, SIGNAL(sigTitleChanged(const QString&)), label, SLOT(setText(const QString&)) ); } //-------------------------------------------------------------// void KSPanelManager::slot_set_message( const QString& string ) { emit message( string ); } //-------------------------------------------------------------// void KSPanelManager::category_button_factory( int select_category ) { QButtonGroup *button_group = d->categ_buttons; /////////////////////////////////// // delete panel list // /////////////////////////////////// panel_button_factory( -1 ); /////////////////////////////////// // Delete old buttons // /////////////////////////////////// delete d->categ_buttons; d->categ_buttons = new QVButtonGroup( d->categ_area ); d->categ_buttons->setFrameStyle( NoFrame ); d->categ_buttons->setFixedSize( d->categ_area->width(), 140 ); d->categ_buttons->setExclusive( true ); d->categ_buttons->setInsideMargin( 3 ); d->categ_buttons->setInsideSpacing( 0 ); connect( d->categ_buttons, SIGNAL(pressed(int)), this, SLOT(slot_category_selected(int)) ); /////////////////////////////////// // Create new buttons // /////////////////////////////////// QSCObject *curr_object = d->curr_object; if ( curr_object && curr_object->isAxesShadow() ) { add_category_button( KSPanelButton::BGeneral ); add_category_button( KSPanelButton::BAxes ); add_category_button( KSPanelButton::BDatasets ); } else if ( curr_object ) { add_category_button( KSPanelButton::BObject ); } ////////////////////////////////// // set button panel // ////////////////////////////////// //d->categ_buttons->resize( d->categ_buttons->width(), d->categ_buttons->sizeHint().height() ); d->categ_buttons->show(); ////////////////////////////////// // Select the first category // ////////////////////////////////// if ( d->categ_buttons->find(select_category) ) { d->categ_buttons->find(select_category)->animateClick(); } else { for( int i=0; i<4; i++ ) if ( d->categ_buttons->find(i) ) { d->categ_buttons->find(i)->animateClick(); break; } } } //-------------------------------------------------------------// void KSPanelManager::panel_button_factory( int category ) { QSCObject *curr_object = d->curr_object; QButtonGroup *button_group = d->panel_buttons; //////////////////////////////////// // delete currently visible panel // //////////////////////////////////// slot_panel_selected( -1 ); //////////////////////////////////////// // delete old buttons // //////////////////////////////////////// d->panel_area->removeChild( d->panel_buttons ); delete d->panel_buttons; d->panel_buttons = new QButtonGroup( 4, Horizontal, d->panel_area->viewport() ); d->panel_buttons->setExclusive( true ); d->panel_buttons->setFrameStyle( NoFrame | Plain ); d->panel_buttons->setInsideMargin( 3 ); d->panel_buttons->setInsideSpacing( 0 ); connect( d->panel_buttons, SIGNAL(pressed(int)), this, SLOT(slot_panel_selected(int)) ); //////////////////////////////////////// // create new buttons // //////////////////////////////////////// if ( curr_object && curr_object->isAxesShadow() ) { QSAxes *axes = curr_object->parentAxes(); if ( category == KSPanelButton::BGeneral ) { new KSPanelButtonRange(d->panel_buttons,d->workbook,axes); arrange_button_row( tr("Range"), 1 ); new KSPanelButtonGeneral(d->panel_buttons,d->workbook,axes); arrange_button_row( tr("General"), 1 ); } if ( category == KSPanelButton::BGeneral ) if ( dynamic_cast(axes) ) { QSAxes2D *axes2 = dynamic_cast(axes); new KSPanelButtonFrame( d->panel_buttons, d->workbook, axes2 ); arrange_button_row( tr("Frame"), 1 ); } if ( category == KSPanelButton::BGeneral ) if ( dynamic_cast(axes) ) { QSAxes3D *axes3 = dynamic_cast(axes); new KSPanelButtonCube(d->panel_buttons,d->workbook,axes3); arrange_button_row( tr("Cube"), 1 ); new KSPanelButtonView(d->panel_buttons,d->workbook,axes3); arrange_button_row( tr("View"), 1 ); new KSPanelButtonLight(d->panel_buttons,d->workbook,axes3); arrange_button_row( tr("Light"), 1 ); new KSPanelButtonGL(d->panel_buttons,d->workbook,axes3); arrange_button_row( tr("OpenGL"), 1 ); } if ( category == KSPanelButton::BAxes ) for( int axis=axes->axisCount()-1; axis>=0; axis-- ) { new KSPanelButtonAxis(d->panel_buttons,d->workbook,axes->axis(axis)); new KSPanelButtonGrid(d->panel_buttons,d->workbook,axes->axis(axis)); arrange_button_row( axes->axis(axis)->title(), 2, axes->axis(axis) ); } if ( category == KSPanelButton::BDatasets ) for( int dataset=axes->plotCount()-1; dataset>=0; dataset-- ) { if ( dynamic_cast(axes->plot(dataset)) ) { QSCurve *curve = dynamic_cast(axes->plot(dataset)); new KSPanelButtonCurve(d->panel_buttons,d->workbook,curve); arrange_button_row( axes->plot(dataset)->title(), 1, axes->plot(dataset) ); } if ( dynamic_cast(axes->plot(dataset)) ) { QSContour *contour = dynamic_cast(axes->plot(dataset)); new KSPanelButtonContour(d->panel_buttons,d->workbook,contour); new KSPanelButtonGradient(d->panel_buttons,d->workbook,contour); arrange_button_row( axes->plot(dataset)->title(), 2, axes->plot(dataset) ); } if ( dynamic_cast(axes->plot(dataset)) ) { QSImage *image = dynamic_cast(axes->plot(dataset)); new KSPanelButtonImage(d->panel_buttons,d->workbook,image); new KSPanelButtonGradient(d->panel_buttons,d->workbook,image); arrange_button_row( axes->plot(dataset)->title(), 2, axes->plot(dataset) ); } if ( dynamic_cast(axes->plot(dataset)) ) { QSSurface *surface = dynamic_cast(axes->plot(dataset)); new KSPanelButtonSurface(d->panel_buttons,d->workbook,surface); new KSPanelButtonMesh(d->panel_buttons,d->workbook,surface); arrange_button_row( axes->plot(dataset)->title(), 2, axes->plot(dataset) ); } if ( dynamic_cast(axes->plot(dataset)) ) { QSFigure *figure = dynamic_cast(axes->plot(dataset)); new KSPanelButtonFigure(d->panel_buttons,d->workbook,figure); new KSPanelButtonMesh(d->panel_buttons,d->workbook,figure); arrange_button_row( axes->plot(dataset)->title(), 2, axes->plot(dataset) ); } } } if ( category == KSPanelButton::BObject ) if ( dynamic_cast(curr_object) ) { QSCLegend *l = dynamic_cast(curr_object); new KSPanelButtonCLegend(d->panel_buttons,d->workbook,l); arrange_button_row( tr("Legend"), 1 ); new KSPanelButtonCLabel(d->panel_buttons,d->workbook,l); arrange_button_row( tr("Labels"), 1 ); new KSPanelButtonCPos(d->panel_buttons,d->workbook,l,"posX","posY","posZ","coordX","coordY","coordZ"); arrange_button_row( tr("Position"), 1 ); } else if ( dynamic_cast(curr_object) ) { QSCArrow *a = dynamic_cast(curr_object); new KSPanelButtonCArrow(d->panel_buttons,d->workbook,a); arrange_button_row( tr("Arrow"), 1 ); new KSPanelButtonCPos(d->panel_buttons,d->workbook,a,"originX","originY","originZ","originCoordX","originCoordY","originCoordZ"); arrange_button_row( tr("Origin"), 1 ); new KSPanelButtonCPos(d->panel_buttons,d->workbook,a,"endX","endY","endZ","endCoordX","endCoordY","endCoordZ"); arrange_button_row( tr("End"), 1 ); } else if ( dynamic_cast(curr_object) ) { QSCLabel *l = dynamic_cast(curr_object); new KSPanelButtonCLabel(d->panel_buttons,d->workbook,l); arrange_button_row( tr("Label"), 1 ); new KSPanelButtonCPos(d->panel_buttons,d->workbook,l,"posX","posY","posZ","coordX","coordY","coordZ"); arrange_button_row( tr("Position"), 1 ); } else if ( dynamic_cast(curr_object) ) { QSCRect *r = dynamic_cast(curr_object); new KSPanelButtonCRect(d->panel_buttons,d->workbook,r); arrange_button_row( tr("Rectangle"), 1 ); new KSPanelButtonCPos(d->panel_buttons,d->workbook,r,"originX","originY","originZ","originCoordX","originCoordY","originCoordZ"); arrange_button_row( tr("First corner"), 1 ); new KSPanelButtonCPos(d->panel_buttons,d->workbook,r,"endX","endY","endZ","endCoordX","endCoordY","endCoordZ"); arrange_button_row( tr("Second corner"), 1 ); } ////////////////////////////////////////////// // set button view // ////////////////////////////////////////////// //d->panel_buttons->setFixedSize( d->panel_buttons->sizeHint() ); d->panel_buttons->show(); d->panel_area->addChild( d->panel_buttons ); d->panel_area->resizeContents( d->panel_buttons->sizeHint().width(), d->panel_buttons->sizeHint().height() ); ////////////////////////////// // select the first panel // ////////////////////////////// if ( d->panel_buttons->find(0) ) d->panel_buttons->find(0)->animateClick(); } //-------------------------------------------------------------// bool KSPanelManager::eventFilter ( QObject *watched, QEvent *e ) { if ( watched == d->panel_area->viewport() && e->type() == QEvent::ContextMenu ) { d->menu->popup( ((QContextMenuEvent*)e)->globalPos() ); return TRUE; } return FALSE; } //-------------------------------------------------------------// void KSPanelManager::setOrientation( Qt::Orientation o ) { d->o = o; d->splitter->setOrientation( o ); adjust_panel_orientation(); } //-------------------------------------------------------------// void KSPanelManager::adjust_panel_orientation() { if ( d->curr_panel ) { const QObjectList *objects = d->curr_panel->queryList( "QBoxLayout", 0, FALSE, FALSE ); if ( objects ) { QObjectListIt object( *objects ); while ( (QObject*)object ) { QBoxLayout *layout = dynamic_cast((QObject*)object); if ( layout ) layout->setDirection( d->o==Horizontal ? QBoxLayout::LeftToRight : QBoxLayout::TopToBottom ); ++object; } } } } //-------------------------------------------------------------// void KSPanelManager::resizeEvent ( QResizeEvent * ) { d->splitter->resize( size() ); }