13501
|
1 /* Quint - A graphical user interface for Octave |
|
2 * Copyright (C) 2011 Jacob Dawid |
|
3 * jacob.dawid@googlemail.com |
|
4 * |
|
5 * This program is free software: you can redistribute it and/or modify |
|
6 * it under the terms of the GNU General Public License as published by |
|
7 * the Free Software Foundation, either version 3 of the License, or |
|
8 * (at your option) any later version. |
|
9 * |
|
10 * This program is distributed in the hope that it will be useful, |
|
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
13 * GNU General Public License for more details. |
|
14 * |
|
15 * You should have received a copy of the GNU General Public License |
|
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
17 */ |
|
18 |
|
19 #include "VariablesDockWidget.h" |
|
20 #include <QHBoxLayout> |
|
21 #include <QVBoxLayout> |
|
22 #include <QPushButton> |
|
23 |
|
24 VariablesDockWidget::VariablesDockWidget(QWidget *parent) |
|
25 : QDockWidget(parent) { |
|
26 setObjectName("VariablesDockWidget"); |
|
27 construct(); |
|
28 } |
|
29 |
|
30 void VariablesDockWidget::construct() { |
|
31 m_updateSemaphore = new QSemaphore(1); |
|
32 QStringList headerLabels; |
|
33 headerLabels << tr("Name") << tr("Type") << tr("Value"); |
|
34 m_variablesTreeWidget = new QTreeWidget(this); |
|
35 m_variablesTreeWidget->setHeaderHidden(false); |
|
36 m_variablesTreeWidget->setHeaderLabels(headerLabels); |
|
37 QVBoxLayout *layout = new QVBoxLayout(); |
|
38 |
|
39 setWindowTitle(tr("Workspace")); |
|
40 setWidget(new QWidget()); |
|
41 |
|
42 layout->addWidget(m_variablesTreeWidget); |
|
43 QWidget *buttonBar = new QWidget(this); |
|
44 layout->addWidget(buttonBar); |
|
45 |
|
46 QHBoxLayout *buttonBarLayout = new QHBoxLayout(); |
|
47 QPushButton *saveWorkspaceButton = new QPushButton(tr("Save"), buttonBar); |
|
48 QPushButton *loadWorkspaceButton = new QPushButton(tr("Load"), buttonBar); |
|
49 QPushButton *clearWorkspaceButton = new QPushButton(tr("Clear"), buttonBar); |
|
50 buttonBarLayout->addWidget(saveWorkspaceButton); |
|
51 buttonBarLayout->addWidget(loadWorkspaceButton); |
|
52 buttonBarLayout->addWidget(clearWorkspaceButton); |
|
53 buttonBarLayout->setMargin(2); |
|
54 buttonBar->setLayout(buttonBarLayout); |
|
55 |
|
56 layout->setMargin(2); |
|
57 widget()->setLayout(layout); |
|
58 |
|
59 connect(saveWorkspaceButton, SIGNAL(clicked()), this, SLOT(emitSaveWorkspace())); |
|
60 connect(loadWorkspaceButton, SIGNAL(clicked()), this, SLOT(emitLoadWorkspace())); |
|
61 connect(clearWorkspaceButton, SIGNAL(clicked()), this, SLOT(emitClearWorkspace())); |
|
62 |
|
63 QTreeWidgetItem *treeWidgetItem = new QTreeWidgetItem(); |
|
64 treeWidgetItem->setData(0, 0, QString(tr("Local"))); |
|
65 m_variablesTreeWidget->insertTopLevelItem(0, treeWidgetItem); |
|
66 |
|
67 treeWidgetItem = new QTreeWidgetItem(); |
|
68 treeWidgetItem->setData(0, 0, QString(tr("Global"))); |
|
69 m_variablesTreeWidget->insertTopLevelItem(1, treeWidgetItem); |
|
70 |
|
71 treeWidgetItem = new QTreeWidgetItem(); |
|
72 treeWidgetItem->setData(0, 0, QString(tr("Persistent"))); |
|
73 m_variablesTreeWidget->insertTopLevelItem(2, treeWidgetItem); |
|
74 |
|
75 treeWidgetItem = new QTreeWidgetItem(); |
|
76 treeWidgetItem->setData(0, 0, QString(tr("Hidden"))); |
|
77 m_variablesTreeWidget->insertTopLevelItem(3, treeWidgetItem); |
|
78 |
|
79 m_variablesTreeWidget->expandAll(); |
|
80 m_variablesTreeWidget->setAlternatingRowColors(true); |
|
81 m_variablesTreeWidget->setAnimated(true); |
|
82 } |
|
83 |
|
84 void VariablesDockWidget::updateTreeEntry(QTreeWidgetItem *treeItem, SymbolRecord symbolRecord) { |
|
85 treeItem->setData(0, 0, QString(symbolRecord.name().c_str())); |
|
86 treeItem->setData(1, 0, QString(symbolRecord.varval().type_name().c_str())); |
|
87 treeItem->setData(2, 0, OctaveLink::octaveValueAsQString(symbolRecord.varval())); |
|
88 } |
|
89 |
|
90 void VariablesDockWidget::setVariablesList(QList<SymbolRecord> symbolTable) { |
|
91 m_updateSemaphore->acquire(); |
|
92 // Split the symbol table into its different scopes. |
|
93 QList<SymbolRecord> localSymbolTable; |
|
94 QList<SymbolRecord> globalSymbolTable; |
|
95 QList<SymbolRecord> persistentSymbolTable; |
|
96 QList<SymbolRecord> hiddenSymbolTable; |
|
97 |
|
98 foreach(SymbolRecord symbolRecord, symbolTable) { |
|
99 // It's true that being global or hidden includes it's can mean it's also locally visible, |
|
100 // but we want to distinguish that here. |
|
101 if(symbolRecord.is_local() && !symbolRecord.is_global() && !symbolRecord.is_hidden()) { |
|
102 localSymbolTable.append(symbolRecord); |
|
103 } |
|
104 |
|
105 if(symbolRecord.is_global()) { |
|
106 globalSymbolTable.append(symbolRecord); |
|
107 } |
|
108 |
|
109 if(symbolRecord.is_persistent()) { |
|
110 persistentSymbolTable.append(symbolRecord); |
|
111 } |
|
112 |
|
113 if(symbolRecord.is_hidden()) { |
|
114 hiddenSymbolTable.append(symbolRecord); |
|
115 } |
|
116 } |
|
117 |
|
118 updateScope(0, localSymbolTable); |
|
119 updateScope(1, globalSymbolTable); |
|
120 updateScope(2, persistentSymbolTable); |
|
121 updateScope(3, hiddenSymbolTable); |
|
122 m_updateSemaphore->release(); |
|
123 } |
|
124 |
|
125 void VariablesDockWidget::updateScope(int topLevelItemIndex, QList<SymbolRecord> symbolTable) { |
|
126 // This method may be a little bit confusing; variablesList is a complete list of all |
|
127 // variables that are in the workspace currently. |
|
128 QTreeWidgetItem *topLevelItem = m_variablesTreeWidget->topLevelItem(topLevelItemIndex); |
|
129 |
|
130 // First we check, if any variables that exist in the model tree have to be updated |
|
131 // or created. So we walk the variablesList check against the tree. |
|
132 foreach(SymbolRecord symbolRecord, symbolTable) { |
|
133 int childCount = topLevelItem->childCount(); |
|
134 bool alreadyExists = false; |
|
135 QTreeWidgetItem *child; |
|
136 |
|
137 // Search for the corresponding item in the tree. If it has been found, child |
|
138 // will contain the appropriate QTreeWidgetItem* pointing at it. |
|
139 for(int i = 0; i < childCount; i++) { |
|
140 child = topLevelItem->child(i); |
|
141 if(child->data(0, 0).toString() == QString(symbolRecord.name().c_str())) { |
|
142 alreadyExists = true; |
|
143 break; |
|
144 } |
|
145 } |
|
146 |
|
147 // If it already exists, just update it. |
|
148 if(alreadyExists) { |
|
149 updateTreeEntry(child, symbolRecord); |
|
150 } else { |
|
151 // It does not exist, so create a new one and set the right values. |
|
152 child = new QTreeWidgetItem(); |
|
153 updateTreeEntry(child, symbolRecord); |
|
154 topLevelItem->addChild(child); |
|
155 } |
|
156 } |
|
157 |
|
158 // Check the tree against the list for deleted variables. |
|
159 for(int i = 0; i < topLevelItem->childCount(); i++) { |
|
160 bool existsInVariableList = false; |
|
161 QTreeWidgetItem *child = topLevelItem->child(i); |
|
162 foreach(SymbolRecord symbolRecord, symbolTable) { |
|
163 if(QString(symbolRecord.name().c_str()) == child->data(0, 0).toString()) { |
|
164 existsInVariableList = true; |
|
165 } |
|
166 } |
|
167 |
|
168 if(!existsInVariableList) { |
|
169 topLevelItem->removeChild(child); |
|
170 delete child; |
|
171 i--; |
|
172 } |
|
173 } |
|
174 } |
|
175 |
|
176 void VariablesDockWidget::emitSaveWorkspace() { |
|
177 emit saveWorkspace(); |
|
178 } |
|
179 |
|
180 void VariablesDockWidget::emitLoadWorkspace() { |
|
181 emit loadWorkspace(); |
|
182 } |
|
183 |
|
184 void VariablesDockWidget::emitClearWorkspace() { |
|
185 emit clearWorkspace(); |
|
186 } |