src/SalomeApp/Test/Makefile \
src/GuiHelpers/Makefile \
src/TreeData/Makefile \
+ src/TreeData/Test/Makefile \
src/SALOME_SWIG/Makefile \
src/SALOME_SWIG/supervisionexample.py \
src/SALOME_SWIG/supervisiongeomexample.py \
nodist_libSalomeGuiHelpers_la_SOURCES = $(MOC_FILES)
-EXTRA_DIST=$(MOC_FILES:%_moc.cxx=%.hxx)
+EXTRA_DIST+=$(MOC_FILES:%_moc.cxx=%.hxx)
##
if GUI_ENABLE_CORBA
SUBDIRS_CORBA = TOOLSGUI Session SalomeApp GuiHelpers TreeData
+ SUBDIRS_CORBA += TreeData/Test
endif
+
##
# Extra Python packages
##
--- /dev/null
+# Copyright (C) 2010 CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+# -* Makefile *-
+#
+# Author : Guillaume Boulant (EDF)
+#
+
+include $(top_srcdir)/adm_local/unix/make_common_starter.am
+
+# moc-files generation
+%_moc.cxx: %.hxx
+ $(MOC) $< -o $@
+
+mostlyclean-local:
+ rm -f @builddir@/*_moc.cxx
+ rm -f @builddir@/*.qm
+
+# qt forms files generation (uic)
+ui_%.h: %.ui
+ $(UIC) -o $@ $<
+
+
+CORBA_CXXFLAGS=@OMNIORB_CXXFLAGS@ @OMNIORB_INCLUDES@
+CORBA_LIBS=@OMNIORB_LIBS@
+QT_CXXFLAGS=@QT_INCLUDES@ @QT_MT_INCLUDES@
+
+TEST_CPPFLAGS = \
+ $(QT_CXXFLAGS) \
+ $(CORBA_CXXFLAGS) \
+ $(KERNEL_CXXFLAGS) \
+ -I$(top_srcdir)/src/GuiHelpers \
+ -I$(top_srcdir)/src/TreeData
+
+TEST_LDFLAGS = \
+ $(CORBA_LIBS) $(QT_LIBS) \
+ $(top_builddir)/src/TreeData/libSalomeTreeData.la \
+ $(top_builddir)/src/GuiHelpers/libSalomeGuiHelpers.la \
+ $(KERNEL_LDFLAGS) -lSalomeLifeCycleCORBA -lSalomeKernelHelpers
+
+# Program targets
+bin_PROGRAMS = TreeData_guitester TreeData_tester
+
+MOC_FILES = \
+ mainwindow_moc.cxx
+
+UIC_FILES = \
+ ui_mainwindow.h
+
+BUILT_SOURCES = $(UIC_FILES)
+
+nodist_TreeData_guitester_SOURCES = $(MOC_FILES) $(UIC_FILES)
+
+TreeData_guitester_SOURCES = \
+ testhelper.cxx \
+ guitester.cxx \
+ mainwindow.cxx \
+ MyDataModel.cxx
+
+TreeData_guitester_CPPFLAGS = \
+ $(TEST_CPPFLAGS)
+
+TreeData_guitester_LDFLAGS = \
+ $(TEST_LDFLAGS)
+
+TreeData_tester_SOURCES = \
+ tester.cxx \
+ MyDataModel.cxx
+
+TreeData_tester_CPPFLAGS = \
+ $(TEST_CPPFLAGS)
+
+TreeData_tester_LDFLAGS = \
+ $(TEST_LDFLAGS)
+
+# test data files
+testdir = $(salomeresdir)/testdata
+test_DATA = \
+ data.txt
+
+EXTRA_DIST+=$(test_DATA)
+
--- /dev/null
+#include "MyDataModel.hxx"
+
+//
+// =================================================================
+// MyDataObject implementation
+// =================================================================
+//
+
+const string MyDataObject::PROPERTY_KEY_TYPE = "type";
+const string MyDataObject::PROPERTY_KEY_CIRCUIT ="circuit";
+const string MyDataObject::PROPERTY_KEY_REPFONC ="rf";
+
+MyDataObject::MyDataObject() : DataObject() {
+ this->setProperty(PROPERTY_KEY_TYPE, "Tuyauterie");
+ this->setProperty(PROPERTY_KEY_CIRCUIT,"RRA");
+ this->setProperty(PROPERTY_KEY_REPFONC,"RF_01");
+}
+
+/*! This function specified the localization of the object in the
+ * hierarchical organization
+ */
+string MyDataObject::getPath() {
+ // We choose here a convention for organizing the path for this
+ // class of object.
+ /*
+ string path = getProperty(PROPERTY_KEY_CIRCUIT) + pathsep
+ + getProperty(PROPERTY_KEY_REPFONC) + pathsep
+ + getProperty(PROPERTY_KEY_TYPE);
+ */
+ string path = getProperty(PROPERTY_KEY_TYPE) + pathsep
+ + getProperty(PROPERTY_KEY_CIRCUIT) + pathsep
+ + getProperty(PROPERTY_KEY_REPFONC);
+
+ return path;
+}
+
+//
+// =================================================================
+// MyDataModel implementation
+// =================================================================
+//
+MyDataModel::MyDataModel() : DataModel() {
+}
+
+DataObject * MyDataModel::newDataObject() {
+ MyDataObject * dataObject = new MyDataObject();
+ return dataObject;
+}
--- /dev/null
+#ifndef _MYDATAMODEL_H_
+#define _MYDATAMODEL_H_
+
+//
+// =================================================================
+// Definition of an atom in the data model as an implementation of
+// the virtual class DataObject
+// =================================================================
+//
+
+#include "DataObject.hxx"
+class MyDataObject: public DataObject {
+public:
+ MyDataObject();
+ virtual string getPath();
+ static const string PROPERTY_KEY_TYPE;
+ static const string PROPERTY_KEY_CIRCUIT;
+ static const string PROPERTY_KEY_REPFONC;
+};
+
+
+//
+// =================================================================
+// Definition of the data model as an implementation of the virtual
+// class DataModel. It implements the DataObject factory.
+// =================================================================
+//
+#include "DataModel.hxx"
+class MyDataModel: public DataModel {
+public:
+ MyDataModel();
+ virtual DataObject * newDataObject();
+};
+
+#endif // _MYDATAMODEL_H_
--- /dev/null
+Tuyauterie;RF1;T1\r
+Tuyauterie;RF1;T2\r
+Tuyauterie;RF1;T3\r
+Tuyauterie;RF2;T1\r
+Tuyauterie;RF3;T1\r
+Tuyauterie;RF3;T2\r
+Composansts;RF1;T1\r
+Composansts;RF1;T2\r
+Composansts;RF3;T2\r
+Genie Civil;RF1;T1\r
+Genie Civil;RF1;T2\r
+Genie Civil;RF1;T3\r
+Genie Civil;RF2;T1\r
+Genie Civil;RF3;T1\r
+Genie Civil;RF3;T2\r
--- /dev/null
+#include <QApplication>
+#include <QMainWindow>
+#include <QDockWidget>
+#include <QTreeView>
+
+#include <Basics_Utils.hxx>
+
+//
+// =================================================================
+// Generic helper functions
+// =================================================================
+//
+/*!
+ * This functions displays a main window that embeds the specified
+ * widget. A dockwidget is used to create a context similar to as the
+ * SALOME target context.
+ */
+void showWidget(QWidget * widget) {
+
+ QMainWindow * window = new QMainWindow();
+
+ // Prepare a gui framework for testing the widget. We use a
+ // dockwidget, just to be in a context similar to as the SALOME
+ // target context.
+ QDockWidget * dwDataPanel = new QDockWidget(window);
+ dwDataPanel->setVisible(true);
+ dwDataPanel->setWindowTitle("XCAD data model");
+ window->addDockWidget(Qt::LeftDockWidgetArea, dwDataPanel);
+
+ // Then plug the widget in the dock widget framework:
+ widget->setParent(dwDataPanel);
+ widget->setMinimumHeight(300);
+ dwDataPanel->setWidget(widget);
+
+ window->show();
+}
+
+//
+// =================================================================
+// Tests functions for TreeModel
+// =================================================================
+//
+#include "TreeModel.hxx"
+#include "MyDataModel.hxx"
+#include "testhelper.hxx"
+
+
+/*!
+ * This function fills the specified tree with data that show
+ * different levels of path in the tree.
+ */
+void _TEST_treemodel_addData_01(TreeModel * dataTreeModel) {
+ // We can first add categories (for example to set categories
+ // properties)
+ QStringList path;
+ DataObject * folder;
+
+ path << "folder_1";
+ folder = TESTHELPER_dummyObject("folder_1.1");
+ dataTreeModel->addData(folder, path);
+ folder = TESTHELPER_dummyObject("folder_1.2");
+ dataTreeModel->addData(folder, path);
+
+ path.clear();
+ path << "folder_2";
+ folder = TESTHELPER_dummyObject("folder_2.1");
+ dataTreeModel->addData(folder, path);
+
+ // Then we can add data
+ DataObject * data;
+ path.clear();
+ path << "folder_1" << "folder_1.1";
+ data = TESTHELPER_dummyObject("data_1.1.1");
+ dataTreeModel->addData(data, path);
+ data = TESTHELPER_dummyObject("data_1.1.2");
+ dataTreeModel->addData(data, path);
+ // You can notice that there is no conceptual difference between a
+ // folder and an item, as in the QTreeModel.
+
+ // No limit to the depth
+ path.clear();
+ path << "xcad" << "data1" << "x" << "y";
+ data = TESTHELPER_dummyObject("z");
+ dataTreeModel->addData(data,path);
+}
+
+#define LOOPSIZE 15
+/*!
+ * This function fills the specified tree with a huge amount of data
+ */
+void _TEST_treemodel_addData_02(TreeModel * dataTreeModel) {
+ QStringList path;
+ DataObject * data;
+
+ START_TIMING(treemodel);
+ for (int i=0; i<LOOPSIZE; i++) {
+ END_TIMING(treemodel,1);
+ for (int j=0; j<LOOPSIZE; j++) {
+ for (int k=0; k<LOOPSIZE; k++) {
+ // The data list corresponds to the path of the item in the tree
+ path << QString("folder_%0").arg(i)
+ << QString("subfolder_%0_%1").arg(i).arg(j);
+ data = TESTHELPER_dummyObject(QString("item_%0_%1_%2").arg(i).arg(j).arg(k));
+ dataTreeModel->addData(data,path);
+ path.clear();
+ }
+ }
+ }
+ END_TIMING(treemodel,1);
+}
+
+void _TEST_treemodel_addData_03(TreeModel * dataTreeModel) {
+ MyDataObject * dataObject = new MyDataObject();
+ dataObject->setProperty(MyDataObject::PROPERTY_KEY_TYPE, "Tuyauterie");
+ dataObject->setProperty(MyDataObject::PROPERTY_KEY_CIRCUIT, "RCP");
+ dataObject->setProperty(MyDataObject::PROPERTY_KEY_REPFONC, "RF1");
+ dataTreeModel->addData(dataObject);
+
+ dataObject = new MyDataObject();
+ dataObject->setProperty(MyDataObject::PROPERTY_KEY_TYPE, "Tuyauterie");
+ dataObject->setProperty(MyDataObject::PROPERTY_KEY_CIRCUIT, "RCP");
+ dataObject->setProperty(MyDataObject::PROPERTY_KEY_REPFONC, "RF1");
+ dataTreeModel->addData(dataObject);
+
+ dataObject = new MyDataObject();
+ dataObject->setProperty(MyDataObject::PROPERTY_KEY_TYPE, "Tuyauterie");
+ dataObject->setProperty(MyDataObject::PROPERTY_KEY_CIRCUIT, "RCP");
+ dataObject->setProperty(MyDataObject::PROPERTY_KEY_REPFONC, "RF2");
+ dataTreeModel->addData(dataObject);
+
+ dataObject = new MyDataObject();
+ dataObject->setProperty(MyDataObject::PROPERTY_KEY_TYPE, "Tuyauterie");
+ dataObject->setProperty(MyDataObject::PROPERTY_KEY_CIRCUIT, "RRA");
+ dataObject->setProperty(MyDataObject::PROPERTY_KEY_REPFONC, "RF1");
+ dataTreeModel->addData(dataObject);
+
+ dataObject = new MyDataObject();
+ dataObject->setProperty(MyDataObject::PROPERTY_KEY_TYPE, "Génie civil");
+ dataObject->setProperty(MyDataObject::PROPERTY_KEY_CIRCUIT, "RRA");
+ dataObject->setProperty(MyDataObject::PROPERTY_KEY_REPFONC, "RF1");
+ dataTreeModel->addData(dataObject);
+}
+
+/*!
+ * This test function shows how it's possible to load data from a file
+ * to populate the tree model.
+ */
+void _TEST_treemodel_loadDataFromFile(TreeModel * dataTreeModel, const QString &filename) {
+ TESTHELPER_loadDataFromFile(dataTreeModel, filename);
+}
+
+/*!
+ * Main test function for the tree model demo.
+ */
+#include "TreeModel.hxx"
+#include "TreeView.hxx"
+void TEST_treemodel() {
+
+ START_TIMING(treemodel);
+
+ // We first prepare a data view embedding a tree model
+ TreeView * dataView = new TreeView();
+ QStringList headers;
+ headers << QObject::tr("Name") << QObject::tr("Value");
+ TreeModel * dataTreeModel = new TreeModel(headers);
+ dataView->setModel(dataTreeModel);
+ END_TIMING(treemodel,1);
+
+ // Then we can fill the tree model with data. Can proceed with
+ // different ways (comment/uncomment which you want to test):
+ _TEST_treemodel_loadDataFromFile(dataTreeModel, TESTHELPER_testfilename(DATAFILENAME));
+ //_TEST_treemodel_addData_01(dataTreeModel);
+ //_TEST_treemodel_addData_02(dataTreeModel);
+ //_TEST_treemodel_addData_03(dataTreeModel);
+ // Finally, show the widget in a main window
+ END_TIMING(treemodel,1);
+
+ showWidget(dataView);
+ END_TIMING(treemodel,1);
+}
+
+//
+// =================================================================
+// Tests functions for TreeModel with interactive changes
+// =================================================================
+//
+#include "mainwindow.hxx"
+void TEST_treemodel_interactif() {
+ MainWindow * window = new MainWindow();
+ window->show();
+}
+
+//
+// =================================================================
+//
+int main(int argc, char * argv[ ])
+{
+ QApplication app(argc, argv);
+ TEST_treemodel();
+ //TST_treemodel_interactif();
+ return app.exec();
+}
--- /dev/null
+#include <QtGui>
+
+#include "mainwindow.hxx"
+#include "TreeModel.hxx"
+
+#include <Basics_Utils.hxx>
+#include "testhelper.hxx"
+
+MainWindow::MainWindow(QWidget *parent)
+ : QMainWindow(parent)
+{
+ setupUi(this);
+
+ QStringList headers;
+ headers << tr("Title") << tr("Description");
+
+ TreeModel *model = new TreeModel(headers);
+ TESTHELPER_loadDataFromFile(model, TESTHELPER_testfilename(DATAFILENAME));
+
+ view->setModel(model);
+ for (int column = 0; column < model->columnCount(); ++column)
+ view->resizeColumnToContents(column);
+
+ connect(exitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
+
+ connect(view->selectionModel(),
+ SIGNAL(selectionChanged(const QItemSelection &,
+ const QItemSelection &)),
+ this, SLOT(updateActions()));
+
+ connect(actionsMenu, SIGNAL(aboutToShow()), this, SLOT(updateActions()));
+ connect(insertRowAction, SIGNAL(triggered()), this, SLOT(insertRow()));
+ connect(insertColumnAction, SIGNAL(triggered()), this, SLOT(insertColumn()));
+ connect(removeRowAction, SIGNAL(triggered()), this, SLOT(removeRow()));
+ connect(removeColumnAction, SIGNAL(triggered()), this, SLOT(removeColumn()));
+ connect(insertChildAction, SIGNAL(triggered()), this, SLOT(insertChild()));
+ connect(newDataAction, SIGNAL(triggered()), this, SLOT(newData()));
+
+ updateActions();
+}
+
+void MainWindow::newData() {
+ LOG("MainWindow::newData(): START");
+
+ bool ok;
+ QString text = QInputDialog::getText(this, tr("QInputDialog::getText()"),
+ tr("Data path:"), QLineEdit::Normal,
+ "folder/subfolder/item", &ok);
+ if (!ok || text.trimmed().isEmpty())
+ return;
+
+ QStringList path = text.trimmed().split("/");
+ TreeModel *model = (TreeModel *)view->model();
+
+ QString label = path.last();
+ path.removeLast();
+ DataObject * data = TESTHELPER_dummyObject(label);
+ model->addData(data,path);
+
+ LOG("MainWindow::newData(): END");
+}
+
+void MainWindow::insertChild()
+{
+ QModelIndex index = view->selectionModel()->currentIndex();
+ QAbstractItemModel *model = view->model();
+
+ if (model->columnCount(index) == 0) {
+ if (!model->insertColumn(0, index))
+ return;
+ }
+
+ if (!model->insertRow(0, index))
+ return;
+
+ for (int column = 0; column < model->columnCount(index); ++column) {
+ QModelIndex child = model->index(0, column, index);
+ model->setData(child, QVariant("[No data]"), Qt::EditRole);
+ if (!model->headerData(column, Qt::Horizontal).isValid())
+ model->setHeaderData(column, Qt::Horizontal, QVariant("[No header]"),
+ Qt::EditRole);
+ }
+
+ view->selectionModel()->setCurrentIndex(model->index(0, 0, index),
+ QItemSelectionModel::ClearAndSelect);
+ updateActions();
+}
+
+bool MainWindow::insertColumn(const QModelIndex &parent)
+{
+ QAbstractItemModel *model = view->model();
+ int column = view->selectionModel()->currentIndex().column();
+
+ // Insert a column in the parent item.
+ bool changed = model->insertColumn(column + 1, parent);
+ if (changed)
+ model->setHeaderData(column + 1, Qt::Horizontal, QVariant("[No header]"),
+ Qt::EditRole);
+
+ updateActions();
+
+ return changed;
+}
+
+void MainWindow::insertRow()
+{
+ QModelIndex index = view->selectionModel()->currentIndex();
+ QAbstractItemModel *model = view->model();
+
+ if (!model->insertRow(index.row()+1, index.parent()))
+ return;
+
+ updateActions();
+
+ for (int column = 0; column < model->columnCount(index.parent()); ++column) {
+ QModelIndex child = model->index(index.row()+1, column, index.parent());
+ model->setData(child, QVariant("[No data]"), Qt::EditRole);
+ }
+}
+
+bool MainWindow::removeColumn(const QModelIndex &parent)
+{
+ QAbstractItemModel *model = view->model();
+ int column = view->selectionModel()->currentIndex().column();
+
+ // Insert columns in each child of the parent item.
+ bool changed = model->removeColumn(column, parent);
+
+ if (!parent.isValid() && changed)
+ updateActions();
+
+ return changed;
+}
+
+void MainWindow::removeRow()
+{
+ QModelIndex index = view->selectionModel()->currentIndex();
+ QAbstractItemModel *model = view->model();
+ if (model->removeRow(index.row(), index.parent()))
+ updateActions();
+}
+
+void MainWindow::updateActions()
+{
+ bool hasSelection = !view->selectionModel()->selection().isEmpty();
+ removeRowAction->setEnabled(hasSelection);
+ removeColumnAction->setEnabled(hasSelection);
+
+ bool hasCurrent = view->selectionModel()->currentIndex().isValid();
+ insertRowAction->setEnabled(hasCurrent);
+ insertColumnAction->setEnabled(hasCurrent);
+
+ if (hasCurrent) {
+ view->closePersistentEditor(view->selectionModel()->currentIndex());
+
+ int row = view->selectionModel()->currentIndex().row();
+ int column = view->selectionModel()->currentIndex().column();
+ if (view->selectionModel()->currentIndex().parent().isValid())
+ statusBar()->showMessage(tr("Position: (%1,%2)").arg(row).arg(column));
+ else
+ statusBar()->showMessage(tr("Position: (%1,%2) in top level").arg(row).arg(column));
+ }
+}
+
+void MainWindow::contextMenuEvent(QContextMenuEvent *event) {
+ QMenu menu(this);
+ menu.addAction(newDataAction);
+ menu.exec(event->globalPos());
+}
--- /dev/null
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QMainWindow>
+#include <QModelIndex>
+
+#include "ui_mainwindow.h"
+
+class QAction;
+class QTreeView;
+class QWidget;
+
+class MainWindow : public QMainWindow, private Ui::MainWindow
+{
+ Q_OBJECT
+
+public:
+ MainWindow(QWidget *parent = 0);
+
+protected:
+ void contextMenuEvent(QContextMenuEvent *event);
+
+public slots:
+ void updateActions();
+
+private slots:
+ void insertChild();
+ bool insertColumn(const QModelIndex &parent = QModelIndex());
+ void insertRow();
+ bool removeColumn(const QModelIndex &parent = QModelIndex());
+ void removeRow();
+ void newData();
+};
+
+#endif
--- /dev/null
+<ui version="4.0" >
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>573</width>
+ <height>468</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Editable Tree Model</string>
+ </property>
+ <widget class="QWidget" name="centralwidget" >
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QTreeView" name="view" >
+ <property name="alternatingRowColors" >
+ <bool>true</bool>
+ </property>
+ <property name="selectionBehavior" >
+ <enum>QAbstractItemView::SelectItems</enum>
+ </property>
+ <property name="horizontalScrollMode" >
+ <enum>QAbstractItemView::ScrollPerPixel</enum>
+ </property>
+ <property name="animated" >
+ <bool>false</bool>
+ </property>
+ <property name="allColumnsShowFocus" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QMenuBar" name="menubar" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>573</width>
+ <height>29</height>
+ </rect>
+ </property>
+ <widget class="QMenu" name="actionsMenu" >
+ <property name="title" >
+ <string>&Actions</string>
+ </property>
+ <addaction name="insertRowAction" />
+ <addaction name="insertColumnAction" />
+ <addaction name="separator" />
+ <addaction name="removeRowAction" />
+ <addaction name="removeColumnAction" />
+ <addaction name="separator" />
+ <addaction name="insertChildAction" />
+ </widget>
+ <widget class="QMenu" name="fileMenu" >
+ <property name="title" >
+ <string>&File</string>
+ </property>
+ <addaction name="exitAction" />
+ </widget>
+ <widget class="QMenu" name="menuData" >
+ <property name="title" >
+ <string>Data</string>
+ </property>
+ <addaction name="newDataAction" />
+ </widget>
+ <addaction name="fileMenu" />
+ <addaction name="actionsMenu" />
+ <addaction name="menuData" />
+ </widget>
+ <widget class="QStatusBar" name="statusbar" />
+ <action name="exitAction" >
+ <property name="text" >
+ <string>E&xit</string>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+Q</string>
+ </property>
+ </action>
+ <action name="insertRowAction" >
+ <property name="text" >
+ <string>Insert Row</string>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+I, R</string>
+ </property>
+ </action>
+ <action name="removeRowAction" >
+ <property name="text" >
+ <string>Remove Row</string>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+R, R</string>
+ </property>
+ </action>
+ <action name="insertColumnAction" >
+ <property name="text" >
+ <string>Insert Column</string>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+I, C</string>
+ </property>
+ </action>
+ <action name="removeColumnAction" >
+ <property name="text" >
+ <string>Remove Column</string>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+R, C</string>
+ </property>
+ </action>
+ <action name="insertChildAction" >
+ <property name="text" >
+ <string>Insert Child</string>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+N</string>
+ </property>
+ </action>
+ <action name="newDataAction" >
+ <property name="text" >
+ <string>new</string>
+ </property>
+ </action>
+ </widget>
+ <resources>
+ <include location="editabletreemodel.qrc" />
+ </resources>
+ <connections/>
+</ui>
--- /dev/null
+#include "QtHelper.hxx"
+
+//
+// =================================================================
+// Helper functions for DataObject and DataModel classes
+// =================================================================
+//
+
+// ----
+// A DataObject can't be used as is but must be specialized to
+// specify the behavior in the hierarchic model.
+#include "MyDataModel.hxx"
+
+void TEST_DataObject() {
+ // In this test, the object id should increase at each instance
+ DataObject * dataObject;
+ for (int i=0; i<100; i++) {
+ dataObject = new MyDataObject();
+ QLOG("object nameId = " << dataObject->getNameId().c_str());
+ }
+ QLOG("path = " << dataObject->getPath().c_str());
+ QLOG("pathname = " << dataObject->getPathName().c_str());
+
+ QLOG("serialize= " << dataObject->toString().c_str());
+
+}
+
+void TEST_DataModel() {
+ MyDataModel * dataModel = new MyDataModel();
+
+ int refIter = 53;
+ string refNameId;
+
+ DataObject * dataObject;
+ for (int i=0; i<100; i++) {
+ // We can either create the data object using its constructor or
+ // using the factory of the model (the prefered way):
+ // dataObject = new MyDataObject();
+ dataObject = dataModel->newDataObject();
+ dataObject->setLabel("myobject"+ToString(i));
+ if ( i == refIter ) {
+ refNameId = dataObject->getNameId();
+ }
+ dataModel->addDataObject(dataObject);
+ }
+
+ dataObject = dataModel->getDataObject(refNameId);
+ QLOG("object nameId = " << dataObject->getNameId().c_str());
+ QLOG("path = " << dataObject->getPath().c_str());
+ QLOG("pathname = " << dataObject->getPathName().c_str());
+}
+
+//
+// =================================================================
+//
+int main(int argc, char * argv[ ])
+{
+ TEST_DataObject();
+ //TEST_DataModel();
+}
--- /dev/null
+
+
+#include "testhelper.hxx"
+
+#include <QFile>
+#include <QString>
+
+#include "QtHelper.hxx"
+#include "MyDataModel.hxx"
+
+// Standard C include (for getenv)
+#include <stdlib.h>
+
+QString TESTHELPER_testfilename(const char * basefilename) {
+ QString aFile;
+ char * GUI_ROOT_DIR = getenv("GUI_ROOT_DIR");
+ QString * root;
+ if ( GUI_ROOT_DIR != NULL ) {
+ root = new QString(GUI_ROOT_DIR);
+ }
+ else {
+ root = new QString("/home/gboulant/development/projets/salome/devel/XSALOME/install");
+ }
+ QString relativePathName = "/share/salome/resources/gui/testdata/";
+ aFile.append(*root + relativePathName + basefilename);
+
+ QLOG("The test file is : "<<aFile);
+ return aFile;
+}
+
+/*!
+ * This creates a dummy data object for the needs of the test
+ * functions. The label is the basename of the spécified pathname.
+ */
+DataObject * TESTHELPER_dummyObject(QString label) {
+ MyDataObject * dataObject = new MyDataObject();
+ dataObject->setLabel(QCHARSTAR(label));
+ return dataObject;
+}
+
+
+#define SEP ";"
+/*!
+ * This test function shows how it's possible to load data from a file
+ * to populate the tree model.
+ */
+void TESTHELPER_loadDataFromFile(TreeModel * dataTreeModel, const QString &filename) {
+ QFile file ( filename );
+ file.open ( QIODevice::ReadOnly );
+
+ MyDataObject * dataObject;
+ while ( 1 ) {
+ QByteArray byteArray = file.readLine();
+
+ if ( byteArray.isEmpty() )
+ break;
+
+ QString data = (QString ( byteArray.mid(0, byteArray.size()-1))).trimmed();
+ QStringList dataList = data.split ( SEP );
+ // The data list is used here to set properties (and then the path
+ // of location in the tree model).
+
+ dataObject = new MyDataObject();
+ // The label is autogenerated, but we may specify here a custom
+ // one. We just fill the properties with data values read in the
+ // file.
+ dataObject->setProperty(MyDataObject::PROPERTY_KEY_TYPE, QCHARSTAR(dataList[0]));
+ dataObject->setProperty(MyDataObject::PROPERTY_KEY_REPFONC, QCHARSTAR(dataList[1]));
+ dataObject->setProperty(MyDataObject::PROPERTY_KEY_CIRCUIT, QCHARSTAR(dataList[2]));
+ if ( ! dataTreeModel->addData(dataObject) ) {
+ QLOG("ERR: data not added");
+ }
+ }
+
+ file.close();
+}
--- /dev/null
+
+#ifndef _TESTHELPER_HXX_
+#define _TESTHELPER_HXX_
+
+#include <QString>
+#include "TreeModel.hxx"
+#include "DataObject.hxx"
+
+#define DATAFILENAME "data.txt"
+
+QString TESTHELPER_testfilename(const char * basefilename);
+DataObject * TESTHELPER_dummyObject(QString label);
+void TESTHELPER_loadDataFromFile(TreeModel * dataTreeModel, const QString &filename);
+
+#endif // _TESTHELPER_HXX_