VPTissue Reference Manual
WorkspaceController.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 "WorkspaceController.h"
21 
22 #include "AppController.h"
23 
24 #include "common/PTreeQtState.h"
25 #include "gui/NewProjectDialog.h"
26 #include "gui/PTreeContainer.h"
28 #include "gui/PTreeMenu.h"
29 #include "gui/WorkspaceView.h"
31 #include "util/misc/Exception.h"
32 
33 #include <QAction>
34 #include <QMessageBox>
35 
36 using namespace std;
37 using namespace boost::property_tree;
38 using namespace SimPT_Sim::Util;
39 
40 namespace SimShell {
41 namespace Gui {
42 namespace Controller {
43 
44 WorkspaceController::WorkspaceController(shared_ptr<Ws::IWorkspaceFactory> f, AppController* m)
45  : QWidget(m),
46  HasUnsavedChangesPrompt("Workspace"),
47  m_factory(f),
48  m_main_controller(m),
49  m_project_controller(m)
50 {
51  qRegisterMetaType< std::string >();
52  InitActions();
53  InitWidgets();
54  InitBaseClasses();
55 }
56 
57 QAction* WorkspaceController::GetActionNewProject() const
58 {
59  return m_a_new_project;
60 }
61 
62 QAction* WorkspaceController::GetActionRefreshWorkspace() const
63 {
64  return m_a_refresh_workspace;
65 }
66 
67 QDockWidget* WorkspaceController::GetPreferencesDock() const
68 {
69  return m_container_preferences->GetDock();
70 }
71 
72 QMenu* WorkspaceController::GetPreferencesMenu() const
73 {
74  return m_container_preferences->GetMenu();
75 }
76 
77 ptree WorkspaceController::GetPTreeState() const
78 {
79  ptree state;
80  state.put_child("project_controller", m_project_controller.GetPTreeState());
81  state.put_child("view", m_view->GetPTreeState());
82  state.put_child("container_preferences", m_container_preferences->GetPTreeState());
83  return state;
84 }
85 
86 WorkspaceView* WorkspaceController::GetView() const
87 {
88  return m_view;
89 }
90 
91 void WorkspaceController::InitActions()
92 {
93  m_a_new_project = new QAction(QIcon::fromTheme("document-new"), "New Project...", this);
94  m_a_new_project->setShortcut(QKeySequence("Ctrl+N"));
95  m_a_new_project->setEnabled(false);
96  connect(m_a_new_project, SIGNAL(triggered()), this, SLOT(SLOT_NewProjectDialog()));
97 
98  m_a_refresh_workspace = new QAction(QIcon::fromTheme("view-refresh"), "Refresh Workspace", this);
99  m_a_refresh_workspace->setShortcut(QKeySequence("F5"));
100  m_a_refresh_workspace->setEnabled(false);
101  connect(m_a_refresh_workspace, SIGNAL(triggered()), this, SLOT(SLOT_RefreshWorkspace()));
102 
103  m_enabled_actions.Set({ m_a_new_project, m_a_refresh_workspace });
104 }
105 
106 void WorkspaceController::InitBaseClasses()
107 {
108  HasUnsavedChanges::SetChildren({
109  &m_project_controller,
110  m_container_preferences.get()
111  });
112 }
113 
114 void WorkspaceController::InitWidgets()
115 {
116  m_view = new WorkspaceView(this);
117 
118  m_container_preferences = make_shared<PTreeContainerPreferencesObserver>("Workspace Preferences");
119  m_container_preferences->SetOnlyEditData(true);
120  connect(m_container_preferences.get(), SIGNAL(Applied(const boost::property_tree::ptree&)),
121  this, SLOT(SLOT_ApplyPreferences(const boost::property_tree::ptree&)));
122 }
123 
124 void WorkspaceController::InternalForceClose()
125 {
126  m_enabled_actions.Disable();
127  m_view->setModel(nullptr);
128  m_model.reset();
129 }
130 
131 bool WorkspaceController::InternalIsClean() const
132 {
133  return true;
134 }
135 
136 void WorkspaceController::InternalPreForceClose()
137 {
138  m_model->Workspace()->SetUserData("main_controller", m_main_controller->GetPTreeState());
139 }
140 
141 bool WorkspaceController::InternalSave()
142 {
143  return true;
144 }
145 
146 bool WorkspaceController::IsOpened() const
147 {
148  return (bool) m_model;
149 }
150 
151 bool WorkspaceController::Open(const std::string& path)
152 {
153  if (!PromptClose())
154  return false;
155  try {
156  // Create workspace model.
157  auto workspace = m_factory->CreateWorkspace(path);
158  m_model = WorkspaceQtModel::Create(workspace, &m_project_controller);
159 
160  // Open preferences ptree in dock and menu.
161  m_container_preferences->Open(m_model->Workspace()->GetPreferences());
162 
163  auto handler = bind(&PTreeContainerPreferencesObserver::Update,
164  m_container_preferences.get(), std::placeholders::_1);
165  m_model->Workspace()->Subject<Ws::Event::PreferencesChanged,
166  std::weak_ptr<const void>>::Register(m_container_preferences, handler);
167 
168  // Open workspace in central view.
169  m_view->setModel(m_model.get());
170 
171  m_enabled_actions.Enable();
172 
173  m_main_controller->SetPTreeState(m_model->Workspace()->GetUserData("main_controller"));
174 
175  return true;
176  }
177  catch (Exception&) {
178  return false;
179  }
180 }
181 
182 ProjectController& WorkspaceController::Project()
183 {
184  return m_project_controller;
185 }
186 
187 const ProjectController& WorkspaceController::Project() const
188 {
189  return m_project_controller;
190 }
191 
192 void WorkspaceController::SetPTreeState(const ptree& state)
193 {
194  auto container_preferences_state = state.get_child_optional("container_preferences");
195  if (container_preferences_state) {
196  m_container_preferences->SetPTreeState(container_preferences_state.get());
197  }
198 
199  auto view_state = state.get_child_optional("view");
200  if (view_state) {
201  m_view->SetPTreeState(view_state.get());
202  }
203 
204  auto project_controller_state = state.get_child_optional("project_controller");
205  if (project_controller_state) {
206  m_project_controller.SetPTreeState(project_controller_state.get());
207  }
208 }
209 
210 WorkspaceController::operator bool() const
211 {
212  return IsOpened();
213 }
214 
215 void WorkspaceController::SLOT_ApplyPreferences(const ptree& p)
216 {
217  m_model->Workspace()->SetPreferences(p);
218 }
219 
220 void WorkspaceController::SLOT_NewProjectDialog()
221 {
222  NewProjectDialog dialog(m_factory);
223  if (dialog.exec() == QDialog::Accepted) {
224  auto project_name = dialog.GetProjectName();
225 
226  if (dialog.IsCopyProject()) {
227  auto src_project = dialog.GetSrcProject();
228 
229  try {
230  QDir dst_dir(QString::fromStdString(m_model->Workspace()->GetPath()));
231  dst_dir.mkdir(QString::fromStdString(project_name));
232 
233  // Copy all files from src_project to new project dir.
234  QDir src_dir(QString::fromStdString(src_project->second->GetPath()));
235  auto src_files = src_dir.entryList(QDir::Files | QDir::Hidden);
236  for (auto& src_file : src_files) {
237  QFile::copy(QString::fromStdString(src_project->second->GetPath()) + '/' + src_file,
238  QString::fromStdString(m_model->Workspace()->GetPath()) + '/' + QString::fromStdString(project_name) + '/' + src_file);
239  }
240 
241  // New project.
242  m_model->Workspace()->Add("project", project_name);
243  }
244  catch (Exception& e) {
245  QMessageBox::warning(this, "Error", QString("Could not create project: ") + e.what());
246  }
247  } else {
248  auto src_path = dialog.GetSrcPath();
249  auto src_file = QFileInfo(QString::fromStdString(src_path)).fileName().toStdString();
250 
251  try {
252  QDir dst_dir(QString::fromStdString(m_model->Workspace()->GetPath()));
253  dst_dir.mkdir(QString::fromStdString(project_name));
254 
255  // Copy selected file
256  QFile::copy(QString::fromStdString(src_path),
257  QString::fromStdString(m_model->Workspace()->GetPath()) + '/' + QString::fromStdString(project_name) + '/' + QString::fromStdString(src_file));
258 
259  // New project.
260  m_model->Workspace()->Add("project", project_name);
261  }
262  catch (Exception& e) {
263  QMessageBox::warning(this, "Error", QString("Could not create project: ") + e.what());
264  }
265  }
266  }
267 }
268 
269 void WorkspaceController::SLOT_RefreshWorkspace()
270 {
271  m_model->Workspace()->Refresh();
272 }
273 
274 Ws::IWorkspace* WorkspaceController::operator->()
275 {
276  return m_model->Workspace().get();
277 }
278 
279 const Ws::IWorkspace* WorkspaceController::operator->() const
280 {
281  return m_model->Workspace().get();
282 }
283 
284 shared_ptr<Ws::IWorkspace> WorkspaceController::operator*()
285 {
286  return m_model->Workspace();
287 }
288 
289 shared_ptr<const Ws::IWorkspace> WorkspaceController::operator*() const
290 {
291  return m_model->Workspace();
292 }
293 
294 } // namespace Controller
295 } // namespace Gui
296 } // namespace SimShell
Event used to inform some observer that preferences have changed.
STL namespace.
AppController header.
Namespace for miscellaneous utilities.
Definition: PTreeFile.cpp:44
virtual const char * what() const noexcept
Return error message.
Definition: Exception.h:38
Interface for PTreeQtState.
Interface for NewProjectDialog.
Interface for PTreeContainerPreferencesObserver.
Dialog that asks user about information for setting up a new project.
Interface for WorkspaceQtModel.
Extremely simple Exception root class.
Definition: Exception.h:28
see the online Qt documentation
Interface for PTreeMenu.
see the online Qt documentation
Interface for WorkspaceView.
see the online Qt documentation
TreeView widget that uses WorkspaceQtModel as a model.
Definition: WorkspaceView.h:39
Header file for Exception class.
Namespace for generic graphical shell for simulators.
Definition: SimSession.h:32
WorkspaceController header.
Interface for PTreeContainer.