Fork me on GitHub
2.15.20
FGx
A cross-platform launcher for FlightGear
propstreewidget.cpp
Go to the documentation of this file.
1 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-
2 // FGx FlightGear Launcher // propstreewidget.cpp
3 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-
4 // (c) 2010-2012
5 // Yves Sablonier, Pete Morgan
6 // Geoff McLane
7 // GNU GPLv2, see main.cpp and shipped licence.txt for further information
8 
9 #include <QHostAddress>
10 #include <QNetworkInterface>
11 
12 #include <QList>
13 
14 #include <QVBoxLayout>
15 #include <QSplitter>
16 #include <QToolBar>
17 #include <QAction>
18 #include <QAbstractItemView>
19 #include <QTreeWidgetItem>
20 #include <QIcon>
21 #include <QFont>
22 
23 
24 #include "props/propstreewidget.h"
25 #include "props/propeditwidget.h"
26 
27 /*
28 
29 
30 
31  --TODO--
32  Move tree columns numbers to constants
33 
34  */
35 
37  QWidget(parent)
38 {
39 
40  mainObject = mOb;
41 
42  setProperty("settings_namespace", QVariant("properties_window"));
44 
45  telnet = new TelnetSlave(this);
46 
47  connect(telnet, SIGNAL(props_folder(QString, QString)),
48  this, SLOT(on_props_folder(QString, QString))
49  );
50  connect(telnet, SIGNAL(props_value(QString, QString, QString, QString)),
51  this, SLOT(on_props_value(QString, QString, QString, QString))
52  );
53  connect(telnet, SIGNAL(telnet_connected(bool)),
54  this, SLOT(on_telnet_connected(bool))
55  );
56 
57  setWindowTitle("Property Tree Browser");
58  setWindowIcon(QIcon(":/icon/props"));
59 
60 
61  //* Main Layout
62  QVBoxLayout *mainLayout = new QVBoxLayout();
63  setLayout(mainLayout);
64  mainLayout->setSpacing(0);
65  mainLayout->setContentsMargins(0,0,0,0);
66 
67  QSplitter *splitter = new QSplitter(this);
68  mainLayout->addWidget(splitter);
69 
70  //***************************************************
71  //** Left
72  QWidget *leftWidget = new QWidget();
73  splitter->addWidget(leftWidget);
74  QVBoxLayout *treeLayout = new QVBoxLayout();
75  leftWidget->setLayout(treeLayout);
76  treeLayout->setContentsMargins(0,0,0,0);
77  treeLayout->setSpacing(0);
78 
79 
80  //== Toolbar
81  QToolBar *treeToolbar = new QToolBar();
82  treeLayout->addWidget(treeToolbar);
83  treeToolbar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
84 
85  //===========================================================
86  // Telnet
87  //===========================================================
88 
89  //= Host
90  comboHost = new QComboBox();
91  comboHost->setMaximumWidth(100);
92  //comboHost->setText("localhost");
93  treeToolbar->addWidget(comboHost);
94  QList<QHostAddress> addresses = QNetworkInterface::allAddresses();
95  for (int i = 0; i < addresses.size(); ++i) {
96  if(addresses.at(i).protocol() == QAbstractSocket::IPv4Protocol){
97  comboHost->addItem( addresses.at(i).toString(), addresses.at(i).toString() );
98  }
99  }
100  comboHost->setCurrentIndex(0);
101 
102  //= Port
103  txtPort = new QLineEdit();
104  txtPort->setMaximumWidth(50);
105  //txtPort->setText(mainObject->settings->value("telnet_port").toString());
106  txtPort->setText("6666");
107  treeToolbar->addWidget(txtPort);
108 
109  //= Connect
110  actionConnect = new QAction(this);
111  actionConnect->setText("Connect");
112  actionConnect->setIcon(QIcon(":/icon/connect"));
113  actionConnect->setDisabled(false);
114  treeToolbar->addAction(actionConnect);
115  connect(actionConnect, SIGNAL(triggered()), this, SLOT(telnet_connect()) );
116 
117  //= Disconnect
118  actionDisconnect = new QAction(this);
119  actionDisconnect->setText("DisConnect");
120  actionDisconnect->setIcon(QIcon(":/icon/disconnect"));
121  actionDisconnect->setDisabled(true);
122  treeToolbar->addAction(actionDisconnect);
123  connect(actionDisconnect, SIGNAL(triggered()), this, SLOT(telnet_disconnect()) );
124 
125 
126  treeToolbar->addSeparator();
127 
128  //== Refresh Button
129  QAction *actionRefreshTree = new QAction(this);
130  treeToolbar->addAction(actionRefreshTree);
131  actionRefreshTree->setText("Refresh");
132  actionRefreshTree->setIcon(QIcon(":/icon/refresh"));
133  connect(actionRefreshTree, SIGNAL(triggered()), this, SLOT(load_nodes()) );
134 
135 
136  treeToolbar->addSeparator();
137 
138  //========================
139  //== Autorefresh
140  timer = new QTimer(this);
141  timer->setInterval(1000); //TODO default more
142 
143  //== Check Autorefresh enabled
144  chkAutoRefresh = new QCheckBox();
145  treeToolbar->addWidget(chkAutoRefresh);
146  chkAutoRefresh->setText("Autorefresh Enabled");
147  chkAutoRefresh->setCheckState(Qt::Unchecked);
148  connect(chkAutoRefresh, SIGNAL(toggled(bool)),
149  this, SLOT(on_auto_refresh_enabled())
150  );
151 
152  //== ComboBox sets refresh rate
153  comboAutoRefreshRate = new QComboBox();
154  treeToolbar->addWidget(comboAutoRefreshRate);
155  comboAutoRefreshRate->addItem("1");
156  comboAutoRefreshRate->addItem("2");
157  comboAutoRefreshRate->addItem("3");
158  comboAutoRefreshRate->addItem("4");
159  comboAutoRefreshRate->addItem("5");
160  connect(comboAutoRefreshRate, SIGNAL(activated(int)),
161  this, SLOT(on_set_timer_rate())
162  );
163 
164  treeToolbar->addSeparator();
165 
166  //== Edit Property Action
167  actionEditProperty = new QAction(this);
168  actionEditProperty->setText("Edit");
169  actionEditProperty->setDisabled(true);
170  actionEditProperty->setIcon(QIcon(":/icons/node_val"));
171  treeToolbar->addAction(actionEditProperty);
172  connect(actionEditProperty, SIGNAL(triggered()), this, SLOT(on_edit_property()) );
173  actionEditProperty->setVisible(false);
174 
175  QAction *actionTest = new QAction(this);
176  actionTest->setText("Test");
177  treeToolbar->addAction(actionTest);
178  connect(actionTest, SIGNAL(triggered()), this, SLOT(on_test_()) );
179  actionTest->setVisible(false);
180 
181 
182  //======================================================
183  //= Models
184  model = new QStandardItemModel(this);
185  model->setColumnCount(4);
186  QStringList headers;
187  headers << "Node" << "Value" << "Type" << "Path";
188  model->setHorizontalHeaderLabels(headers);
189 
190 
191  proxyModel = new QSortFilterProxyModel(this);
192  proxyModel->setSourceModel(model);
193 
194 
195  //======================================================
196  //=== Tree View
197  tree = new QTreeView(this);
198  treeLayout->addWidget(tree);
199  tree->setModel(model);
200 
201  tree->setItemsExpandable(true);
202  tree->setUniformRowHeights(true);
203  tree->setAlternatingRowColors(true);
204  tree->setRootIsDecorated(true);
205  tree->setSelectionMode(QAbstractItemView::SingleSelection);
206  tree->setSelectionBehavior(QAbstractItemView::SelectRows);
207  tree->sortByColumn(C_NODE, Qt::AscendingOrder);
208  tree->setSortingEnabled(true);
209 
210  /*
211  QTreeWidgetItem *headerItem = tree->headerItem();
212  headerItem->setText(C_NODE, tr("Property"));
213  headerItem->setText(C_VALUE, tr("Value"));
214  headerItem->setText(C_TYPE, tr("Type"));
215  headerItem->setText(C_PATH, tr("Full Path"));
216  */
217  tree->setColumnWidth(C_NODE, 200);
218  tree->setColumnWidth(C_VALUE, 200);
219 
220  /*
221  connect(tree, SIGNAL(itemExpanded(QTreeWidgetItem*)),
222  this, SLOT(on_item_expanded(QTreeWidgetItem*))
223  );
224  connect(tree, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)),
225  this, SLOT(on_item_double_clicked(QTreeWidgetItem*,int))
226  ); */
227  //connect(treeWidget, SIGNAL(itemSelectionChanged()),
228  // this, SLOT(on_on_aiport_selection_changedselection_changed())
229  //);
230 
231 
232  statusBarTree = new QStatusBar();
233  treeLayout->addWidget(statusBarTree);
234  statusBarTree->showMessage("Idle");
235 }
236 
237 //=============================================
239  //mainObject->telnet->fg_connect();
240  telnet->get_node("/");
241  qDebug() << "get_node /";
242 }
243 
244 
245 //================================
246 // make_row - returns a list of standard items
247 QList<QStandardItem *> PropsTreeWidget::make_row(QString node_name, QString node_value, QString node_type, QString end_path, bool is_folder)
248 {
249  QList<QStandardItem *> items;
250 
251  QStandardItem *name = new QStandardItem(node_name);
252  name->setIcon(QIcon(is_folder ? ":/icon/folder" : ":/icon/prop_node"));
253  QStandardItem *value = new QStandardItem(node_value);
254  QStandardItem *type = new QStandardItem(node_type);
255  QStandardItem *path = new QStandardItem(end_path);
256 
257  items << name << value << type << path;
258  return items;
259 }
260 
261 
262 //=========================================================================
263 //== On Props Folder
264 //=========================================================================
265 void PropsTreeWidget::on_props_folder(QString parent_path, QString path){
266 
267  //= Find if actual path end node is already there
268  QString end_path = QString(parent_path).append(path);
269  QList<QStandardItem *> items = model->findItems(end_path, Qt::MatchExactly | Qt::MatchRecursive, C_PATH);
270  if( items.size() > 0){
271  return; //= node exists so no need to add
272  }
273  //== Find the parent and add child
274  if(parent_path == "/"){
275  //= add top level item
276  model->invisibleRootItem()->appendRow(make_row(path, "","",path, true));
277  //qDebug() << path;
278  //telnet->get_node(path);
279  }else{
280  //= Find parent and append child node
281  QList<QStandardItem *> fitems = model->findItems(path, Qt::MatchExactly | Qt::MatchRecursive, C_PATH);
282  fitems.at(0)->appendRow( make_row(path, "","",path, true) );
283  }
284 
285  //telnet->get_node(path);
286 }
287 
288 //========================================================================
289 //== On props Value
290 //========================================================================
291 void PropsTreeWidget::on_props_value(QString parent_path, QString node_name,
292  QString node_value, QString node_type){
293 
294  //qDebug() << parent_path << node_name << node_value;
295  //= Find if actual path end node is already there
296  QString end_path = QString(parent_path).append(node_name);
297  QList<QStandardItem *> existing_items = model->findItems(end_path,
298  Qt::MatchExactly | Qt::MatchRecursive,
299  C_PATH);
300  if( existing_items.size() > 0){
301  //= Node exists so update value
302  existing_items[0]->setText( node_value);
303  return;
304  }
305 
306  //= Find the parent and add child
307  if(parent_path == "/"){
308  model->invisibleRootItem()->appendRow( make_row(node_name, node_value, node_type, end_path, false) );
309 
310  }else{
311  QList<QStandardItem *> fitems = model->findItems(parent_path, Qt::MatchExactly | Qt::MatchRecursive, C_PATH);
312  fitems.at(0)->appendRow( make_row(node_name, node_value, node_type, end_path, false) );
313  }
314 }
315 
316 
317 
318 
319 
321  Q_UNUSED(item);
322  // qDebug() << "ON Expand=" << item->text(3);
323  // qDebug() << item->text(3);
324  //item->setIcon(0, QIcon(":/icon/folder")); // folder_open
325  /*
326  item->setText(1, tr("Refresh"));
327  QFont font = item->font(1);
328  font.setPointSize(7);
329  item->setFont(1, font);
330  QColor color(0, 0, 170);
331  item->setForeground(1, color);
332  item->setCheckState(1, Qt::Unchecked);
333  */
334  //telnet->get_node(item->text(3));
335 }
336 
337 //*** TODO ???
339  Q_UNUSED(col);
340  if(item->text(C_TYPE).length() == 0){
341  return;
342  }
343  actionEditProperty->trigger();
344 }
345 
346 
348  //QTreeWidgetItem *item = treeWidget->currentItem();
349  //if(!item){
350  // return;
351  //}
352  //** Using the Type column to determine if its a value as there is always a type
353  //actionEditProperty->setDisabled(item->text(C_TYPE).length() == 0);
354 }
355 
356 
357 
358 
359 //*************************************************************
360 //* checkbox to start/stop timer in toolbar check button
362  if( chkAutoRefresh->checkState() ){
363  timer->start();
364  }else{
365  timer->stop();
366  }
367 }
368 //** Combobox event to set timer rate
370  int rate = comboAutoRefreshRate->itemText( comboAutoRefreshRate->currentIndex() ).toInt();
371  timer->setInterval(rate * 1000);
372 }
373 
374 
375 
376 
377 
378 
380  return;
381 // PropEditWidget *propEditWidget = new PropEditWidget(mainObject);
382 // propEditWidget->set_from_item(treeWidget->currentItem());
383 // propEditWidget->exec();
384 }
385 
387  telnet->set_property("/autopilot/settings/target-speed-kt", "250");
388 }
389 
390 
391 //= window close
392 void PropsTreeWidget::closeEvent(QCloseEvent *event){
394  event->accept();
395 }
396 
397 
399  telnet->telnet_connect(comboHost->currentText(), txtPort->text().toInt());
400 }
403 }
404 
406  qDebug()<< "on_connect" << connected;
407  actionConnect->setEnabled(!connected);
408  actionDisconnect->setEnabled(connected);
409  if(connected){
410  telnet->get_node("/");
411  }
412 }
void closeEvent(QCloseEvent *event)
QList< QStandardItem * > make_row(QString node_name, QString node_value, QString node_type, QString full_path, bool is_folder)
QLineEdit * txtPort
void on_auto_refresh_enabled()
The MainObject is an extended QObject, and the main "controller" for FGx.
Definition: mainobject.h:66
QAction * actionEditProperty
QAction * actionConnect
MainObject * mainObject
void get_node(QString path)
Definition: telnetslave.cpp:75
QTreeView * tree
void saveWindow(QWidget *widget)
Saves a window's size and position.
Definition: xsettings.cpp:90
QCheckBox * chkAutoRefresh
void on_item_selection_changed()
void restoreWindow(QWidget *widget)
Restores a size window position.
Definition: xsettings.cpp:101
QStatusBar * statusBarTree
QSortFilterProxyModel * proxyModel
void on_props_folder(QString, QString)
void telnet_connect(QString address, int port)
Definition: telnetslave.cpp:43
QStandardItemModel * model
QComboBox * comboHost
void on_telnet_connected(bool)
void telnet_disconnect()
Definition: telnetslave.cpp:52
void on_item_double_clicked(QTreeWidgetItem *, int)
void on_props_value(QString, QString, QString, QString)
QAction * actionDisconnect
PropsTreeWidget(MainObject *mOb, QWidget *parent=0)
void set_property(QString path, QString value)
Definition: telnetslave.cpp:56
TelnetSlave * telnet
XSettings * settings
Definition: mainobject.h:85
void on_item_expanded(QTreeWidgetItem *)
QComboBox * comboAutoRefreshRate