tabbedplotwidget.cpp
Go to the documentation of this file.
00001 #include <QMenu>
00002 #include <QSignalMapper>
00003 #include <QAction>
00004 #include <QInputDialog>
00005 #include <QMouseEvent>
00006 #include <QFileDialog>
00007 #include "qwt_plot_renderer.h"
00008 #include "tabbedplotwidget.h"
00009 #include "ui_tabbedplotwidget.h"
00010 
00011 std::map<QString,TabbedPlotWidget*> TabbedPlotWidget::_instances;
00012 
00013 TabbedPlotWidget::TabbedPlotWidget(QString name,
00014                                    QMainWindow *main_window,
00015                                    PlotMatrix  *first_tab,
00016                                    PlotDataMap &mapped_data,
00017                                    QMainWindow *parent ) :
00018     QWidget(parent),
00019     _mapped_data(mapped_data),
00020     ui(new Ui::TabbedPlotWidget),
00021     _name(name)
00022 {
00023 
00024     if( main_window == parent){
00025         _parent_type = "main_window";
00026     }
00027     else
00028     {
00029         _parent_type = "floating_window";
00030     }
00031 
00032     if( TabbedPlotWidget::_instances.count(_name) > 0)
00033     {
00034         throw std::runtime_error("This is not supposed to happen");
00035     }
00036     // register this instance
00037     _instances[_name] = this;
00038 
00039     ui->setupUi(this);
00040 
00041     _horizontal_link = true;
00042 
00043     ui->tabWidget->tabBar()->installEventFilter( this );
00044 
00045     _action_renameTab = new QAction(tr("Rename tab"), this);
00046     connect( _action_renameTab, &QAction::triggered, this, &TabbedPlotWidget::on_renameCurrentTab);
00047 
00048     QIcon iconSave;
00049     iconSave.addFile(QStringLiteral(":/icons/resources/filesave@2x.png"), QSize(26, 26));
00050     _action_savePlots = new  QAction(tr("&Save plots to file"), this);
00051     _action_savePlots->setIcon(iconSave);
00052     connect(_action_savePlots, &QAction::triggered, this, &TabbedPlotWidget::on_savePlotsToFile);
00053 
00054     _tab_menu = new QMenu(this);
00055     _tab_menu->addAction( _action_renameTab );
00056     _tab_menu->addSeparator();
00057     _tab_menu->addAction( _action_savePlots );
00058     _tab_menu->addSeparator();
00059 
00060     connect( this, SIGNAL(destroyed(QObject*)),             main_window, SLOT(on_tabbedAreaDestroyed(QObject*)) );
00061     connect( this, SIGNAL(sendTabToNewWindow(PlotMatrix*)), main_window, SLOT(onCreateFloatingWindow(PlotMatrix*)) );
00062     connect( this, SIGNAL(matrixAdded(PlotMatrix*)),        main_window, SLOT(onPlotMatrixAdded(PlotMatrix*)) );
00063     connect( this, SIGNAL(undoableChangeHappened()),        main_window, SLOT(onUndoableChange()) );
00064 
00065     this->addTab(first_tab);
00066 }
00067 
00068 //void TabbedPlotWidget::setSiblingsList(const std::map<QString, TabbedPlotWidget *> &other_tabbed_widgets)
00069 //{
00070 //    _other_siblings = other_tabbed_widgets;
00071 //}
00072 
00073 PlotMatrix *TabbedPlotWidget::currentTab()
00074 {
00075     return static_cast<PlotMatrix*>( ui->tabWidget->currentWidget() );
00076 }
00077 
00078 QTabWidget *TabbedPlotWidget::tabWidget()
00079 {
00080     return ui->tabWidget;
00081 }
00082 
00083 void TabbedPlotWidget::addTab( PlotMatrix* tab)
00084 {
00085     if( !tab )
00086     {
00087         tab = new PlotMatrix("plot", _mapped_data, this);
00088         ui->tabWidget->addTab( tab, QString("plot") );
00089 
00090         QApplication::processEvents();
00091         emit matrixAdded( tab );
00092         tab->addColumn();
00093     }
00094     else{
00095         ui->tabWidget->addTab( tab, tab->name() );
00096     }
00097 
00098     ui->tabWidget->setCurrentWidget( tab );
00099 
00100     tab->setHorizontalLink( _horizontal_link );
00101 }
00102 
00103 QDomElement TabbedPlotWidget::xmlSaveState(QDomDocument &doc) const
00104 {
00105     QDomElement tabbed_area = doc.createElement( "tabbed_widget" );
00106 
00107     tabbed_area.setAttribute("name",   _name);
00108     tabbed_area.setAttribute("parent", _parent_type);
00109 
00110     for(int i=0; i< ui->tabWidget->count(); i++)
00111     {
00112         PlotMatrix* widget = static_cast<PlotMatrix*>( ui->tabWidget->widget(i) );
00113         QDomElement element = widget->xmlSaveState(doc);
00114 
00115         element.setAttribute("tab_name",  ui->tabWidget->tabText(i) );
00116         tabbed_area.appendChild( element );
00117     }
00118 
00119     QDomElement current_plotmatrix =  doc.createElement( "currentPlotMatrix" );
00120     current_plotmatrix.setAttribute( "index", ui->tabWidget->currentIndex() );
00121     tabbed_area.appendChild( current_plotmatrix );
00122 
00123     return tabbed_area;
00124 }
00125 
00126 bool TabbedPlotWidget::xmlLoadState(QDomElement &tabbed_area)
00127 {
00128     int num_tabs =  ui->tabWidget->count();
00129     int index = 0;
00130 
00131     QDomElement plotmatrix_el;
00132 
00133     for (  plotmatrix_el = tabbed_area.firstChildElement( "plotmatrix" )  ;
00134            !plotmatrix_el.isNull();
00135            plotmatrix_el = plotmatrix_el.nextSiblingElement( "plotmatrix" ) )
00136     {
00137         // add if tabs are too few
00138         if( index == num_tabs)
00139         {
00140             this->addTab( NULL );
00141             num_tabs++;
00142         }
00143         PlotMatrix* plot_matrix = static_cast<PlotMatrix*>(  ui->tabWidget->widget(index) );
00144         bool success = plot_matrix->xmlLoadState( plotmatrix_el );
00145 
00146         // read tab name
00147         if( plotmatrix_el.hasAttribute("tab_name"))
00148         {
00149             QString tab_name = plotmatrix_el.attribute("tab_name" );
00150             ui->tabWidget->setTabText( index, tab_name );
00151             plot_matrix->setName( tab_name );
00152         }
00153 
00154         if( !success )
00155         {
00156             return false;
00157         }
00158 
00159         index++;
00160     }
00161 
00162     // remove if tabs are too much
00163     while( num_tabs > index ){
00164         ui->tabWidget->removeTab( num_tabs-1 );
00165         num_tabs--;
00166     }
00167 
00168     QDomElement current_plotmatrix =  tabbed_area.firstChildElement( "currentPlotMatrix" );
00169     int current_index = current_plotmatrix.attribute( "index" ).toInt();
00170 
00171     if(current_index>=0 && current_index < ui->tabWidget->count())
00172     {
00173         ui->tabWidget->setCurrentIndex( current_index );
00174         currentTab()->replot();
00175     }
00176     return true;
00177 }
00178 
00179 void TabbedPlotWidget::setStreamingMode(bool streaming_mode)
00180 {
00181     ui->buttonLinkHorizontalScale->setEnabled( !streaming_mode );
00182     ui->pushVerticalResize->setEnabled( !streaming_mode );
00183     ui->pushHorizontalResize->setEnabled( !streaming_mode );
00184 }
00185 
00186 
00187 TabbedPlotWidget::~TabbedPlotWidget(){
00188 
00189     delete ui;
00190 }
00191 
00192 void TabbedPlotWidget::on_renameCurrentTab()
00193 {
00194     int idx = ui->tabWidget->tabBar()->currentIndex ();
00195 
00196     bool ok = true;
00197     QString newName = QInputDialog::getText (
00198                 this, tr ("Change Name of the selected tab"),
00199                 tr ("Insert New Tab Name"),
00200                 QLineEdit::Normal,
00201                 ui->tabWidget->tabText (idx),
00202                 &ok);
00203 
00204     if (ok) {
00205         ui->tabWidget->setTabText (idx, newName);
00206         currentTab()->setName( newName );
00207     }
00208 }
00209 
00210 void TabbedPlotWidget::on_savePlotsToFile()
00211 {
00212     int idx = ui->tabWidget->tabBar()->currentIndex();
00213     PlotMatrix* matrix = static_cast<PlotMatrix*>( ui->tabWidget->widget(idx) );
00214 
00215     QFileDialog saveDialog;
00216     saveDialog.setAcceptMode(QFileDialog::AcceptSave);
00217     saveDialog.setDefaultSuffix("png");
00218 
00219 #ifndef QWT_NO_SVG
00220     saveDialog.setNameFilter("Compatible formats (*.jpg *.jpeg *.svg *.png)");
00221 #else
00222     saveDialog.setNameFilter("Compatible formats (*.jpg *.jpeg *.png)");
00223 #endif
00224     saveDialog.exec();
00225 
00226     if(saveDialog.result() == QDialog::Accepted && !saveDialog.selectedFiles().empty())
00227     {
00228         QString fileName = saveDialog.selectedFiles().first();
00229 
00230         QPixmap pixmap (1200,900);
00231         QPainter * painter = new QPainter(&pixmap);
00232 
00233         if ( !fileName.isEmpty() )
00234         {
00235             QwtPlotRenderer rend;
00236 
00237             int delta_X = pixmap.width() /  matrix->colsCount();
00238             int delta_Y = pixmap.height() /  matrix->rowsCount();
00239 
00240             for (int c=0; c< matrix->colsCount(); c++)
00241             {
00242                 for (int r=0; r< matrix->rowsCount(); r++)
00243                 {
00244                     PlotWidget* widget = matrix->plotAt(r,c);
00245                     QRect rect(delta_X*c, delta_Y*r, delta_X, delta_Y);
00246                     rend.render(widget,painter, rect);
00247                 }
00248             }
00249             pixmap.save(fileName);
00250         }
00251     }
00252 }
00253 
00254 void TabbedPlotWidget::on_pushAddColumn_pressed()
00255 {
00256     currentTab()->addColumn();
00257     emit undoableChangeHappened();
00258 }
00259 
00260 void TabbedPlotWidget::on_pushVerticalResize_pressed()
00261 {
00262     currentTab()->maximumZoomOutVertical();
00263     emit undoableChangeHappened();
00264 }
00265 
00266 void TabbedPlotWidget::on_pushHorizontalResize_pressed()
00267 {
00268     currentTab()->maximumZoomOutHorizontal();
00269     emit undoableChangeHappened();
00270 }
00271 
00272 void TabbedPlotWidget::on_pushAddRow_pressed()
00273 {
00274     currentTab()->addRow();
00275     emit undoableChangeHappened();
00276 }
00277 
00278 void TabbedPlotWidget::on_addTabButton_pressed()
00279 {
00280     addTab( NULL );
00281     emit undoableChangeHappened();
00282 }
00283 
00284 void TabbedPlotWidget::on_pushRemoveEmpty_pressed()
00285 {
00286     PlotMatrix *tab = currentTab();
00287 
00288     for( unsigned row = 0; row< tab->rowsCount(); row++)
00289     {
00290         while( tab->rowsCount() > 1 &&
00291                tab->isRowEmpty( row ) &&
00292                row < tab->rowsCount() )
00293         {
00294             tab->removeRow( row );
00295         }
00296     }
00297 
00298     for( unsigned col = 0; col< tab->colsCount(); col++)
00299     {
00300         while( tab->colsCount() > 1 &&
00301                tab->isColumnEmpty( col ) &&
00302                col < tab->colsCount() )
00303         {
00304             tab->removeColumn( col );
00305         }
00306     }
00307 
00308     emit undoableChangeHappened();
00309 }
00310 
00311 void TabbedPlotWidget::on_tabWidget_currentChanged(int index)
00312 {
00313     if( ui->tabWidget->count() == 0)
00314     {
00315         if( _parent_type.compare("main_window") == 0)
00316         {
00317             addTab( NULL);
00318         }
00319         else{
00320             this->parent()->deleteLater();
00321         }
00322     }
00323 
00324     PlotMatrix* tab = static_cast<PlotMatrix*>( ui->tabWidget->widget(index) );
00325     if( tab )
00326     {
00327         tab->replot();
00328     }
00329 }
00330 
00331 void TabbedPlotWidget::on_tabWidget_tabCloseRequested(int index)
00332 {
00333     PlotMatrix* tab = static_cast<PlotMatrix*>( ui->tabWidget->widget(index) );
00334 
00335     bool ask_confirmation = true;
00336     if( tab->plotCount() == 1 )
00337     {
00338         if( tab->plotAt(0)->isEmpty()){
00339             ask_confirmation = false;
00340         }
00341     }
00342 
00343     QMessageBox::StandardButton do_remove = QMessageBox::Yes;
00344 
00345     if( ask_confirmation )
00346     {
00347         ui->tabWidget->setCurrentIndex( index );
00348         QApplication::processEvents();
00349 
00350         do_remove = QMessageBox::question(0, tr("Warning"),
00351                                           tr("Do you really want to destroy this tab?\n"),
00352                                           QMessageBox::Yes | QMessageBox::No,
00353                                           QMessageBox::No );
00354     }
00355     if( do_remove == QMessageBox::Yes )
00356     {
00357         // first add then delete.
00358         // Otherwise currentPlotGrid might be empty
00359         if( ui->tabWidget->count() == 1){
00360             on_addTabButton_pressed();
00361         }
00362         ui->tabWidget->removeTab( index );
00363         emit undoableChangeHappened();
00364     }
00365 }
00366 
00367 void TabbedPlotWidget::on_buttonLinkHorizontalScale_toggled(bool checked)
00368 {
00369     _horizontal_link = checked;
00370 
00371     for (int i = 0; i < ui->tabWidget->count(); i++)
00372     {
00373         PlotMatrix* tab = static_cast<PlotMatrix*>( ui->tabWidget->widget(i) );
00374         tab->setHorizontalLink( _horizontal_link );
00375     }
00376 }
00377 
00378 void TabbedPlotWidget::on_requestTabMovement(const QString & destination_name)
00379 {
00380     TabbedPlotWidget* destination_widget = TabbedPlotWidget::_instances[destination_name];
00381 
00382     PlotMatrix* tab_to_move = currentTab();
00383     int index = ui->tabWidget->tabBar()->currentIndex ();
00384 
00385     const QString& tab_name =  this->tabWidget()->tabText(index);
00386 
00387     destination_widget->tabWidget()->addTab( tab_to_move, tab_name );
00388 
00389     qDebug() << "move "<< tab_name<< " into " << destination_name;
00390     emit undoableChangeHappened();
00391 
00392 }
00393 
00394 void TabbedPlotWidget::on_moveTabIntoNewWindow()
00395 {
00396     emit sendTabToNewWindow( currentTab() );
00397 }
00398 
00399 
00400 bool TabbedPlotWidget::eventFilter(QObject *obj, QEvent *event)
00401 {
00402     QTabBar* tab_bar = ui->tabWidget->tabBar();
00403 
00404     if (obj == tab_bar )
00405     {
00406         if( event->type() == QEvent::MouseButtonPress)
00407         {
00408             QMouseEvent *mouse_event = static_cast<QMouseEvent*>(event);
00409 
00410             int index = tab_bar->tabAt( mouse_event->pos() );
00411             tab_bar->setCurrentIndex( index );
00412 
00413 
00414             if( mouse_event->button() == Qt::RightButton )
00415             {
00416                 QMenu* submenu = new QMenu("Move tab to...");
00417                 _tab_menu->addMenu( submenu );
00418 
00419                 std::map<QString,TabbedPlotWidget*>::iterator it;
00420                 QSignalMapper* signalMapper = new QSignalMapper(submenu);
00421 
00422                 //-----------------------------------
00423                 QAction* action_new_window = submenu->addAction( "New Window" );
00424 
00425                 QIcon icon;
00426                 icon.addFile(QStringLiteral(":/icons/resources/stacks_32px.png"), QSize(16, 16));
00427 
00428                 action_new_window->setIcon( icon);
00429                 submenu->addSeparator();
00430 
00431                 connect( action_new_window, &QAction::triggered, this, &TabbedPlotWidget::on_moveTabIntoNewWindow );
00432 
00433                 //-----------------------------------
00434                 for (auto it : TabbedPlotWidget::_instances)
00435                 {
00436                     QString name = it.first;
00437                     TabbedPlotWidget* tabbed_menu = it.second;
00438                     if( tabbed_menu != this )
00439                     {
00440                         QAction* action = submenu->addAction( name );
00441                         connect(action, SIGNAL(triggered()), signalMapper, SLOT(map()));
00442                         signalMapper->setMapping( action, name );
00443                     }
00444                 }
00445 
00446                 connect(signalMapper, SIGNAL(mapped(QString)), this, SLOT(on_requestTabMovement(QString)) );
00447 
00448                 //-------------------------------
00449                 _tab_menu->exec( mouse_event->globalPos() );
00450                 //-------------------------------
00451                 submenu->deleteLater();
00452             }
00453         }
00454     }
00455 
00456     // Standard event processing
00457     return QObject::eventFilter(obj, event);
00458 }
00459 
00460 void TabbedPlotWidget::on_pushButtonShowLabel_toggled(bool checked)
00461 {    
00462     for(int i=0; i< ui->tabWidget->count(); i++)
00463     {
00464         PlotMatrix* matrix = static_cast<PlotMatrix*>( ui->tabWidget->widget(i) );
00465 
00466         for(unsigned p=0; p< matrix->plotCount(); p++)
00467         {
00468             PlotWidget* plot = matrix->plotAt(p);
00469             plot->activateLegent( checked );
00470         }
00471     }
00472     currentTab()->replot();
00473 }
00474 
00475 void TabbedPlotWidget::closeEvent(QCloseEvent *event)
00476 {
00477   TabbedPlotWidget::_instances.erase(name());
00478 }
00479 
00480 const std::map<QString, TabbedPlotWidget *> &TabbedPlotWidget::instances()
00481 {
00482     return TabbedPlotWidget::_instances;
00483 }
00484 
00485 TabbedPlotWidget* TabbedPlotWidget::instance(const QString &key)
00486 {
00487     auto it = TabbedPlotWidget::_instances.find(key);
00488     if( it == TabbedPlotWidget::_instances.end())
00489     {
00490         return nullptr;
00491     }
00492     else{
00493         return it->second;
00494     }
00495 }
00496 
00497 void TabbedPlotWidget::setControlsVisible(bool visible)
00498 {
00499     ui->widgetControls->setVisible(visible);
00500 }
00501 


plotjuggler
Author(s): Davide Faconti
autogenerated on Fri Sep 1 2017 02:41:57