diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f88a82bda376f3bccee6073e4b0908bbccb3780b..9236fcc4add89e5e39ec40d2297feb940f3da90b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -98,8 +98,11 @@ SET(VITE_HDRS interface/Interface.hpp interface/Settings_window.hpp interface/Interface_graphic.hpp + interface/Node_select.hpp + interface/viteqtreewidget.hpp # Core header core/Core.hpp + core/getopt.h # Parser headers parser/ParsingThread.hpp parser/Parser.hpp @@ -132,6 +135,7 @@ SET(VITE_UIS interface/stats_viewer.ui interface/global_cmd.ui interface/list_of_counter_to_export.ui + interface/node_select.ui ) SET(VITE_SRCS @@ -194,12 +198,15 @@ SET(VITE_SRCS # Interface code files interface/Settings_window.cpp interface/Interface_graphic.cpp + interface/Node_select.cpp + interface/viteqtreewidget.cpp # Plugin code file plugin/Command_window.cpp plugin/Plugin_window.cpp plugin/Plugin.cpp # Core code files core/Core.cpp + core/getopt.c # Main main.cpp ) diff --git a/src/core/Core.cpp b/src/core/Core.cpp index 12f1a71cf38e2c6ad4099348f145e2bd56adb46c..c4e24463c56f24a1ec3b0e1de14afdcf59aff591 100644 --- a/src/core/Core.cpp +++ b/src/core/Core.cpp @@ -55,11 +55,17 @@ #include <map> #include <vector> #include <stack> +#ifndef WIN32 #include <cmath> -#include <unistd.h> +#include <unistd.h>* #if defined(HAVE_GETOPT_H) #include <getopt.h> #endif /* defined(HAVE_GETOPT_H) */ + +#else +#include <core/getopt.h> +#endif + /* -- */ #include <QObject> //#include <QtUiTools>/* for the run-time loading .ui file */ @@ -102,6 +108,7 @@ /* -- */ #include "statistics/Stats_window.hpp" /* -- */ +#include "interface/Node_select.hpp" #include "interface/Interface_graphic.hpp" #include "core/Core.hpp" /* -- */ @@ -320,18 +327,24 @@ bool Core::draw_trace(const string & filename, const int format) { if (Info::Render::_x_min_visible == Info::Render::_x_max_visible){// first time _trace->set_interval_constrained(new Interval(0,_trace->get_max_date())); }else{ - // _trace->set_interval_constrained(new Interval(Info::Render::_x_min_visible, Info::Render::_x_max_visible)); + _trace->set_interval_constrained(new Interval(Info::Render::_x_min_visible, Info::Render::_x_max_visible)); // // WARNING I HAVE COMMENTED THIS LINE BECAUSE I FOUND IT USELESS. I TRIED AFTER AND NO BUG APPEARED // MOREOVER IT ENABLES THE PLUGIN TIME SELECTION // } + + // if(_state & _STATE_IN_AN_INTERVAL) { // _trace->set_interval_constrained(new Interval(_time_start,_time_end)); // } if (_DRAW_OPENGL == format) { + if(!_xml_config_file.empty() && _trace->get_view_root_containers()->empty()){//if we have a partial loading, process it here, but only once + launch_action(_DRAW_OPENGL_PARTIAL,NULL); + } + drawing_ogl.build(&render, _trace); _render_opengl->build(); // _render_opengl->updateGL(); @@ -413,13 +426,14 @@ int Core::run(){ * * **********************************/ -#define GETOPT_STRING "t:e:i:h" +#define GETOPT_STRING "t:e:c:i:h" #if defined(HAVE_GETOPT_LONG) static struct option long_options[] = { {"interval", required_argument, 0, 't'}, {"export", required_argument, 0, 'e'}, + {"load_containers_config", required_argument, 0, 'c'}, {"input", required_argument, 0, 'i'}, {"help", no_argument, 0, 'h'}, {0, 0, 0, 0} @@ -488,6 +502,10 @@ int Core::get_state(int argc, char** argv){ case 'h' : return _STATE_DISPLAY_HELP; + case 'c' : + _xml_config_file = optarg; + //cerr << "Export in file: " << _path_to_export << endl; + break; default: continue; @@ -790,11 +808,30 @@ void Core::launch_action(int state, void* arg) { case _STATE_RENDER_UPDATE: _render_opengl->updateGL(); break; + + case _STATE_CLEAN_RENDER_AREA: + if (_render_opengl->unbuild()==false) + message << "Close file : an error occured while cleaning the render." << Message::ende; + break; case _STATE_RENDER_SHOW_MINIMAP: _render_opengl->show_minimap(); break; + case _DRAW_OPENGL_PARTIAL: + { + _main_window->get_node_select()->set_trace(_trace); + bool xml_success = _main_window->get_node_select()->load_config_from_xml(QString(_xml_config_file.c_str())); + if(xml_success){ + std::list<Container *> displayed_containers; + _main_window->get_node_select()->build_displayed_nodes(displayed_containers); + _trace->set_view_root_containers(displayed_containers); + }else{ + message << "Error while parsing" << _xml_config_file << Message::ende; + } + break; + } + default:/* like _STATE_UNKNOWN */ display_help(); warning(string("Cannot determine the arguments past. Please check the correct syntax.")); @@ -812,6 +849,7 @@ void Core::display_help(){ << " -a display all the inputfile (Default)" << endl << " -t [T0]:[T1] display the interval [T0:T1] (Default: T0 = 0 and T1 = Tmax)" << endl << " -e outputfile export the trace file in the svg format to outpufile" << endl + << " -c xmlfile import a list of containers to display from an xml file" << endl << endl; } diff --git a/src/core/Core.hpp b/src/core/Core.hpp index 7247e6479aa74a7ebf0671202d052284c6cb9ac8..98671f79cb244465f80ee20a764d254d98efbb69 100644 --- a/src/core/Core.hpp +++ b/src/core/Core.hpp @@ -212,6 +212,7 @@ public: */ static const int _DRAW_OPENGL_PARTIAL = 24; + static const int _STATE_CLEAN_RENDER_AREA = 25; /*! * \brief Launch an action according to the argument state value. * \param state An integer corresponding to a kind of action which must be executed. @@ -302,6 +303,11 @@ protected: */ std::string _file_opened; + /*! + *\brief If a container's config file has to be opened, this attribute contains its path. + */ + std::string _xml_config_file; + /*! *\brief If a file must be exported, this attribute contains its path. */ diff --git a/src/core/getopt.c b/src/core/getopt.c new file mode 100644 index 0000000000000000000000000000000000000000..55afe726ede1700dbf8bdd94f476c1bcb25d7fe0 --- /dev/null +++ b/src/core/getopt.c @@ -0,0 +1,70 @@ +#include <windows.h> +#include <stdio.h> + +char *optarg; // global argument pointer +int optind = 0; // global argv index +char c; +char *cp; + +int getopt(int argc, char *argv[], char *optstring) +{ + static char *next = NULL; + if (optind == 0) + next = NULL; + + optarg = NULL; + + if (next == NULL || *next == '\0') + { + if (optind == 0) + optind++; + + if (optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0') + { + optarg = NULL; + if (optind < argc) + optarg = argv[optind]; + return EOF; + } + + if (strcmp(argv[optind], "--") == 0) + { + optind++; + optarg = NULL; + if (optind < argc) + optarg = argv[optind]; + return EOF; + } + + next = argv[optind]; + next++; // skip past - + optind++; + } + + c = *next++; + cp = strchr(optstring, c); + + if (cp == NULL || c == ':') + return '?'; + + cp++; + if (*cp == ':') + { + if (*next != '\0') + { + optarg = next; + next = NULL; + } + else if (optind < argc) + { + optarg = argv[optind]; + optind++; + } + else + { + return '?'; + } + } + + return c; +} \ No newline at end of file diff --git a/src/core/getopt.h b/src/core/getopt.h new file mode 100644 index 0000000000000000000000000000000000000000..971f94a5d1727b6f981570d8c41dae4319b8eb37 --- /dev/null +++ b/src/core/getopt.h @@ -0,0 +1,44 @@ +/****************************************************************************** +fgdump - by fizzgig and the foofus.net group +Copyright (C) 2005 by fizzgig +http://www.foofus.net + +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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +******************************************************************************/ +// XGetopt.h Version 1.2 +// +// Author: Hans Dietrich +// hdietrich2@hotmail.com +// +// This software is released into the public domain. +// You are free to use it in any way you like. +// +// This software is provided "as is" with no expressed +// or implied warranty. I accept no liability for any +// damage or loss of business that this software may cause. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef XGETOPT_H +#define XGETOPT_H + + +extern "C" int optind, opterr; +extern "C" char *optarg; + +extern "C" int getopt(int argc, char *argv[], char *optstring); + + +#endif //XGETOPT_H \ No newline at end of file diff --git a/src/interface/Interface_graphic.cpp b/src/interface/Interface_graphic.cpp index dd41167db42a0d73a18ad487d185e362324c9bf6..7714d9662cb6ab6a39ea935c0805856babb4b6a8 100644 --- a/src/interface/Interface_graphic.cpp +++ b/src/interface/Interface_graphic.cpp @@ -118,9 +118,21 @@ Interface_graphic::Interface_graphic(Core* core, QWidget *parent):QMainWindow(pa _progress_dialog = NULL; _plugin_window = NULL; _ui_settings = NULL; + _ui_node_selection=NULL; // _cmd_window = NULL; _cmd_window = new Command_window(this,this); + if (!_ui_node_selection) { + _ui_node_selection = new Node_select(this, 0); + if(_core->get_trace()){ + _ui_node_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())); + } + // For drag and drop operations setAcceptDrops(true); } @@ -837,6 +849,21 @@ void Interface_graphic::on_show_settings_triggered() { _ui_settings->show(); } + void Interface_graphic::on_node_selection_triggered() { + + if (!_ui_node_selection) { + _ui_node_selection = new Node_select(this, 0); + if(_core->get_trace()){ + _ui_node_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_node_selection->show(); + } + void Interface_graphic::on_actionCommand_triggered(){ if(_core->get_trace()){ if (!_cmd_window) @@ -985,6 +1012,9 @@ Core * Interface_graphic::get_console(){ return _core; } +Node_select* Interface_graphic::get_node_select(){ + return _ui_node_selection; +} void Interface_graphic::update_recent_files_menu() { const QStringList filenames = Session::get_recent_files(); QString absoluteFilename; diff --git a/src/interface/Interface_graphic.hpp b/src/interface/Interface_graphic.hpp index f0716a7983f1172b5aa34e2226488a8841bee40c..af603d23f57e00dd936f592646d50330a2b37aca 100644 --- a/src/interface/Interface_graphic.hpp +++ b/src/interface/Interface_graphic.hpp @@ -70,6 +70,7 @@ class QProgressDialog; /* Global informations */ #include "interface/Interface.hpp" #include "interface/Settings_window.hpp" +#include "interface/Node_select.hpp" /*! *\brief This class is a graphical interface which creates a window, it inherited from the Interface interface. @@ -217,6 +218,11 @@ class Interface_graphic : public QMainWindow, protected Ui::main_window, public * \brief Dialog box to allow user to set its ViTE environment. (change color, text size, etc.) */ Settings_window* _ui_settings; + + /*! + * \brief Dialog box to allow user to select nodes to display + */ + Node_select* _ui_node_selection; /*! * \brief Text area which informs the user about the trace resume. @@ -471,6 +477,12 @@ public: */ Core *get_console(); + /*! + * \fn get_node_select() + * \brief To get the node selection console + */ + Node_select* get_node_select(); + /*! * \fn update_recent_files_menu() * \brief update the recent files opened menu @@ -589,6 +601,11 @@ protected slots: *\brief A slot called when 'Settings' in the menu is clicked. */ void on_show_settings_triggered(); + + /*! + *\brief A slot called when 'Node selection' in the menu is clicked. + */ + void on_node_selection_triggered(); /*! * \brief A slot called when 'command' in the menu is clicked. diff --git a/src/interface/Node_select.cpp b/src/interface/Node_select.cpp new file mode 100644 index 0000000000000000000000000000000000000000..61cdd3fb9304e1412def8b43faa7c757397309c0 --- /dev/null +++ b/src/interface/Node_select.cpp @@ -0,0 +1,642 @@ +/* +** 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 <QFileDialog> // To choose the file to save +#include <QKeyEvent> +#include <QDropEvent> +#include <QtXml> +#include <QFile> +#include <iostream> + +#include "interface/Node_select.hpp" +Q_DECLARE_METATYPE( Container * ); + +using namespace std; + +Node_select::Node_select(Interface_graphic * console,QWidget *parent) :_console(console), QWidget(parent) { + setupUi(this); + + + + QMetaObject::connectSlotsByName(NULL); +} + +Node_select::~Node_select() { +} + +void Node_select::set_initial_container_names(){ + + const Container::Vector *root_containers = _trace->get_root_containers(); + + if(root_containers->empty()) { + *Message::get_instance() << tr("No containers in this trace").toStdString() << Message::ende; + return; + } + _nodes_original->clear(); + // Add the root container names + QList<QTreeWidgetItem *> items; + QFlags<Qt::ItemFlag> flg; + for (Container::VectorIt it = root_containers->begin(); + it != root_containers->end(); + it ++) { + string name = (*it)->get_name().to_string(); + QStringList temp(QString::fromStdString(name)); + QTreeWidgetItem *current_node = new QTreeWidgetItem((QTreeWidgetItem *)0, temp); + current_node->setData(0,Qt::UserRole,qVariantFromValue(*it));//store the pointer to the container in the Data field + items.append(current_node); + + // Recursivity to add the children names + set_container_names_rec(current_node, (*it), flg); + } + + _nodes_original->insertTopLevelItems(0, items); + + _nodes_original->expandAll(); + +} + + +void Node_select::set_displayed_container_names(){ + + const Container::Vector *root_containers = _trace->get_root_containers(); + + if(root_containers->empty()) { + *Message::get_instance() << tr("No containers in this trace").toStdString() << Message::ende; + return; + } + // Add the root container names + QList<QTreeWidgetItem *> items; + QFlags<Qt::ItemFlag> flg= Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsTristate; + for (Container::VectorIt it = root_containers->begin(); + it != root_containers->end(); + it ++) { + string name = (*it)->get_name().to_string(); + QStringList temp(QString::fromStdString(name)); + QTreeWidgetItem *current_node = new QTreeWidgetItem((QTreeWidgetItem *)0, temp); + + current_node->setFlags(flg); + current_node->setCheckState(0,Qt::Checked); + current_node->setData(0,Qt::UserRole,qVariantFromValue(*it));//store the pointer to the container in the Data field + items.append(current_node); + + // Recursivity to add the children names + set_container_names_rec(current_node, (*it), flg); + } + + _nodes_displayed->insertTopLevelItems(0, items); + + _nodes_displayed->expandAll(); + +} + + + + + +void Node_select::set_container_names_rec(QTreeWidgetItem *current_node, Container *current_container, QFlags<Qt::ItemFlag> flg) { + const Container::Vector *children = current_container->get_children(); + //QFlags<Qt::ItemFlag> flg= Qt::ItemIsDragEnabled; + + for (Container::VectorIt it = children->begin(); + it != children->end(); + it ++) { + // We create the node and we do the recursivity + string name = (*it)->get_name().to_string(); + QStringList temp(QString::fromStdString(name)); + QTreeWidgetItem *node = new QTreeWidgetItem(current_node, temp); + + node->setFlags(flg); + node->setData(0,Qt::UserRole, qVariantFromValue(*it));//store the pointer to the container in the Data field + if(flg & Qt::ItemIsUserCheckable)node->setCheckState(0,Qt::Checked); + set_container_names_rec(node ,(*it), flg); + } +} + + +void Node_select::set_trace(Trace *trace) { + // Initialize _trace + _trace = trace; + // Fill the tree + set_initial_container_names(); + set_displayed_container_names(); +} +/* +void Stats_window::set_selected_nodes(string kind_of_state){ + const list<StateType *> *states_types_list; + list<StateType *>::const_iterator itstat; + list<StateType *>::const_iterator endstat; + const ContainerType *kind_of_container = NULL; + + states_types_list = _trace->get_state_types(); + endstat = states_types_list->end(); + for (itstat = states_types_list->begin(); + itstat != endstat; + itstat++){ + if ((*itstat)->get_name().to_string() == kind_of_state){ + kind_of_container = (*itstat)->get_container_type(); + continue; + } + } + + // We delete the previous selected containers + if(!_selected_containers.empty()) { + _selected_containers.clear(); + } + + // We fill the new selected containers + // TODO : Use the tree instead of the list + QTreeWidgetItemIterator it(_nodes_selected); + while (*it) { + if ((*it)->checkState(0) == Qt::Checked){ + Container *cont = _trace->search_container((*it)->text(0).toStdString()); + //cout << ((ContainerType *)cont->get_type())->get_name().to_string() << " " << ((ContainerType *)kind_of_container)->get_name().to_string() << endl; + if (cont->get_type() == kind_of_container) + _selected_containers.push_back(cont); + } + it ++; + } + _number_of_selected_container = _selected_containers.size(); + +#ifdef STAT_DEBUG + for(unsigned int i = 0 ; i < _selected_containers.size() ; i ++) { + cout << _selected_containers[i]->get_name().to_string() << endl; + } +#endif +} + +*/ + + void Node_select::on_reset_button_clicked(){ + //resets to initial containers, + _displayed_containers.clear(); + QList<QTreeWidgetItem *> items; + QTreeWidgetItemIterator it(_nodes_original);//browse only top containers + while (*it) { + if((*it)->parent()==NULL){//we only want parent nodes + _displayed_containers.push_back(((*it)->data(0,Qt::UserRole)).value<Container*>()); + reassign_children_rec(*it, 0); + } + ++it; + + } + + _nodes_displayed->clear(); + //can we load that from _nodes_original instead ? + set_displayed_container_names(); + + _trace->set_view_root_containers(_displayed_containers); + //_trace->set_selected_container(_trace->get_root_containers()); + _console->get_console()->launch_action(Core:: _STATE_CLEAN_RENDER_AREA); + _console->get_console()->draw_trace(_console->get_filename(),Core::_DRAW_OPENGL); + _console->get_console()->launch_action(Core:: _STATE_RENDER_UPDATE); + + + } + + + +void Node_select::on_load_button_clicked(){ + //load an xml file and appply the structure described inside to the trace + const QString path_by_default = QString(_file_viewed.substr(0, _file_viewed.find_last_of('.')).c_str()) + ".xml"; + + QString filename = QFileDialog::getOpenFileName(this, tr("Import File"), + path_by_default, + tr("Documents XML (*.xml)")); + + if (filename.isEmpty()) { + *Message::get_instance() << tr("No File Selected").toStdString() << Message::ende; + return ; + } + else { + // Adding .svg to the end + if(!filename.endsWith(".xml")) { + filename += ".xml"; + } + } + + load_config_from_xml(filename); +} + +bool Node_select::load_config_from_xml(QString filename){ + QDomDocument doc( "Subset" ); + QFile file( filename); + if( !file.open( QIODevice::ReadOnly ) ){ + *Message::get_instance() << tr("File opening fail").toStdString() << Message::ende; + return false ; + } + + if( !doc.setContent( &file ) ) + { + file.close(); + *Message::get_instance() << tr("File is not a valid xml file").toStdString() << Message::ende; + return false; + } + file.close(); + + + QDomElement root = doc.documentElement(); + if( root.tagName() != "nodes" ) { + *Message::get_instance() << tr("File is not a valid xml file").toStdString() << Message::ende; + return false; + } + + const Container::Vector *root_containers = _trace->get_root_containers(); + _nodes_displayed->clear(); + + + QList<QTreeWidgetItem *> items; + QFlags<Qt::ItemFlag> flg=Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsTristate; + //go through all the top elements of the trace to construct a representation + QDomNode n = root.firstChild(); + while( !n.isNull() ) + { + QDomElement e = n.toElement(); + if( !e.isNull() ) + { + if( e.tagName() == "rootNode" ) + { + string n(e.attribute( "name", "" ).toStdString()); + Container::VectorIt it = root_containers->begin(); + for (; + it != root_containers->end(); + it ++) { + if((*it)->get_name().to_string()==n){//we found the root container corresponding + QTreeWidgetItem *current_node = new QTreeWidgetItem((QTreeWidgetItem *)0, QStringList(QString::fromStdString(n))); + current_node->setFlags(flg); + current_node->setData(0,Qt::UserRole,qVariantFromValue(*it));//store the pointer to the container in the Data field + current_node->setCheckState(0,Qt::Checked); + items.append(current_node); + // Recursivity to add the children names + load_names_rec(current_node, (*it), flg, e); + break; + } + + } + + if(it==root_containers->end())*Message::get_instance() << tr("Root node was not found, check if it exists. Continuing ...").toStdString() << Message::ende; + + }else + *Message::get_instance() << tr("wrong node was found when parsing for rootNode, check xml construction. Continuing ...").toStdString() << Message::ende; + + } + + n = n.nextSibling(); + } + + + _nodes_displayed->insertTopLevelItems(0, items); + + _nodes_displayed->expandAll(); + return true; +} + + + void Node_select::load_names_rec(QTreeWidgetItem *current_node, Container *current_container, QFlags<Qt::ItemFlag> flg, QDomElement& element) { + + //we need to loop on both the xml childs and the container's child to make them correspond + const Container::Vector *children = current_container->get_children(); + + QDomNode n = element.firstChild(); + while( !n.isNull() ) + { + QDomElement e = n.toElement(); + if( !e.isNull() ) + { + if( e.tagName() == "Node" ) + { + string n(e.attribute( "name", "" ).toStdString()); + Container::VectorIt it = children->begin(); + for (; + it != children->end(); + it ++) { + // We create the node and we do the recursivity + + + if( (*it)->get_name().to_string()==n){ + //we found the good Container + QTreeWidgetItem *node = new QTreeWidgetItem(current_node, QStringList(QString::fromStdString(n))); + + node->setFlags(flg); + node->setData(0,Qt::UserRole, qVariantFromValue(*it));//store the pointer to the container in the Data field + node->setCheckState(0,Qt::Checked); + //printf("we found a sub element %s\n", n.c_str()); + load_names_rec(node ,(*it), flg, e); + break; + } + } + if(it==children->end())*Message::get_instance() << tr("node was not found, check if it exists. Continuing ...").toStdString() << Message::ende; + + + + }else + *Message::get_instance() << tr("wrong node was found when parsing for Node, check xml construction. Continuing ...").toStdString() << Message::ende; + + } + + n = n.nextSibling(); + } + +} + + + void Node_select::on_display_button_clicked(){ + //take the new list and apply it to the trace + // if not checked, remove container + // if position has changed, set to the new position + + //we need to be recursive again, and to avoid problems with similar names + + + /* + //this only works to select containers, we cannot order them by this way + _displayed_containers.clear(); + QTreeWidgetItemIterator it(_nodes_displayed, QTreeWidgetItemIterator::Checked); + while (*it) { + _displayed_containers.push_back(((*it)->data(0,Qt::UserRole)).value<Container*>()); + ++it; + } + + + _trace->set_selected_container(&_displayed_containers);*/ + + //use _view_root containers and _view_children in order not to modify the actual structure and limit modifications to do in drawtrace + _displayed_containers.clear(); + build_displayed_nodes(_displayed_containers); + + + _trace->set_view_root_containers(_displayed_containers); + //_trace->set_selected_container(_trace->get_root_containers()); + _console->get_console()->launch_action(Core:: _STATE_CLEAN_RENDER_AREA); + _console->get_console()->draw_trace(_console->get_filename(),Core::_DRAW_OPENGL); + _console->get_console()->launch_action(Core:: _STATE_RENDER_UPDATE); + } + + void Node_select::build_displayed_nodes( std::list<Container *>& displayed_containers){ + QTreeWidgetItemIterator it(_nodes_displayed, QTreeWidgetItemIterator::Checked);//browse only top containers + while (*it) { + if((*it)->parent()==NULL){//we only want parent nodes + displayed_containers.push_back(((*it)->data(0,Qt::UserRole)).value<Container*>()); + QFlags<Qt::CheckState> flg(Qt::Checked|Qt::PartiallyChecked); + reassign_children_rec(*it,flg); + } + ++it; + + } + + } + + + void Node_select::reassign_children_rec(QTreeWidgetItem* item, QFlags<Qt::CheckState> flg){ + //browse all childs of a container, add him and recursively all its children to the view we want + item->data(0,Qt::UserRole).value<Container*>()->clear_view_children(); + for(int i=0; i<item->childCount(); i++){ + if(flg==0 || (item->child(i)->checkState(0)& flg) ){ + item->data(0,Qt::UserRole).value<Container*>()->add_view_child(item->child(i)->data(0,Qt::UserRole).value<Container*>()); + reassign_children_rec(item->child(i), flg); + } + + } + + } + + + + + +void Node_select::set_filename(string filename){ + _file_viewed = filename; +} + + +void Node_select::on_export_button_clicked(){ + //export the trees to a XML file, in order to allow easy reusing + + const QString path_by_default = QString(_file_viewed.substr(0, _file_viewed.find_last_of('.')).c_str()) + ".xml"; + + QString filename = QFileDialog::getSaveFileName(this, tr("Export File"), + path_by_default, + tr("Documents XML (*.xml)")); + + if (filename.isEmpty()) { + *Message::get_instance() << tr("You must select a name for the file").toStdString() << Message::ende; + return ; + } + else { + // Adding .svg to the end + if(!filename.endsWith(".xml")) { + filename += ".xml"; + } + } + + QDomDocument doc( "Subset " ); + QDomElement root = doc.createElement( "nodes" ); + doc.appendChild( root ); + + //go through all elements of _nodes_displayed + QTreeWidgetItemIterator it(_nodes_displayed);//browse only top containers + + while (*it) { + if((*it)->parent()==NULL){//we only want parent nodes + + QDomElement rootElement = doc.createElement( "rootNode" ); + rootElement.setAttribute( "name", QString((*it)->data(0,Qt::UserRole).value<Container*>()->get_name().to_string().c_str()) ); + + export_children_rec(*it, rootElement, doc); + root.appendChild( rootElement ); + } + ++it; + + } + + QFile file( filename ); + if( !file.open( QIODevice::WriteOnly) ){ + *Message::get_instance() << tr("Error while opening the file").toStdString() << Message::ende; + return ; + } + + QTextStream ts( &file ); + ts << doc.toString(); + + file.close(); + + + + + +} + + + void Node_select::export_children_rec(QTreeWidgetItem* item, QDomElement& parent, QDomDocument& doc){ + for(int i=0; i<item->childCount(); i++){ + if((item->child(i)->checkState(0)& (Qt::Checked|Qt::PartiallyChecked)) ){ + QDomElement element = doc.createElement( "Node" ); + element.setAttribute( "name", QString(item->child(i)->data(0,Qt::UserRole).value<Container*>()->get_name().to_string().c_str()) ); + parent.appendChild( element ); + export_children_rec(item->child(i), element, doc); + + } + + } + + } + + +void Node_select::close_window(){ + hide(); +} + + + + +void Node_select::keyPressEvent(QKeyEvent *event) { + /* switch (event->key()) { + case Qt::Key_Left: + // Key 'left' pressed. + if(_x_translated > 0) { + _ui_stats_area->translate_x(--_x_translated); + x_scroll->setSliderPosition(_x_translated); + } + break; + case Qt::Key_Right: + // Key 'right' pressed. + if(_x_translated < 99) { + _ui_stats_area->translate_x(++_x_translated); + x_scroll->setSliderPosition(_x_translated); + } + break; + case Qt::Key_Up: + // Key 'up' pressed. + if(_y_translated > 0) { + _ui_stats_area->translate_y(--_y_translated); + y_scroll->setSliderPosition(_y_translated); + } + break; + case Qt::Key_Down: + // Key 'down' pressed. + if(_y_translated < 99) { + _ui_stats_area->translate_y(++_y_translated); + y_scroll->setSliderPosition(_y_translated); + } + break; + case Qt::Key_PageUp: + // Key 'Page Up' pressed. + _ui_stats_area->translate_y(0); + y_scroll->setSliderPosition(0); + break; + case Qt::Key_PageDown: + // Key 'Page Down' pressed. + _ui_stats_area->translate_y(100); + y_scroll->setSliderPosition(100); + break; + default: + + break; + } + + event->accept();*/ +} +/* +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"; +}*/ diff --git a/src/interface/Node_select.hpp b/src/interface/Node_select.hpp new file mode 100644 index 0000000000000000000000000000000000000000..3553a31d11bcce1b8b9d4687821a987cee527d79 --- /dev/null +++ b/src/interface/Node_select.hpp @@ -0,0 +1,175 @@ +/* +** 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 Stats_window.hpp + */ + +#ifndef NODE_SELECT_HPP +#define NODE_SELECT_HPP + +class Node_select; + +/* For moc compilation */ +#include <string> +#include <map> +#include <list> +/* -- */ +#include <QWidget> +#include "ui_node_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 QDomElement; +class QDomDocument; +/* -- */ + + + + +/*! + * \class Node select + * \brief Class used to select which containers should be displayed + * + */ + +class Node_select : public QWidget, protected Ui::node_selector { + + Q_OBJECT + + private: + + std::vector<Container *> _initial_containers; + std::list<Container *> _displayed_containers; + int _number_of_selected_container; + int _screen_width, _screen_height; + std::string _file_viewed; + Trace* _trace; + Interface_graphic *_console; +public: + /*! + * Default constructor + * \param parent The parent widget of the window. + */ + Node_select( Interface_graphic *console, QWidget *parent = 0); + + ~Node_select(); + + /*! + * \fn set_initial_container_names() + * \brief Set the names of the containers in the trees + */ + void set_initial_container_names(); + + /*! + * \fn set_initial_container_names() + * \brief Set the names of the containers in the trees + */ + void set_displayed_container_names(); + + /*! + * \fn set_trace(Trace *trace) + * \brief Set the trace parsed (give the container names) + * \param trace The trace. + */ + void set_trace(Trace *trace); + + /*! + * \fn set_filename(std::string filename) + * \brief Set the name of the file trace. + * \param filename The file name. + */ + void set_filename(std::string filename); + + + /*! + * \fn init_window() + * \brief Initialise the node selection window : set the container names, expand the lists + and clear what could have been here before + */ + void init_window(); + + /*! + * \fn close_window() + * \brief Properly close the window + */ + void close_window(); + + bool load_config_from_xml(QString filename); + void build_displayed_nodes( std::list<Container *>& displayed_containers); + +private: + void set_container_names_rec(QTreeWidgetItem *current_node, Container *current_container, QFlags<Qt::ItemFlag>); + + /*! + * \brief Fill the vector of selected containers depending on the ones chosen in the tree widget + */ + void set_displayed_nodes(std::string); + void reassign_children_rec(QTreeWidgetItem* item, QFlags<Qt::CheckState> flg); + + /*! + * \brief This functions receives all keyboard events. + * \param event The event triggered by the keyboard event. + */ + void keyPressEvent(QKeyEvent *event); + void export_children_rec(QTreeWidgetItem* item, QDomElement& parent, QDomDocument& doc); + void load_names_rec(QTreeWidgetItem *current_node, Container *current_container, QFlags<Qt::ItemFlag> flg, QDomElement& element); + +private slots: + + void on_reset_button_clicked(); + void on_export_button_clicked(); + + void on_load_button_clicked(); +public slots: // just for testing, remove + void on_display_button_clicked(); + +}; + +#endif // NODE_SELECT_HPP diff --git a/src/interface/main_window.ui b/src/interface/main_window.ui index 01d0bde6a04e11bd69c3339e157dee6209427f71..1b566645c451d867156ea3ca00340a4d4eb430fa 100644 --- a/src/interface/main_window.ui +++ b/src/interface/main_window.ui @@ -248,6 +248,7 @@ <addaction name="show_plugins"/> <addaction name="separator"/> <addaction name="show_settings"/> + <addaction name="node_selection"/> </widget> <addaction name="menuFile"/> <addaction name="menuView"/> @@ -530,6 +531,11 @@ <string>Settings</string> </property> </action> + <action name="node_selection"> + <property name="text"> + <string>Node Selection</string> + </property> + </action> <action name="shaded_states"> <property name="checkable"> <bool>true</bool> diff --git a/src/interface/node_select.ui b/src/interface/node_select.ui new file mode 100644 index 0000000000000000000000000000000000000000..e72866e525781623ff62fcd8ebac357a404f743e --- /dev/null +++ b/src/interface/node_select.ui @@ -0,0 +1,237 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>node_selector</class> + <widget class="QWidget" name="node_selector"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>640</width> + <height>612</height> + </rect> + </property> + <property name="windowTitle"> + <string>Node Selection</string> + </property> + <widget class="QTreeWidget" name="_nodes_original"> + <property name="geometry"> + <rect> + <x>20</x> + <y>40</y> + <width>281</width> + <height>481</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="dragEnabled"> + <bool>false</bool> + </property> + <property name="selectionMode"> + <enum>QAbstractItemView::ExtendedSelection</enum> + </property> + <property name="selectionBehavior"> + <enum>QAbstractItemView::SelectItems</enum> + </property> + <property name="headerHidden"> + <bool>true</bool> + </property> + <column> + <property name="text"> + <string>1</string> + </property> + </column> + </widget> + <widget class="viteQTreeWidget" name="_nodes_displayed"> + <property name="geometry"> + <rect> + <x>340</x> + <y>40</y> + <width>281</width> + <height>481</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="dragEnabled"> + <bool>true</bool> + </property> + <property name="dragDropMode"> + <enum>QAbstractItemView::InternalMove</enum> + </property> + <property name="defaultDropAction"> + <enum>Qt::MoveAction</enum> + </property> + <property name="selectionMode"> + <enum>QAbstractItemView::ExtendedSelection</enum> + </property> + <property name="selectionBehavior"> + <enum>QAbstractItemView::SelectItems</enum> + </property> + <property name="headerHidden"> + <bool>true</bool> + </property> + <column> + <property name="text"> + <string>1</string> + </property> + </column> + </widget> + <widget class="QPushButton" name="load_button"> + <property name="geometry"> + <rect> + <x>440</x> + <y>530</y> + <width>85</width> + <height>31</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Load</string> + </property> + </widget> + <widget class="QPushButton" name="export_button"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="geometry"> + <rect> + <x>530</x> + <y>530</y> + <width>85</width> + <height>31</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="text"> + <string>Export</string> + </property> + </widget> + <widget class="QLabel" name="label_4"> + <property name="geometry"> + <rect> + <x>110</x> + <y>20</y> + <width>101</width> + <height>17</height> + </rect> + </property> + <property name="text"> + <string>Initial nodes :</string> + </property> + </widget> + <widget class="QLabel" name="label_5"> + <property name="geometry"> + <rect> + <x>430</x> + <y>20</y> + <width>121</width> + <height>17</height> + </rect> + </property> + <property name="text"> + <string>Displayed nodes :</string> + </property> + </widget> + <widget class="QWidget" name="verticalLayoutWidget"> + <property name="geometry"> + <rect> + <x>10</x> + <y>530</y> + <width>331</width> + <height>31</height> + </rect> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Expanding</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>298</width> + <height>26</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + <widget class="QPushButton" name="reset_button"> + <property name="geometry"> + <rect> + <x>350</x> + <y>530</y> + <width>85</width> + <height>31</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Reset</string> + </property> + </widget> + <widget class="QPushButton" name="display_button"> + <property name="geometry"> + <rect> + <x>350</x> + <y>570</y> + <width>261</width> + <height>31</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Display Trace</string> + </property> + </widget> + </widget> + <customwidgets> + <customwidget> + <class>viteQTreeWidget</class> + <extends>QTreeWidget</extends> + <header location="global">interface/viteqtreewidget.hpp</header> + </customwidget> + </customwidgets> + <resources/> + <connections/> +</ui> diff --git a/src/interface/viteqtreewidget.cpp b/src/interface/viteqtreewidget.cpp new file mode 100644 index 0000000000000000000000000000000000000000..34d130384308850d088590fb5a16235d470f8029 --- /dev/null +++ b/src/interface/viteqtreewidget.cpp @@ -0,0 +1,142 @@ +#include "interface/viteqtreewidget.hpp" +#include "stdio.h" +#include <QTreeWidget> + +viteQTreeWidget::viteQTreeWidget(QWidget *parent) + : QTreeWidget(parent) +{ + +} + + viteQTreeWidget::~viteQTreeWidget(){ +} + +void viteQTreeWidget::dropEvent(QDropEvent *e){ + + + //we want to avoid to destroy the hierarchy of the trace, so let's only move containers near a container with the same parent + + + //QTreeWidgetItem* item= itemAt(event->pos());//get the item where we want to move + //printf("drop %s to %s!\n", ); + + const QPoint pos = e->pos(); + QTreeWidgetItem* target = itemAt(e->pos()); + + if(target==NULL){ + e->ignore(); + return; + } + + bool do_move = true; + + // this is used to determine if the target is itself a child + + foreach(QTreeWidgetItem* item, selected_items) + { + + // if target and item don't share the same parent... + if(target->parent() != item->parent()) + { + // ...then don't allow the move + do_move = false; + break; + } + + if(target==item){ + // ...do nothing + do_move = false; + break; + } + + } + + + if(!do_move) + e->setDropAction(Qt::IgnoreAction); + else + { + //QTreeWidget::dropEvent(e); + int index=target->parent()->indexOfChild(target); + int modifier=0; + + int initial_count=target->parent()->childCount(); + //we want to insert below the pointed event + foreach(QTreeWidgetItem* item, selected_items) + { + //remove all items from their parent + if(item->parent()->indexOfChild(item)<index)modifier++; + item->parent()->removeChild(item); + + } + //insert them again in the right position and order + + index=target->parent()->indexOfChild(target); + + int max=0; + if(index+modifier > target->parent()->childCount()){ + max=target->parent()->childCount(); + foreach(QTreeWidgetItem* item, selected_items) + { + target->parent()->insertChild(max, item); + max++; + } + } + + else{ + max=index+modifier; + target->parent()->insertChildren(max, selected_items); + } + + if (target->parent()->childCount()!=initial_count){ + //prevent loss of elements if insertions failed (can happen sometimes) + //try to reinsert all elements at the end + foreach(QTreeWidgetItem* item, selected_items) + { + target->parent()->insertChild(target->parent()->childCount(), item); + } + + } + e->setDropAction(Qt::TargetMoveAction); + } + + e->accept(); + selected_items.clear(); + + } + + + +void viteQTreeWidget::dragEnterEvent(QDragEnterEvent *event) +{ + selected_items = selectedItems(); + if (event->source() == this) + { + event->setDropAction(Qt::MoveAction); + event->accept(); + } + else + event->acceptProposedAction(); + +} + +void viteQTreeWidget::dragMoveEvent(QDragMoveEvent *e) +{ +e->accept(); +} + +QMimeData *viteQTreeWidget::mimeData(const QList<QTreeWidgetItem *>) const +{ +return new QMimeData; +} + +bool viteQTreeWidget::dropMimeData ( QTreeWidgetItem * , int , const QMimeData * , Qt::DropAction ) +{ +return true; +} + +Qt::DropActions viteQTreeWidget::supportedDropActions () const +{ +return Qt::CopyAction|Qt::MoveAction; +} + diff --git a/src/interface/viteqtreewidget.hpp b/src/interface/viteqtreewidget.hpp new file mode 100644 index 0000000000000000000000000000000000000000..40ae35d5f4d71dd53a20a27bdd5b561599bc7774 --- /dev/null +++ b/src/interface/viteqtreewidget.hpp @@ -0,0 +1,30 @@ +#ifndef VITETREEWIDGET_H +#define VITETREEWIDGET_H + +#include <QtGui> +#include <QObject> + +class viteQTreeWidget : public QTreeWidget +{ + Q_OBJECT + +public: + viteQTreeWidget(QWidget *parent = 0); + ~viteQTreeWidget(); +protected: + void dropEvent(QDropEvent *event); + + void dragEnterEvent(QDragEnterEvent *e); +void dragMoveEvent(QDragMoveEvent *e); + +QList<QTreeWidgetItem *> selected_items; + +QMimeData *mimeData(const QList<QTreeWidgetItem *> items) const; + +bool dropMimeData ( QTreeWidgetItem * newParentPtr, int index, const QMimeData * data, Qt::DropAction action ) ; + +Qt::DropActions supportedDropActions () const; +}; + + +#endif diff --git a/src/parser/PajeFileManager.cpp b/src/parser/PajeFileManager.cpp index ba360030605f8947dda089b7daa5b53f84f24503..9bd94447859dfbb18f619fdd9368f2e3468719f1 100644 --- a/src/parser/PajeFileManager.cpp +++ b/src/parser/PajeFileManager.cpp @@ -128,7 +128,7 @@ int PajeFileManager::get_line(PajeLine *lineptr) { c = _line[0]; _tokens[itks] = &_line[0]; - for(i = 0; ((c != '\n') && (c != '\0')) && (itks < _PAJE_NBMAXTKS); i++) { + for(i = 0; i<_line.size() /*&& ((c != '\n') &&(c != '\r\n')&&(c != '\r') && (c != '\0'))*/ && (itks < _PAJE_NBMAXTKS); i++) { c = _line[i]; switch (c) { @@ -167,8 +167,10 @@ int PajeFileManager::get_line(PajeLine *lineptr) { // We finish the token by replacing the \' by \0 _line[i] = '\0'; - itks++; - _tokens[itks] = &_line[i+1]; + if(i+1<_line.size()){//begin a new token if we are not at the end of the line + itks++; + _tokens[itks] = &_line[i+1]; + } break; } case '"' : @@ -190,30 +192,34 @@ int PajeFileManager::get_line(PajeLine *lineptr) { // We finish the token by replacing the " by \0 _line[i] = '\0'; + if(i+1<_line.size()){//begin a new token if we are not at the end of the line itks++; _tokens[itks] = &_line[i+1]; + } break; } case ' ' : case '\t' : { // Skip all spaces - while ( ((_line[i] == ' ') || (_line[i] == '\t')) ) { + while (i<_line.size() && ((_line[i] == ' ') || (_line[i] == '\t')) ) { _line[i] = '\0'; i++; } // We store a new token if it's a new space - if (_tokens[itks][0] != '\0') - itks++; - _tokens[itks] = &_line[i]; - i--; + if(i!=_line.size()){ + if (_tokens[itks]!=NULL && _tokens[itks][0] != '\0') + itks++; + _tokens[itks] = &_line[i]; + i--; + } break; } default : break; } } - + itks++; //add a token to avoid bugs, because we don't meet \n with std strings // We remove the last token if it is empty if ((itks > 0) && (_tokens[itks-1][0] == '\0')) itks--; diff --git a/src/src.pro b/src/src.pro index 508ee069252cd2c4e5807527f66c8bdf047f0f4c..2aa21c2acdb952f036fb2ecdd47040be70cb56f1 100644 --- a/src/src.pro +++ b/src/src.pro @@ -54,8 +54,8 @@ TARGET = vite macx:QMAKE_LIBS_OPENGL += -framework -lobjc DEPENDPATH += . INCLUDEPATH += . -QMAKE_CFLAGS += -O2 -Wall -QMAKE_CXXFLAGS += -O2 -Wall +QMAKE_CFLAGS += -O2 -Wall -g +QMAKE_CXXFLAGS += -O2 -Wall -g #TRANSLATIONS = ViTE_fr.ts @@ -79,6 +79,8 @@ HEADERS += common/common.hpp \ interface/Settings_window.hpp \ interface/Interface_graphic.hpp \ interface/resource.hpp \ + interface/Node_select.hpp \ + interface/viteqtreewidget.hpp \ # Core header core/Core.hpp \ # Render headers @@ -155,7 +157,8 @@ FORMS += interface/info_window.ui \ interface/settings.ui \ interface/stats_viewer.ui \ interface/global_cmd.ui \ - interface/list_of_counter_to_export.ui + interface/list_of_counter_to_export.ui\ + interface/node_select.ui SOURCES += common/Message.cpp \ common/Errors.cpp \ @@ -215,6 +218,8 @@ SOURCES += common/Message.cpp \ # Interface code files interface/Settings_window.cpp \ interface/interface_graphic.cpp \ + interface/Node_select.cpp \ + interface/viteqtreewidget.cpp \ # Core code file core/Core.cpp \ # Plugin code file diff --git a/src/trace/Container.cpp b/src/trace/Container.cpp index 9cc01fe0bb1245b03ffdc8c37019c272fb83dc97..167366356f68d648c1413591fdbc23bb56afd7bb 100644 --- a/src/trace/Container.cpp +++ b/src/trace/Container.cpp @@ -116,6 +116,12 @@ void Container::add_child(Container *child) { } } +void Container::add_view_child(Container *child) { + if(child != NULL){ + _view_children.push_back(child); + } +} + void Container::add_current_state(Date end) { State *new_state = new State( _current_states.top().start, @@ -284,6 +290,18 @@ const Container::Vector * Container::get_children() const { return &_children; } +const Container::Vector * Container::get_view_children() const { + return &_view_children; +} + +void Container::clear_children() { + _children.clear(); +} + +void Container::clear_view_children() { + _view_children.clear(); +} + Date Container::get_creation_time() const { return _creation_time; } diff --git a/src/trace/Container.hpp b/src/trace/Container.hpp index 9693667e433ba49768b7cbd9feace91fbe222e32..4627b18521e2c1a3826e613ad60341bd516be713 100644 --- a/src/trace/Container.hpp +++ b/src/trace/Container.hpp @@ -68,6 +68,7 @@ private: ContainerType *_type; Container *_parent; Vector _children; + Vector _view_children; unsigned int _n_states; StateChange::Vector _states; StateChange::Tree *_state_tree; @@ -246,6 +247,29 @@ public: */ const Vector *get_children() const; + /*! + * \fn clear_children() const + * \brief Clear the list of the child containers, to allow reordering + */ + void clear_children(); + + /*! + * \fn add_view_child(Container* child) const + * \brief Add a children to the view + */ + void add_view_child(Container *child); + + /*! + * \fn get_view_children() const + * \brief Get the list of the child containers to display + */ + const Vector *get_view_children() const; + + /*! + * \fn clear_view_children() const + * \brief Clear the list of the child containers to display + */ + void clear_view_children(); /*! * \fn get_creation_time() const * \brief Get the time when the container was created diff --git a/src/trace/DrawTrace.hpp b/src/trace/DrawTrace.hpp index 5e2c758c566cbeb8ac9532369c60fdbda9c9d44a..72d4f45f4ecb90aa7df530a510fa4a5196a3ee84 100644 --- a/src/trace/DrawTrace.hpp +++ b/src/trace/DrawTrace.hpp @@ -203,8 +203,10 @@ public: trace->set_filter(0); std::stack<Container *> containers; - for (Container::VectorIt i = trace->get_root_containers()->begin(); - i != trace->get_root_containers()->end(); + const Container::Vector *root_containers = trace->get_view_root_containers(); + if(root_containers->empty())root_containers= trace->get_root_containers(); + for (Container::VectorIt i = root_containers->begin(); + i != root_containers->end(); i++){ containers.push(*i); container->push_back(*i); @@ -267,7 +269,8 @@ public: /*** Drawing containers ***/ int position = 0; - const Container::Vector *root_containers = trace->get_root_containers(); + const Container::Vector *root_containers = trace->get_view_root_containers(); + if(root_containers->empty())root_containers= trace->get_root_containers(); if (root_containers->empty()) { *Message::get_instance() << QObject::tr("There is no container. The trace can not be drawn.").toStdString() << Message::endw; } @@ -291,7 +294,9 @@ public: int size = 0; // Draw children - const Container::Vector *children = container->get_children(); + const Container::Vector *children = container->get_view_children();//we want to display only children meant to be displayed + if(children->empty())children = container->get_children(); + for (Container::VectorIt i = children->begin(); i != children->end(); i++) { @@ -530,7 +535,8 @@ public: // find container needs to know the position of each container double yr = y; - const Container::Vector *root_containers = trace->get_root_containers(); + const Container::Vector *root_containers = trace->get_view_root_containers(); + if(root_containers->empty())root_containers= trace->get_root_containers(); if (!root_containers->empty()) for (Container::VectorIt i = root_containers->begin(); i != root_containers->end(); @@ -644,7 +650,8 @@ public: const Container *search_container_by_position(const Container *container, double &y) { const Container *result; // Search if the result is a descendant - const Container::Vector *children = container->get_children(); + const Container::Vector *children = container->get_view_children();//we want to display only children meant to be displayed + if(children->empty())children = container->get_children(); for (Container::VectorIt i = children->begin(); i != children->end(); i++) { @@ -681,7 +688,8 @@ public: int size = 0; // Draw children - const Container::Vector *children = container->get_children(); + const Container::Vector *children = container->get_view_children();//we want to display only children meant to be displayed + if(children->empty())children = container->get_children(); for (Container::VectorIt i = children->begin(); i != children->end(); i++) { @@ -829,8 +837,10 @@ public: while (!containers->empty()) { const Container * c = containers->top(); containers->pop(); - for (Container::VectorIt i = c->get_children()->begin(); - i != c->get_children()->end(); + const Container::Vector *children = c->get_view_children();//we want to display only children meant to be displayed + if(children->empty())children = c->get_children(); + for (Container::VectorIt i = children->begin(); + i != children->end(); i++){ containers->push(*i); container->push_back(*i); diff --git a/src/trace/Trace.cpp b/src/trace/Trace.cpp index 23af4e04b31f7a7e8771df714d07f78a7c6f4c80..0b95b0c66785091c11eccbf916a4d20de6ab74be 100644 --- a/src/trace/Trace.cpp +++ b/src/trace/Trace.cpp @@ -347,6 +347,18 @@ const Container::Vector *Trace::get_root_containers() const { return &_root_containers; } +void Trace::set_root_containers(Container::Vector& conts) { + _root_containers=conts; +} + +const Container::Vector *Trace::get_view_root_containers() const { + return &_view_root_containers; +} + +void Trace::set_view_root_containers(Container::Vector& conts) { + _view_root_containers=conts; +} + void Trace::get_all_containers(Container::Vector &list_to_fill) const { Container::VectorIt it = _root_containers.begin(); Container::VectorIt const &end = _root_containers.end(); diff --git a/src/trace/Trace.hpp b/src/trace/Trace.hpp index 5a7dc19cecc459e5405fce4041d5ca1e0923d5c6..de8be36233c7e4ca1fda4cce16521e3df9374e63 100644 --- a/src/trace/Trace.hpp +++ b/src/trace/Trace.hpp @@ -73,6 +73,7 @@ private: Date _max_date; std::list<ContainerType *> _root_container_types; Container::Vector _root_containers; + Container::Vector _view_root_containers; std::list<StateType *> _state_types; std::list<EventType *> _event_types; std::list<LinkType *> _link_types; @@ -296,6 +297,24 @@ public : */ const Container::Vector *get_root_containers() const; + /*! + * \fn get_view_root_containers() const + * \brief Get the list of the root containers to be displayed + */ + const Container::Vector *get_view_root_containers() const; + + /*! + * \fn set_root_containers() + * \brief allows to replace the root containers of the trace, to reorder them + */ + void set_root_containers( std::list<Container*>& conts); + + /*! + * \fn set_root_containers() + * \brief allows to change the view of containers + */ + void set_view_root_containers( std::list<Container*>& conts); + /*! * \fn get_all_containers(Container::Vector &list_to_fill) const * \brief Get the list of all the containers