Salome HOME
Update copyrights
[modules/yacs.git] / src / genericgui / PropertyEditor.cxx
1 // Copyright (C) 2006-2019  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include "PropertyEditor.hxx"
21
22 #include <QVBoxLayout>
23 #include <QToolButton>
24 #include <QIcon>
25 #include <QLabel>
26 #include <QMenu>
27 #include <QVariant>
28 #include <QActionGroup>
29 #include <QHeaderView>
30 #include <QLineEdit>
31 #include <QInputDialog>
32 #include <QMessageBox>
33 #include "guiObservers.hxx"
34 #include "Message.hxx"
35
36 //#define _DEVDEBUG_
37 #include "YacsTrace.hxx"
38
39 using namespace YACS::HMI;
40 //using namespace YACS::ENGINE;
41
42 /*! \class YACS::HMI::PropertyEditor
43  *  \brief A class to edit properties of a subject
44  *
45  */
46
47 PropertyEditor::PropertyEditor(Subject* subject,QWidget *parent):QWidget(parent),_subject(subject),_editing(false)
48 {
49   std::vector<std::string> v=_subject->knownProperties();
50   for (int i=0; i<v.size(); ++i)
51     {
52       _knownProperties <<  QString::fromStdString(v[i]);
53     }
54
55   _removeAction=new QAction(QIcon("icons:icon_minus.png"),"Remove Property",this);
56   _addAction=new QAction(QIcon("icons:icon_plus.png"),"Add Property",this);
57
58   _table=new QTableWidget;
59   _table->setColumnCount(2);
60   QStringList headers;
61   headers << "Name" << "Value";
62   _table->setHorizontalHeaderLabels(headers);
63   _table->verticalHeader()->hide();
64   _table->setSelectionMode(QAbstractItemView::SingleSelection);
65
66   connect(_table, SIGNAL(itemChanged(QTableWidgetItem *)),this, SLOT(onItemChanged(QTableWidgetItem *)));
67   connect(_removeAction, SIGNAL(triggered()), this, SLOT(onRemoveProperty()));
68
69   QHBoxLayout* hboxLayout = new QHBoxLayout();
70   hboxLayout->setMargin(0);
71   QToolButton* tb_options = new QToolButton();
72   tb_options->setCheckable(true);
73   QIcon icon;
74   icon.addFile("icons:icon_down.png");
75   icon.addFile("icons:icon_up.png", QSize(), QIcon::Normal, QIcon::On);
76   tb_options->setIcon(icon);
77   hboxLayout->addWidget(tb_options);
78   connect(tb_options, SIGNAL(toggled(bool)), this, SLOT(on_tb_options_toggled(bool)));
79
80   QLabel* label=new QLabel("Properties     ");
81   QFont font;
82   font.setBold(true);
83   font.setWeight(75);
84   label->setFont(font);
85   hboxLayout->addWidget(label);
86
87   _bar=new QToolBar();
88
89   QToolButton* button=new QToolButton();
90   button->setDefaultAction(_addAction);
91   button->setPopupMode(QToolButton::InstantPopup);
92   _bar->addWidget(button);
93
94   button=new QToolButton();
95   button->setDefaultAction(_removeAction);
96   _bar->addWidget(button);
97   hboxLayout->addWidget(_bar);
98
99   QVBoxLayout *layout = new QVBoxLayout;
100   layout->setMargin(0);
101   layout->addLayout(hboxLayout);
102   layout->addWidget(_table);
103   setLayout(layout);
104
105   _table->hide();
106   _bar->hide();
107
108   update();
109   updateMenu();
110
111   _editing=true;
112 }
113
114 PropertyEditor::~PropertyEditor()
115 {
116 }
117
118 //! Qt slot to remove the selected item in the table
119 /*!
120  */
121 void PropertyEditor::onRemoveProperty()
122 {
123   DEBTRACE("PropertyEditor::onRemoveProperty");
124   QList<QTableWidgetItem *> litems=_table->selectedItems();
125   if(litems.isEmpty())
126     return;
127   QTableWidgetItem *item =litems.first();
128   _propertyNames.removeOne(item->text());
129   _table->removeRow(_table->row(item));
130   updateMenu();
131   setProperties();
132 }
133
134 //! Qt slot to add a property item in the table
135 /*!
136  * \param action : the triggered action
137  */
138 void PropertyEditor::onAddProperty(QAction* action)
139 {
140   DEBTRACE("PropertyEditor::onAddProperty " << action->text().toStdString());
141   bool ok;
142   QString text=action->text();
143   if(text == "Other ...")
144     {
145       text = QInputDialog::getText(this, tr("New Property"),tr("Name:"), QLineEdit::Normal, "", &ok);
146       if (!ok || text.isEmpty())
147         return;
148     }
149
150   if(_propertyNames.contains(text))
151     {
152       QMessageBox::warning ( 0, "Property already defined", "Property already defined");
153       return;
154     }
155
156   _editing=false;
157   int row=_table->rowCount();
158   _table->setRowCount(row+1);
159
160   QTableWidgetItem *newItem = new QTableWidgetItem(text);
161   newItem->setFlags(newItem->flags() & ~Qt::ItemIsEditable);
162   _table->setItem(row,0, newItem);
163
164   newItem = new QTableWidgetItem();
165   _table->setItem(row,1, newItem);
166   _propertyNames << text;
167   _editing=true;
168   updateMenu();
169 }
170
171 //! Qt slot to change the value of a property item in the table
172 /*!
173  * \param item : the item changed
174  */
175 void PropertyEditor::onItemChanged(QTableWidgetItem * item)
176 {
177   DEBTRACE("PropertyEditor::onItemChanged " << _editing);
178   if(!_editing)
179     return;
180   setProperties();
181 }
182
183 //! Update the property items with their values in the subject
184 /*!
185  */
186 void PropertyEditor::update()
187 {
188   DEBTRACE("PropertyEditor::update " );
189   _editing=false;
190   QTableWidgetItem *newItem;
191   int row=0;
192   _table->setRowCount(0);
193   _propertyNames << QStringList();
194   std::map<std::string,std::string> props=_subject->getProperties();
195   for (std::map<std::string, std::string>::iterator it = props.begin(); it != props.end(); ++it)
196     {
197       _table->setRowCount(row+1);
198       QTableWidgetItem *newItem = new QTableWidgetItem(it->first.c_str());
199       newItem->setFlags(newItem->flags() & ~Qt::ItemIsEditable);
200       _table->setItem(row,0, newItem);
201
202       newItem = new QTableWidgetItem(it->second.c_str());
203       _table->setItem(row,1, newItem);
204       _propertyNames << it->first.c_str();
205       row=row+1;
206     }
207   _editing=true;
208 }
209
210 //! Update the menu used to add properties with the already set properties
211 /*!
212  */
213 void PropertyEditor::updateMenu()
214 {
215   DEBTRACE("PropertyEditor::updateMenu " );
216   QMenu* menu=new QMenu;
217   _addAction->setMenu(menu);
218
219   QActionGroup* actGroup=new QActionGroup(this);
220   connect(actGroup, SIGNAL(triggered(QAction*)), this, SLOT(onAddProperty(QAction*)));
221
222   QAction* anAction;
223   for (int i = 0; i < _knownProperties.size(); ++i)
224     {
225       if(_propertyNames.contains(_knownProperties.at(i)))
226         continue;
227       anAction= actGroup->addAction(_knownProperties.at(i)); 
228       anAction->setData(QVariant(_knownProperties.at(i)));
229       menu->addAction(anAction);
230     }
231   anAction= actGroup->addAction("Other ..."); 
232   menu->addAction(anAction);
233   anAction->setData(QVariant("..."));
234 }
235
236 //! Update the subject properties with the values stored in the table
237 /*!
238  */
239 void PropertyEditor::setProperties()
240 {
241   DEBTRACE("PropertyEditor::setProperties " );
242   QTableWidgetItem *item;
243   std::string name;
244   std::string value;
245   std::map<std::string,std::string> props;
246   for (int i = 0; i < _table->rowCount(); ++i)
247     {
248       item=_table->item(i,0);
249       name=item->data(Qt::DisplayRole).toString().toStdString();
250       item=_table->item(i,1);
251       value=item->data(Qt::DisplayRole).toString().toStdString();
252       props[name]=value;
253     }
254   bool ret=_subject->setProperties(props);
255   if(!ret)
256      Message mess;
257 }
258
259 void PropertyEditor::on_tb_options_toggled(bool checked)
260 {
261   DEBTRACE("PropertyEditor::on_tb_options_toggled " << checked);
262   if(checked)
263     {
264       _table->show();
265       _bar->show();
266     }
267   else
268     {
269       _table->hide();
270       _bar->hide();
271     }
272 }
273