VPTissue Reference Manual
Client.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2011-2016 Universiteit Antwerpen
3  *
4  * Licensed under the EUPL, Version 1.1 or as soon they will be approved by
5  * the European Commission - subsequent versions of the EUPL (the "Licence");
6  * You may not use this work except in compliance with the Licence.
7  * You may obtain a copy of the Licence at: http://ec.europa.eu/idabc/eupl5
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the Licence is distributed on an "AS IS" basis,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the Licence for the specific language governing
13  * permissions and limitations under the Licence.
14  */
20 #include "Client.h"
21 
22 #include "gui/WorkspaceWizard.h"
28 
29 #include "ExplorationSelection.h"
30 #include "ExplorationWizard.h"
31 #include "ServerDialog.h"
32 #include "Status.h"
33 #include "TaskOverview.h"
34 
35 #include "workspace/CliWorkspace.h"
36 
37 #include <QCloseEvent>
38 #include <QCoreApplication>
39 #include <QDir>
40 #include <QFileDialog>
41 #include <QHBoxLayout>
42 #include <QInputDialog>
43 #include <QMenuBar>
44 #include <QMessageBox>
45 #include <QStatusBar>
46 #include <QToolBar>
47 
48 #include <memory>
49 
50 namespace SimPT_Shell { namespace Ws { class WorkspaceFactory; }}
51 
52 namespace SimPT_Parex {
53 
54 using namespace boost::property_tree;
55 using namespace boost::property_tree::xml_parser;
56 using namespace SimPT_Shell;
57 
59  : m_client(nullptr), m_last_exploration(), m_settings("simPT Consortium", "Parex Client")
60 {
61  // Set variables for QSettings
62  QCoreApplication::setOrganizationName("SimPT Consortium");
63  QCoreApplication::setApplicationName("Parex Client");
64 
65  setWindowTitle("Parameter Exploration - Client");
66 
67  setMinimumWidth(750);
68 
69  QHBoxLayout* layout = new QHBoxLayout;
70 
71  m_status = new Status();
72  layout->addWidget(m_status);
73 
74  // Actions
75  action_connect = new QAction("&Connect...", this);
76  action_subscribe = new QAction("&Subscribe", this);
77  action_start_exploration = new QAction("&Start Exploration...", this);
78  action_delete_exploration = new QAction("&Delete exploration...", this);
79  action_download_exploration = new QAction("&Download exploration...", this);
80  action_workspace_wizard = new QAction("&Workspace...", this);
81  action_task_overview = new QAction("&Task overview", this);
82 
83  action_subscribe->setDisabled(true);
84  action_start_exploration->setDisabled(true);
85  action_delete_exploration->setDisabled(true);
86  action_download_exploration->setDisabled(true);
87  action_task_overview->setDisabled(true);
88 
89 
90  action_download_exploration->setVisible(false);
91 
92  action_connect->setShortcut(QKeySequence("Ctrl+C"));
93  action_subscribe->setShortcut(QKeySequence("Ctrl+U"));
94  action_start_exploration->setShortcut(QKeySequence("Ctrl+E"));
95  action_delete_exploration->setShortcut(QKeySequence("Ctrl+Shift+E"));
96  action_workspace_wizard->setShortcut(QKeySequence("Ctrl+W"));
97  action_task_overview->setShortcut(QKeySequence("Ctrl+T"));
98 
99  // Menu
100  QMenuBar* menu = menuBar();
101 
102  QMenu* menu_server = new QMenu("&Server", menu);
103  menu_server->addAction(action_connect);
104  menu_server->addSeparator();
105  menu_server->addAction(action_subscribe);
106  menu_server->addAction(action_task_overview);
107  menu->addMenu(menu_server);
108 
109  QMenu* menu_exploration = new QMenu("&Exploration", menu);
110  menu_exploration->addAction(action_start_exploration);
111  menu_exploration->addAction(action_delete_exploration);
112  menu_exploration->addAction(action_download_exploration);
113  menu->addMenu(menu_exploration);
114 
115  QMenu* menu_workspace = new QMenu("&Workspace", menu);
116  menu_workspace->addAction(action_workspace_wizard);
117  menu->addMenu(menu_workspace);
118 
119  // Toolbar
120  QToolBar* toolbar = new QToolBar(this);
121  toolbar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
122  toolbar->setMovable(false);
123  toolbar->addAction(action_connect);
124  toolbar->addAction(action_subscribe);
125  toolbar->addSeparator();
126  toolbar->addAction(action_start_exploration);
127  toolbar->addAction(action_delete_exploration);
128  toolbar->addAction(action_download_exploration);
129  toolbar->addSeparator();
130  toolbar->addAction(action_task_overview);
131  addToolBar(toolbar);
132 
133  connect(action_connect, SIGNAL(triggered()), this, SLOT(Connect()));
134  connect(action_subscribe, SIGNAL(triggered()), this, SLOT(Subscribe()));
135  connect(action_start_exploration, SIGNAL(triggered()), this, SLOT(StartExploration()));
136  connect(action_delete_exploration, SIGNAL(triggered()), this, SLOT(DeleteExploration()));
137  connect(action_download_exploration, SIGNAL(triggered()), this, SLOT(DownloadExploration()));
138 
139  connect(action_workspace_wizard, SIGNAL(triggered()), this, SLOT(SetWorkspace()));
140  connect(action_task_overview, SIGNAL(triggered()), this, SLOT(ShowTaskOverview()));
141 
142  // Status bar
143  m_statusbar = new QStatusBar(this);
144  m_statusbar->clearMessage();
145 
146  m_connection_button = new QPushButton("Not Connected");
147  m_connection_button->setFlat(true);
148  connect(m_connection_button, SIGNAL(clicked()), action_connect, SLOT(trigger()));
149  m_statusbar->addPermanentWidget(m_connection_button);
150  setStatusBar(m_statusbar);
151 
152  QWidget* central = new QWidget;
153  central->setLayout(layout);
154  setCentralWidget(central);
155 
156  m_task_view = new TaskOverview();
157  connect(m_task_view, SIGNAL(StopTask(int)), this, SLOT(StopTask(int)));
158  connect(m_task_view, SIGNAL(StartTask(int)), this, SLOT(RestartTask(int)));
159 
160  // Set Workspace
161  if (m_settings.contains("workspace"))
162  m_workspace_path = m_settings.value("workspace").toString().toStdString();
163 
164  InitWorkspace();
165 }
166 
168 {
169 
170 }
171 
172 void Client::InitWorkspace()
173 {
174  if (m_workspace_path == "" || !QDir(QString(m_workspace_path.c_str())).exists()) {
175  auto f = std::make_shared<SimPT_Shell::Ws::WorkspaceFactory>();
177  if (wizard.exec() == QDialog::Accepted)
178  m_workspace_path = wizard.GetWorkspaceDir();
179  else
180  return;
181  }
182 }
183 
184 void Client::Connect()
185 {
186  ServerDialog* dialog = new ServerDialog(m_workspace_path);
187  if (dialog->exec() == QDialog::Accepted) {
188  auto server = dialog->GetServer();
189  m_client = new ClientProtocol(server, this);
190  if (!m_client->IsConnected()) {
191  QMessageBox::critical(this, "Connection Error", "Could not connect to server.",
192  QMessageBox::Abort);
193  delete m_client;
194  m_client = nullptr;
195  } else {
196  connect(m_client, SIGNAL(Ended()), this, SLOT(Disconnected()));
197  connect(m_client, SIGNAL(ExplorationStatus(const ExplorationProgress*)),
198  this, SLOT(UpdateStatus(const ExplorationProgress*)));
199  connect(m_client, SIGNAL(ExplorationDeleted()), this, SLOT(ExplorationDeleted()));
200  Connected(server->GetName().toStdString());
201  }
202  }
203 }
204 
205 void Client::Disconnect()
206 {
207  assert(m_client != nullptr);
208 
209  if (QMessageBox::question(this, "Disconnect", "Are you sure you want to disconnect from the server?",
210  QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::Yes) {
211  Disconnected();
212  }
213 }
214 
215 void Client::Subscribe()
216 {
217  assert(m_client != nullptr);
218 
219  ExplorationSelection select_exploration(true);
220  connect(m_client, SIGNAL(ExplorationNames(std::vector<std::string>)),
221  &select_exploration, SLOT(UpdateExplorations(std::vector<std::string>)));
222 
223  m_subscribed_exploration = "";
224  if (!m_client->RequestExplorationNames()) {
225  QMessageBox::critical(this, "Connection Error", "Not connected to server.",
226  QMessageBox::Abort);
227  return;
228  }
229 
230  if (select_exploration.exec() == QDialog::Accepted) {
231  if (select_exploration.Selected()) {
232  m_subscribed_exploration = select_exploration.GetSelection().at(0);
233  if (!m_client->SubscribeUpdates(select_exploration.GetSelection().at(0)))
234  QMessageBox::critical(this, "Connection Error", "Not connected to server.",
235  QMessageBox::Abort);
236  }
237  }
238 
239  disconnect(m_client, SIGNAL(ExplorationNames(std::vector<std::string>)),
240  &select_exploration, SLOT(UpdateExplorations(std::vector<std::string>)));
241  }
242 
243 void Client::StartExploration()
244 {
245  assert(m_client != nullptr);
246 
247  // First check if client is connected
248  if (!m_client->IsConnected()) {
249  QMessageBox::critical(this, "Connection Error", "Not connected to server.",
250  QMessageBox::Abort);
251  return;
252  }
253 
254  std::shared_ptr<const ParameterExploration> exploration
255  = std::dynamic_pointer_cast<const ParameterExploration>(m_last_exploration);
256  ExplorationWizard wizard(Ws::CliWorkspace(m_workspace_path).GetPreferences(), exploration, this);
257  if (wizard.exec() == QDialog::Accepted) {
258  /* Send to server */
259  m_last_exploration = wizard.GetExploration();
260  if (!m_client->SendExploration(m_last_exploration.get())) {
261  QMessageBox::critical(this, "Connection Error",
262  "Not connected to server. Exploration will be saved.", QMessageBox::Abort);
263  } else {
264  QMessageBox::information(this, "Exploration sent",
265  "Exploration successfully sent.", QMessageBox::Ok);
266  }
267  }
268 }
269 
270 void Client::DeleteExploration()
271 {
272  assert(m_client != nullptr);
273 
274  ExplorationSelection select_exploration;
275  connect(m_client, SIGNAL(ExplorationNames(std::vector<std::string>)),
276  &select_exploration, SLOT(UpdateExplorations(std::vector<std::string>)));
277 
278  if (!m_client->RequestExplorationNames()) {
279  QMessageBox::critical(this, "Connection Error", "Not connected to server.",
280  QMessageBox::Abort);
281  return;
282  }
283 
284  if (select_exploration.exec() == QDialog::Accepted) {
285  if (select_exploration.Selected()) {
286  if (QMessageBox::question(this, "Delete exploration",
287  "Are you sure you want to delete the exploration(s) from the server?",
288  QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::Yes) {
289  for (auto exploration : select_exploration.GetSelection()) {
290  if (!m_client->DeleteExploration(exploration)) {
291  QMessageBox::critical(this, "Connection Error", "Not connected to server.",
292  QMessageBox::Abort);
293  return;
294  }
295  }
296  }
297  }
298  }
299 
300  disconnect(m_client, SIGNAL(ExplorationNames(std::vector<std::string>)),
301  &select_exploration, SLOT(UpdateExplorations(std::vector<std::string>)));
302 }
303 
304 void Client::DownloadExploration()
305 {
306  assert(m_client != nullptr);
307 
308  ExplorationSelection select_exploration;
309  connect(m_client, SIGNAL(ExplorationNames(std::vector<std::string>)),
310  &select_exploration, SLOT(UpdateExplorations(std::vector<std::string>)));
311 
312  if (!m_client->RequestExplorationNames()) {
313  QMessageBox::critical(this, "Connection Error", "Not connected to server.",
314  QMessageBox::Abort);
315  return;
316  }
317 
318  if (select_exploration.exec() == QDialog::Accepted) {
319  if (select_exploration.Selected()) {
320  /* if (QMessageBox::question(this, "Delete exploration", "Are you sure you want to delete the exploration(s) from the server?",
321  QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::Yes) {
322  for (auto exploration : select_exploration.GetSelection()) {
323  if (!m_client->DeleteExploration(exploration)) {
324  QMessageBox::critical(this, "Connection Error", "Not connected to server.",
325  QMessageBox::Abort);
326  return;
327  }
328  }
329  }*/
330  }
331  }
332 
333  disconnect(m_client, SIGNAL(ExplorationNames(std::vector<std::string>)),
334  &select_exploration, SLOT(UpdateExplorations(std::vector<std::string>)));
335 }
336 
337 void Client::StopTask(int task)
338 {
339  assert(m_client != nullptr);
340 
341  if (!m_client->StopTask(m_subscribed_exploration, task))
342  QMessageBox::critical(this, "Connection Error", "Not connected to server.",
343  QMessageBox::Abort);
344 }
345 
346 void Client::RestartTask(int task)
347 {
348  assert(m_client != nullptr);
349 
350  if (!m_client->RestartTask(m_subscribed_exploration, task))
351  QMessageBox::critical(this, "Connection Error", "Not connected to server.",
352  QMessageBox::Abort);}
353 
354 void Client::ShowTaskOverview()
355 {
356  m_task_view->show();
357 }
358 
359 void Client::SetWorkspace()
360 {
361  m_workspace_path = "";
362  InitWorkspace();
363 }
364 
365 void Client::Connected(std::string name)
366 {
367  m_connection_button->setText("Connected with: " + QString(name.c_str()));
368 
369  if (m_subscribed_exploration != "") {
370  connect(m_client, SIGNAL(ExplorationNames(std::vector<std::string>)),
371  this, SLOT(ConnectExplorationNames(std::vector<std::string>)));
372  m_client->RequestExplorationNames();
373  }
374 
375  action_connect->setText("&Disconnect...");
376  disconnect(action_connect, SIGNAL(triggered()), this, SLOT(Connect()));
377  connect(action_connect, SIGNAL(triggered()), this, SLOT(Disconnect()));
378  action_subscribe->setDisabled(false);
379  action_start_exploration->setDisabled(false);
380  action_delete_exploration->setDisabled(false);
381  action_download_exploration->setDisabled(false);
382 
383  m_status->Connected();
384 }
385 
386 void Client::ConnectExplorationNames(const std::vector<std::string> &names)
387 {
388  assert(m_client != nullptr);
389 
390  for (auto name : names) {
391  if (name == m_subscribed_exploration) {
392  m_client->SubscribeUpdates(name);
393  return;
394  }
395  }
396  // If not found: clear status
397  UpdateStatus(nullptr);
398 }
399 
400 void Client::Disconnected()
401 {
402  delete m_client;
403  m_client = nullptr;
404 
405  m_connection_button->setText("Not Connected");
406  if (m_task_view->isVisible()) {
407  m_task_view->close();
408  }
409 
410  action_connect->setText("&Connect...");
411  disconnect(action_connect, SIGNAL(triggered()), this, SLOT(Disconnect()));
412  connect(action_connect, SIGNAL(triggered()), this, SLOT(Connect()));
413  action_subscribe->setDisabled(true);
414  action_start_exploration->setDisabled(true);
415  action_delete_exploration->setDisabled(true);
416  action_download_exploration->setDisabled(true);
417  action_task_overview->setDisabled(true);
418 
419  m_status->Disconnected();
420 }
421 
422 void Client::UpdateStatus(const ExplorationProgress *status)
423 {
424  std::shared_ptr<const ExplorationProgress> progress(status);
425  m_subscribed_exploration = progress->GetExploration().GetName();
426  m_status->UpdateStatus(progress);
427  m_task_view->UpdateExploration(progress);
428  action_task_overview->setDisabled(false);
429 }
430 
431 void Client::ExplorationDeleted()
432 {
433  assert(m_client != nullptr);
434 
435  if (m_subscribed_exploration != "") {
436  m_client->UnsubscribeUpdates(m_subscribed_exploration);
437  }
438  m_subscribed_exploration = "";
439  m_status->UpdateStatus(nullptr);
440  m_task_view->UpdateExploration(nullptr);
441  action_task_overview->setDisabled(true);
442 }
443 
444 } // namespace
Interface for WorkspaceWizard.
Client()
Constructor.
Definition: Client.cpp:58
virtual ~Client()
Destructor.
Definition: Client.cpp:167
Interface for Client.
Interface for ServerInfo.
see the online Qt documentation
bool RequestExplorationNames()
Request a list of current Explorations.
Interface for TaskOverview.
Interface for Protocol.
Interface for ExplorationWizard.
SimPT-specific implementation of workspace factory.
Namespace for SimPT shell package.
Definition: Client.cpp:50
Interface for Status.
Interface for ExplorationSelection.
bool RestartTask(const std::string &name, int task)
Request to restart a task.
bool SubscribeUpdates(const std::string &explorationName)
Subscribe for regular updates.
see the online Qt documentation
A wizard that assists the user either specifying an existing workspace, or creating a new workspace...
void UpdateStatus(const std::shared_ptr< const ExplorationProgress > &progress)
Update the status of an exploration.
Definition: Status.cpp:54
bool SendExploration(const Exploration *exploration)
Send exploration.
Interface for ClientProtocol.
void UpdateExploration(const std::shared_ptr< const ExplorationProgress > &explorationProgress)
Update the current exploration.
Overview of tasks.
Definition: TaskOverview.h:37
Interface for workspace.
bool DeleteExploration(const std::string &name)
Request a stop and delete of the given exploration.
Cli Workspace for the command-line simulator.
Definition: CliWorkspace.h:30
see the online Qt documentation
Namespace for SimPT parameter explorer package.
Definition: Client.cpp:52
Interface for ServerDialog.
bool UnsubscribeUpdates(const std::string &explorationName)
Unsubscribe for regular updates.
bool IsConnected()
Check if still connected.
Definition: Protocol.cpp:73
bool StopTask(const std::string &name, int task)
Request to stop a task.
Widget to display status of subscribed exploration.
Definition: Status.h:34
void Disconnected()
Set font to disconnected state.
Definition: Status.cpp:96
Interface for ParameterExploration.
Interface for ExplorationProgress.
void Connected()
Set font to connected state.
Definition: Status.cpp:89