Commit 45084711 authored by Augustin Degomme's avatar Augustin Degomme

Feature : add an Interval Selection Window, allowing to select a displayable...

Feature : add an Interval Selection Window, allowing to select a displayable interval on the trace. (Preferences/Interval Selection)

Combined with IntervalOfContainers and Serialization, this allows to change the displayed interval and load only the data of the wanted interval, while freeing memory for non displayed zones.
parent d5e3f649
......@@ -101,6 +101,9 @@ SET(VITE_HDRS
interface/Interface_graphic.hpp
interface/Node_select.hpp
interface/viteqtreewidget.hpp
interface/Interval_select.hpp
interface/qxtspanslider.h
interface/qxtspanslider_p.h
# Core header
core/Core.hpp
core/getopt.h
......@@ -143,6 +146,7 @@ SET(VITE_UIS
interface/global_cmd.ui
interface/list_of_counter_to_export.ui
interface/node_select.ui
interface/interval_select.ui
)
SET(VITE_SRCS
......@@ -214,6 +218,8 @@ SET(VITE_SRCS
interface/Interface_graphic.cpp
interface/Node_select.cpp
interface/viteqtreewidget.cpp
interface/Interval_select.cpp
interface/qxtspanslider.cpp
# Plugin code file
plugin/Command_window.cpp
plugin/Plugin_window.cpp
......
......@@ -69,6 +69,8 @@ bool Info::Render::_key_alt = false;
bool Info::Render::_key_ctrl = false;
Element_pos Info::Render::_x_min_visible = 0.0;
Element_pos Info::Render::_x_max_visible = 0.0;
Element_pos Info::Render::_x_min = 0.0;
Element_pos Info::Render::_x_max = 0.0;
Element_pos Info::Render::_info_x = 0.0;
Element_pos Info::Render::_info_y = 0.0;
......@@ -84,8 +86,8 @@ bool Info::Splitter::load_splitted = false;
bool Info::Splitter::preview = false;
std::string Info::Splitter::path ;
std::string Info::Splitter::filename ;
Element_pos Info::Splitter::_x_min = 0.;
Element_pos Info::Splitter::_x_max = 0.;
Element_pos Info::Splitter::_x_min = 0.0;
Element_pos Info::Splitter::_x_max = 0.0;
int Info::Trace::depth=0;
......
......@@ -199,6 +199,16 @@ public:
*/
static Element_pos _x_min_visible;
/*!
* \brief Contains the trace maximum visible time.
*/
static Element_pos _x_max;
/*!
* \brief Contains the trace minimum visible time, uncorrected (state width isn't removed)
*/
static Element_pos _x_min;
/*!
* \brief Contains the trace maximum visible time.
*/
......
......@@ -119,6 +119,7 @@ Interface_graphic::Interface_graphic(Core* core, QWidget *parent):QMainWindow(pa
_plugin_window = NULL;
_ui_settings = NULL;
_ui_node_selection=NULL;
_ui_interval_selection=NULL;
// _cmd_window = NULL;
_cmd_window = new Command_window(this,this);
......@@ -130,6 +131,13 @@ Interface_graphic::Interface_graphic(Core* core, QWidget *parent):QMainWindow(pa
connect(quit, SIGNAL(triggered()), _ui_node_selection, SLOT(close()));
}
if (!_ui_interval_selection) {
_ui_interval_selection = new Interval_select(this, 0);
//connect( _ui_node_selection, SIGNAL(settings_changed()), this, SLOT(update_settings()));
// To close the window when we quit the application
connect(quit, SIGNAL(triggered()), _ui_interval_selection, SLOT(close()));
}
// For drag and drop operations
setAcceptDrops(true);
}
......@@ -436,6 +444,9 @@ void Interface_graphic::change_zoom_box_value(int new_value){
else{
_ui_zoom_box->setCurrentIndex(index);/* value exists, select it */
}
//update the interval selection display
if(_ui_interval_selection!=NULL)_ui_interval_selection->update_values();
}
......@@ -727,6 +738,7 @@ void Interface_graphic::on_close_triggered(){
void Interface_graphic::on_quit_triggered(){
((QWidget*)_ui_node_selection)->close();
((QWidget*)_ui_interval_selection)->close();
((QWidget*)_ui_help_window)->close();
((QWidget*)this)->close();
}
......@@ -863,6 +875,21 @@ void Interface_graphic::on_show_settings_triggered() {
//}
_ui_node_selection->show();
}
void Interface_graphic::on_interval_selection_triggered() {
//if (!_ui_node_selection) {
// _ui_node_selection = new Node_select(this, 0);
if(!_ui_interval_selection->get_trace() && _core->get_trace()){//first use
_ui_interval_selection->set_trace(_core->get_trace());
}
//connect( _ui_node_selection, SIGNAL(settings_changed()), this, SLOT(update_settings()));
// To close the window when we quit the application
//connect(quit, SIGNAL(triggered()), _ui_node_selection, SLOT(close()));
//}
_ui_interval_selection->show();
}
void Interface_graphic::on_actionCommand_triggered(){
if(_core->get_trace()){
......@@ -1004,6 +1031,9 @@ void Interface_graphic::closeEvent(QCloseEvent *event){
if(_ui_node_selection)
_ui_node_selection->close();
if(_ui_interval_selection)
_ui_interval_selection->close();
}
const std::string Interface_graphic::get_filename() const{
......@@ -1018,6 +1048,11 @@ Core * Interface_graphic::get_console(){
Node_select* Interface_graphic::get_node_select(){
return _ui_node_selection;
}
Interval_select* Interface_graphic::get_interval_select(){
return _ui_interval_selection;
}
void Interface_graphic::update_recent_files_menu() {
const QStringList filenames = Session::get_recent_files();
QString absoluteFilename;
......
......@@ -71,6 +71,7 @@ class QProgressDialog;
#include "interface/Interface.hpp"
#include "interface/Settings_window.hpp"
#include "interface/Node_select.hpp"
#include "interface/Interval_select.hpp"
/*!
*\brief This class is a graphical interface which creates a window, it inherited from the Interface interface.
......@@ -224,6 +225,11 @@ class Interface_graphic : public QMainWindow, protected Ui::main_window, public
*/
Node_select* _ui_node_selection;
/*!
* \brief Dialog box to allow user to select nodes to display
*/
Interval_select* _ui_interval_selection;
/*!
* \brief Text area which informs the user about the trace resume.
*/
......@@ -483,6 +489,13 @@ public:
*/
Node_select* get_node_select();
/*!
* \fn get_interval_select()
* \brief To get the node selection console
*/
Interval_select* get_interval_select();
/*!
* \fn update_recent_files_menu()
* \brief update the recent files opened menu
......@@ -607,6 +620,11 @@ protected slots:
*/
void on_node_selection_triggered();
/*!
*\brief A slot called when 'Node selection' in the menu is clicked.
*/
void on_interval_selection_triggered();
/*!
* \brief A slot called when 'command' in the menu is clicked.
*/
......
/*
** This file is part of the ViTE project.
**
** This software is governed by the CeCILL-A license under French law
** and abiding by the rules of distribution of free software. You can
** use, modify and/or redistribute the software under the terms of the
** CeCILL-A license as circulated by CEA, CNRS and INRIA at the following
** URL: "http://www.cecill.info".
**
** As a counterpart to the access to the source code and rights to copy,
** modify and redistribute granted by the license, users are provided
** only with a limited warranty and the software's author, the holder of
** the economic rights, and the successive licensors have only limited
** liability.
**
** In this respect, the user's attention is drawn to the risks associated
** with loading, using, modifying and/or developing or reproducing the
** software by the user in light of its specific status of free software,
** that may mean that it is complicated to manipulate, and that also
** therefore means that it is reserved for developers and experienced
** professionals having in-depth computer knowledge. Users are therefore
** encouraged to load and test the software's suitability as regards
** their requirements in conditions enabling the security of their
** systems and/or data to be ensured and, more generally, to use and
** operate it in the same conditions as regards security.
**
** The fact that you are presently reading this means that you have had
** knowledge of the CeCILL-A license and that you accept its terms.
**
**
** ViTE developers are (for version 0.* to 1.0):
**
** - COULOMB Kevin
** - FAVERGE Mathieu
** - JAZEIX Johnny
** - LAGRASSE Olivier
** - MARCOUEILLE Jule
** - NOISETTE Pascal
** - REDONDY Arthur
** - VUCHENER Clément
**
*/
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <map>
#include <set>
#include <list>
#include <stack>
#include <vector>
/* -- */
#include "common/common.hpp"
#include "common/Info.hpp"
#include "common/Message.hpp"
#include "interface/resource.hpp"
#include "interface/Interface.hpp"
#include "core/Core.hpp"
#include "interface/Interface_graphic.hpp"
/* -- */
#include "trace/values/Values.hpp"
#include "trace/EntityValue.hpp"
#include "trace/EntityTypes.hpp"
#include "trace/Entitys.hpp"
#include "trace/tree/Interval.hpp"
#include "trace/Container.hpp"
/* -- */
#include <QKeyEvent>
#include "interface/Interval_select.hpp"
using namespace std;
Interval_select::Interval_select(Interface_graphic * console,QWidget *parent) : QDialog(parent), _trace(NULL),_console(console) {
setupUi(this);
connect( minSpinBox, SIGNAL(valueChanged( double )), SLOT(minSpinBoxValueChanged( double ) ) );
connect( interval_slider, SIGNAL(lowerValueChanged( int )), SLOT(minSliderValueChanged( int ) ) );
connect( maxSpinBox, SIGNAL(valueChanged( double )), SLOT(maxSpinBoxValueChanged( double ) ) );
connect( interval_slider, SIGNAL(upperValueChanged( int )), SLOT(maxSliderValueChanged( int ) ) );
QMetaObject::connectSlotsByName(NULL);
_auto_refresh=auto_refresh_box->isChecked();//true by default
_applied=false;
//interval_slider->setHandleMovementMode(QxtSpanSlider::NoOverlapping);
}
Interval_select::~Interval_select() {
}
Trace* Interval_select::get_trace() {
return _trace;
}
void Interval_select::set_trace(Trace *trace) {
// Initialize _trace
_trace = trace;
//double max =_trace->get_max_date().get_value();
min_value->setText(QString().setNum (Info::Entity::x_min));
max_value->setText(QString().setNum (Info::Entity::x_max));
minSpinBox->setMinimum(Info::Entity::x_min);
minSpinBox->setMaximum(Info::Entity::x_max);
maxSpinBox->setMinimum(Info::Entity::x_min);
maxSpinBox->setMaximum(Info::Entity::x_max);
//the slider stays in int, we will translate its values
/*interval_slider->setMinimum(0);
interval_slider->setMaximum(99);*/
double delta=Info::Entity::x_max-Info::Entity::x_min;
double step= 0.001*delta; //make steps of .1% for spinboxes
minSpinBox->setSingleStep(step);
maxSpinBox->setSingleStep(step);
update_values();
}
//called if a zoom is triggered outside of the window, to update slider position and spinboxes with the real values
void Interval_select::update_values() {
if(_trace!=NULL){//if init
Element_pos _min;
Element_pos _max;
//choose which value to load the actual position from (can change if we are loading from a splitted file set)
if(Info::Splitter::preview==true){
_min=Info::Entity::x_min;
_max=Info::Entity::x_max;
}else if(Info::Splitter::load_splitted==true){
Info::Render::_x_min=Info::Splitter::_x_min;
Info::Render::_x_max=Info::Splitter::_x_max;
auto_refresh_box->setChecked(false);//set the checkbox to false because reload is expensive for splitted mode
_min=Info::Splitter::_x_min;
_max=Info::Splitter::_x_max;
}else{
_min=Info::Render::_x_min;
_max=Info::Render::_x_max;
}
bool v = minSpinBox->blockSignals(true);
bool v2 = maxSpinBox->blockSignals(true);
bool v3 = interval_slider->blockSignals(true);
int maxvalue=int(_max*(interval_slider->maximum() - interval_slider->minimum())/(minSpinBox->maximum() - minSpinBox->minimum()));
interval_slider->setUpperValue(maxvalue);
interval_slider->setLowerValue(int(_min*(interval_slider->maximum() - interval_slider->minimum())/(minSpinBox->maximum() - minSpinBox->minimum())));
maxSpinBox->setValue(_max);
minSpinBox->setValue(_min);
minSpinBox->blockSignals(v);
maxSpinBox->blockSignals(v2);
interval_slider->blockSignals(v3);
_applied=false;
}
}
void Interval_select::minSpinBoxValueChanged( double _value )
{
QPalette myPalette(minSpinBox->palette());
if(_value < maxSpinBox->value()){
bool v = interval_slider->blockSignals(true);
interval_slider->setLowerValue( int(_value *(interval_slider->maximum() - interval_slider->minimum())/(minSpinBox->maximum() - minSpinBox->minimum())) );
interval_slider->blockSignals(v);
emit( minValueChanged( minSpinBox->value() ) );
myPalette.setColor(QPalette::Active, QPalette::Text, Qt::black);
myPalette.setColor(QPalette::Active, QPalette::HighlightedText, Qt::white);
if(_auto_refresh)apply_settings();
}else{
//min cannot be greater than max
//set the incorrect value to red, but don't change it in order to let the user type a full correct value
myPalette.setColor(QPalette::Active, QPalette::Text, Qt::red);
myPalette.setColor(QPalette::Active, QPalette::HighlightedText, Qt::red);
//minSliderValueChanged( maxSpinBox->value() );
}
minSpinBox->setPalette(myPalette);
maxSpinBox->setPalette(myPalette);
_applied=false;
}
void Interval_select::minSliderValueChanged( int _value )
{
if(_value < interval_slider->upperValue()){
bool v = minSpinBox->blockSignals(true);
minSpinBox->setValue( _value *(minSpinBox->maximum() - minSpinBox->minimum())/(interval_slider->maximum() - interval_slider->minimum()));
minSpinBox->blockSignals(v);
emit( minValueChanged( minSpinBox->value() ) );
if(_auto_refresh)apply_settings();
}
_applied=false;
}
void Interval_select::maxSpinBoxValueChanged( double _value )
{
QPalette myPalette(minSpinBox->palette());
if(_value > minSpinBox->value()){
bool v = interval_slider->blockSignals(true);
interval_slider->setUpperValue( int(_value* (interval_slider->maximum() - interval_slider->minimum())/(maxSpinBox->maximum() - maxSpinBox->minimum())));
interval_slider->blockSignals(v);
emit( maxValueChanged( maxSpinBox->value() ) );
myPalette.setColor(QPalette::Active, QPalette::Text, Qt::black);
myPalette.setColor(QPalette::Active, QPalette::HighlightedText, Qt::white);
if(_auto_refresh)apply_settings();
}else{
//max cannot be lower than min
myPalette.setColor(QPalette::Active, QPalette::Text, Qt::red);
myPalette.setColor(QPalette::Active, QPalette::HighlightedText, Qt::red);
//maxSliderValueChanged( minSpinBox->value() ) ;
}
maxSpinBox->setPalette(myPalette);
minSpinBox->setPalette(myPalette);
_applied=false;
}
void Interval_select::maxSliderValueChanged( int _value )
{
if(_value > interval_slider->lowerValue()){
bool v = maxSpinBox->blockSignals(true);
maxSpinBox->setValue( _value * (maxSpinBox->maximum() - maxSpinBox->minimum())/(interval_slider->maximum() - interval_slider->minimum()));
maxSpinBox->blockSignals(v);
emit( maxValueChanged( maxSpinBox->value() ) );
if(_auto_refresh)apply_settings();
}
_applied=false;
}
void Interval_select::apply_settings(){
if(minSpinBox->value()!=maxSpinBox->value()){
Element_pos zoom[2]={minSpinBox->value(), maxSpinBox->value()};
Info::Render::_x_min_visible = 0.0;
Info::Render::_x_max_visible = 0.0;
_console->get_console()->launch_action(Core:: _STATE_CLEAN_RENDER_AREA);
//reload data from disk if needed
#if defined(USE_ITC) && defined(BOOST_SERIALIZE)
Info::Splitter::_x_min=zoom[0];
Info::Splitter::_x_max=zoom[1];
_trace->updateTrace(new Interval(zoom[0], zoom[1]));
#endif
_console->get_console()->draw_trace(_console->get_filename(),Core::_DRAW_OPENGL);
_console->get_console()->launch_action(Core:: _STATE_ZOOM_IN_AN_INTERVAL, &zoom);
_console->get_console()->launch_action(Core:: _STATE_RENDER_UPDATE);
}
}
void Interval_select::on_apply_button_clicked(){
apply_settings();
_applied=true;
}
void Interval_select::on_cancel_button_clicked(){
hide();
}
void Interval_select::on_ok_button_clicked(){
if(!_applied)on_apply_button_clicked();
hide();
}
void Interval_select::on_reset_button_clicked(){
//maxValueChanged( interval_slider->maximum() );
//minValueChanged( interval_slider->minimum() );
interval_slider->setUpperValue(interval_slider->maximum());
interval_slider->setLowerValue(interval_slider->minimum());
//maxSliderValueChanged( interval_slider->maximum() );
//minSliderValueChanged( interval_slider->minimum() );
}
void Interval_select::on_auto_refresh_box_stateChanged(){
_auto_refresh=auto_refresh_box->isChecked();
}
/*
void Stats_window::init() {
// We set the names of the containers for the tree widget
_nodes_selected->clear();
set_container_names();
// We init the times
_start_time = Info::Render::_x_min_visible;
_end_time = Info::Render::_x_max_visible;
QString temp;
temp.setNum(_start_time);
_start_time_widget->setText(temp);
temp.setNum(_end_time);
_end_time_widget->setText(temp);
_ui_stats_area->clear();
Reinit_scroll_bars();
}
void Stats_window::clear() {
_ui_stats_area->makeCurrent();
_nodes_selected->clear();
_ui_stats_area->clear();
_kind_of_state_box->clear();
Reinit_scroll_bars();
_ui_stats_area->doneCurrent();
}
void Stats_window::set_arguments(std::map<std::string , QVariant *>) {
}
void Stats_window::execute() {
on_reload_button_clicked();
}
string Stats_window::get_name() {
return "Statistics window";
}*/
/*
** This file is part of the ViTE project.
**
** This software is governed by the CeCILL-A license under French law
** and abiding by the rules of distribution of free software. You can
** use, modify and/or redistribute the software under the terms of the
** CeCILL-A license as circulated by CEA, CNRS and INRIA at the following
** URL: "http://www.cecill.info".
**
** As a counterpart to the access to the source code and rights to copy,
** modify and redistribute granted by the license, users are provided
** only with a limited warranty and the software's author, the holder of
** the economic rights, and the successive licensors have only limited
** liability.
**
** In this respect, the user's attention is drawn to the risks associated
** with loading, using, modifying and/or developing or reproducing the
** software by the user in light of its specific status of free software,
** that may mean that it is complicated to manipulate, and that also
** therefore means that it is reserved for developers and experienced
** professionals having in-depth computer knowledge. Users are therefore
** encouraged to load and test the software's suitability as regards
** their requirements in conditions enabling the security of their
** systems and/or data to be ensured and, more generally, to use and
** operate it in the same conditions as regards security.
**
** The fact that you are presently reading this means that you have had
** knowledge of the CeCILL-A license and that you accept its terms.
**
**
** ViTE developers are (for version 0.* to 1.0):
**
** - COULOMB Kevin
** - FAVERGE Mathieu
** - JAZEIX Johnny
** - LAGRASSE Olivier
** - MARCOUEILLE Jule
** - NOISETTE Pascal
** - REDONDY Arthur
** - VUCHENER Clément
**
*/
/*!
*\file Interval_select.hpp
*/
#ifndef INTERVAL_SELECT_HPP
#define INTERVAL_SELECT_HPP
class Interval_select;
/* For moc compilation */
#include <string>
#include <map>
#include <list>
/* -- */
#include <QWidget>
#include "ui_interval_select.h"
#include "trace/values/Values.hpp"
#include "trace/EntityValue.hpp"
#include "trace/EntityTypes.hpp"
#include "trace/Entitys.hpp"
#include "trace/tree/Interval.hpp"
#include "trace/Trace.hpp"
#include "interface/Interface_graphic.hpp"
/* -- */
/*!
* \class Node select
* \brief Class used to select which containers should be displayed
*
*/
class Interval_select : public QDialog, protected Ui::interval_selector {
Q_OBJECT
private:
Trace* _trace;
Interface_graphic *_console;
bool _applied;
bool _auto_refresh;
public:
/*!
* Default constructor
* \param parent The parent widget of the window.
*/
Interval_select( Interface_graphic *console, QWidget *parent = 0);
~Interval_select();
/*!
* \fn set_trace(Trace *trace)
* \brief Set the trace parsed (give the container names)
* \param trace The trace.
*/
void set_trace(Trace *trace);
/*!
* \fn get_trace()
* \brief returns the trace
*/
Trace * get_trace();
void apply_settings();
void update_values();
private slots:
void minSpinBoxValueChanged( double value );
void minSliderValueChanged( int value );
void maxSpinBoxValueChanged( double value );
void maxSliderValueChanged( int value );
void on_ok_button_clicked();
void on_cancel_button_clicked();
void on_reset_button_clicked();
void on_apply_button_clicked();
void on_auto_refresh_box_stateChanged();
signals:
void minValueChanged( double value );
void maxValueChanged( double value );
};
#endif // INTERVAL_SELECT_HPP
......@@ -260,7 +260,7 @@ void Stats_window::set_selected_nodes(string kind_of_state){
_nodes_displayed->clear();
//can we load that from _nodes_original instead ?
set_displayed_container_names();
Element_pos zoom[2]={Info::Render::_x_min_visible, Info::Render::_x_max_visible};
Element_pos zoom[2]={Info::Render::_x_min, Info::Render::_x_max};
Info::Render::_x_min_visible = 0.0;
Info::Render::_x_max_visible = 0.0;
_trace->set_view_root_containers(_displayed_containers);
......@@ -335,7 +335,7 @@ void Node_select::on_load_button_clicked(){
build_displayed_nodes(_displayed_containers);
_trace->set_view_root_containers(_displayed_containers);
Element_pos it[2]={Info::Render::_x_min_visible, Info::Render::_x_max_visible};
Element_pos it[2]={Info::Render::_x_min, Info::Render::_x_max};
Info::Render::_x_min_visible = 0.0;
Info::Render::_x_max_visible = 0.0;
......
......@@ -189,7 +189,6 @@ private slots:
void on_export_button_clicked();
void on_load_button_clicked();
public slots: // just for testing, remove
void on_display_button_clicked();
};
......
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>interval_selector</class>
<widget class="QDialog" name="interval_selector">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>522</width>
<height>283</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>522</width>
<height>283</height>
</size>
</property>
<property name="windowTitle">
<string>Interval Selection</string>
</property>
<widget class="QxtSpanSlider" name="interval_slider">
<property name="geometry">
<rect>
<x>60</x>
<y>140</y>
<width>401</width>
<height>20</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
<widget class="QDoubleSpinBox" name="minSpinBox">
<property name="geometry">
<rect>
<x>140</x>
<y>80</y>
<width>101</width>
<height>22</height>
</rect>
</property>
</widget>
<widget class="QDoubleSpinBox" name="maxSpinBox">
<property name="geometry">
<rect>