VPTissue Reference Manual
Project_def.h
Go to the documentation of this file.
1 #ifndef WS_PROJECT_DEF_H_INCLUDED
2 #define WS_PROJECT_DEF_H_INCLUDED
3 /*
4  * Copyright 2011-2016 Universiteit Antwerpen
5  *
6  * Licensed under the EUPL, Version 1.1 or as soon they will be approved by
7  * the European Commission - subsequent versions of the EUPL (the "Licence");
8  * You may not use this work except in compliance with the Licence.
9  * You may obtain a copy of the Licence at: http://ec.europa.eu/idabc/eupl5
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the Licence is distributed on an "AS IS" basis,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the Licence for the specific language governing
15  * permissions and limitations under the Licence.
16  */
22 #include "Project.h"
23 
24 #include "IFile.h"
25 #include "util/misc/Exception.h"
27 
28 #include <boost/property_tree/xml_parser.hpp>
29 #include <QDir>
30 #include <QFileSystemWatcher>
31 #include <sstream>
32 
33 namespace SimShell {
34 namespace Ws {
35 
36 using namespace std;
37 using namespace boost::property_tree;
38 using namespace boost::property_tree::xml_parser;
39 using namespace SimPT_Sim::Util;
40 
41 template <class FileType, const std::string& index_file>
43  const string& prefs_file, const shared_ptr<IWorkspace>& w)
44  : Preferences(path + '/' + prefs_file),
45  m_path(path),
46  m_workspace(w),
47  m_filesystem_watcher(path, bind(&Project<FileType, index_file>::Refresh, this))
48 {
49  // scan project directory for files
50  QDir qd(QString::fromStdString(m_path));
51 
52  QStringList qfilters;
53  QFileInfoList l = qd.entryInfoList(qfilters, QDir::Files);
54  for (auto it : l) {
55  string filename = it.fileName().toStdString();
56  auto file = FileType::Constructor(filename, m_path + '/' + filename);
57  if (file)
58  m_files[filename] = file;
59  }
60 
61  try {
62  ptree p;
63  read_xml(m_path + '/' + index_file, p, trim_whitespace);
64  m_user_data = p.get_child("project.user_data");
65  }
66  // Ignore exceptions
67  catch (xml_parser_error& e) {}
68  catch (ptree_bad_path &) {}
69 
70 }
71 
72 template <class FileType, const std::string& index_file>
74  : Preferences(move(other)),
75  m_path(move(other.m_path)),
76  m_files(move(other.m_files)),
77  m_filesystem_watcher(move(other.m_filesystem_watcher))
78 {
79 }
80 
81 template <class FileType, const std::string& index_file>
82 IProject::FileIterator Project<FileType, index_file>::Add(const string& name)
83 {
84  auto file = FileType::Constructor(name, m_path + '/' + name);
85  if (file) {
86  FileMap::value_type v(name, file);
87  auto result = m_files.insert(v).first;
89  {Event::ProjectChanged::LeafAdded, name});
90  return result;
91  } else {
92  return m_files.end();
93  }
94 }
95 
96 template <class FileType, const std::string& index_file>
98 {
99  return (--m_files.end())->second;
100 }
101 
102 template <class FileType, const std::string& index_file>
103 shared_ptr<const IFile> Project<FileType, index_file>::Back() const
104 {
105  return (--m_files.end())->second;
106 }
107 
108 template <class FileType, const std::string& index_file>
109 IProject::FileIterator
111 {
112  return m_files.begin();
113 }
114 
115 template <class FileType, const std::string& index_file>
116 IProject::ConstFileIterator
118 {
119  return m_files.begin();
120 }
121 
122 template <class FileType, const std::string& index_file>
123 void
125 {
126  if (m_session)
127  m_session->StopSimulation();
128  m_session.reset();
129  m_session_name.clear();
130 }
131 
132 template <class FileType, const std::string& index_file>
133 IProject::FileIterator
135 {
136  return m_files.end();
137 }
138 
139 template <class FileType, const std::string& index_file>
140 IProject::ConstFileIterator
142 {
143  return m_files.end();
144 }
145 
146 template <class FileType, const std::string& index_file>
147 IProject::FileIterator
149 {
150  return m_files.find(name);
151 }
152 
153 template <class FileType, const std::string& index_file>
154 IProject::ConstFileIterator
155 Project<FileType, index_file>::Find(const string& name) const
156 {
157  auto it = m_files.begin();
158  for (; it != m_files.end(); it++) {
159  if (it->first == name)
160  break;
161  }
162  return it;
163 }
164 
165 template <class FileType, const std::string& index_file>
167 {
168  return m_files.begin()->second;
169 }
170 
171 template <class FileType, const std::string& index_file>
172 shared_ptr<const IFile> Project<FileType, index_file>::Front() const
173 {
174  return m_files.begin()->second;
175 }
176 
177 template <class FileType, const std::string& index_file>
178 shared_ptr<IFile> Project<FileType, index_file>::Get(const string& name)
179 {
180  auto it = m_files.find(name);
181  if (it == m_files.end()) {
182  stringstream ss;
183  ss << "No file \"" << name << "\" in project \"" << m_path << "\"";
184  throw Exception(ss.str());
185  }
186  return it->second;
187 }
188 
189 template <class FileType, const std::string& index_file>
190 shared_ptr<const IFile> Project<FileType, index_file>::Get(const string& name) const
191 {
192  auto it = m_files.find(name);
193  if (it == m_files.end()) {
194  stringstream ss;
195  ss << "No file \"" << name << "\" in project \"" << m_path << "\"";
196  throw Exception(ss.str());
197  }
198  return it->second;
199 }
200 
201 template <class FileType, const std::string& index_file>
203 {
204  return index_file;
205 }
206 
207 template <class FileType, const std::string& index_file>
209 {
210  return m_path;
211 }
212 
213 template <class FileType, const std::string& index_file>
214 std::shared_ptr<Session::ISession> Project<FileType, index_file>::GetSession() const
215 {
216  if (!m_session)
217  throw Exception("Called GetSession() while project was not opened.");
218  return m_session;
219 }
220 
221 template <class FileType, const std::string& index_file>
223 {
224  return m_session_name;
225 }
226 
227 template <class FileType, const std::string& index_file>
228 const ptree& Project<FileType, index_file>::GetUserData(const string& user) const
229 {
230  auto result_optional = m_user_data.get_child_optional(user);
231  if (result_optional) {
232  return result_optional.get();
233  } else {
234  auto& result = m_user_data.put_child(user, ptree());
235  return result;
236  }
237 }
238 
239 template <class FileType, const std::string& index_file>
240 bool Project<FileType, index_file>::IsLeaf(const string& name) const
241 {
242  return m_files.find(name) != end();
243 }
244 
245 template <class FileType, const std::string& index_file>
247 {
248  return (bool) m_session;
249 }
250 
251 template <class FileType, const std::string& index_file>
253 {
254  return m_filesystem_watcher.IsActive();
255 }
256 
257 template <class FileType, const std::string& index_file>
259 {
260  Open(--end());
261 }
262 
263 template <class FileType, const std::string& index_file>
264 void Project<FileType, index_file>::Open(const std::string& name)
265 {
266  Open(Find(name));
267 }
268 
269 template <class FileType, const std::string& index_file>
271 {
272  assert(!IsOpened());
273  //auto prefs = GetMergedPreferences();
274  m_session = it->second->CreateSession(shared_ptr<IProject>(this, [](IProject*){}), m_workspace);
275  m_session_name = it->first;
276 }
277 
278 template <class FileType, const std::string& index_file>
280 {
281  // scan project directory for files
282  QDir qd(QString::fromStdString(m_path));
283  QStringList filters;
284  QFileInfoList l = qd.entryInfoList(filters, QDir::Files);
285 
286  // Remove old files.
287  vector<string> to_delete(m_files.size());
288  for (auto& file : m_files) {
289  bool found = false;
290  for (auto it : l) {
291  if (it.fileName().toStdString() == file.first) {
292  found = true;
293  break;
294  }
295  }
296  if (!found) {
297  to_delete.push_back(file.first);
298  }
299  }
300 
301  for (auto& filename : to_delete) {
302  m_files.erase(filename);
304  {Event::ProjectChanged::LeafRemoved, filename});
305  }
306 
307  // Add new files.
308  for (auto it : l) {
309  string filename = it.fileName().toStdString();
310 
311  if (m_files.find(filename) == m_files.end()) {
312  auto file = FileType::Constructor(filename, m_path + '/' + filename);
313  if (file) {
314  m_files[filename] = file;
316  {Event::ProjectChanged::LeafAdded, filename});
317  }
318  }
319  }
320 }
321 
322 template <class FileType, const std::string& index_file>
324 {
325  auto it = m_files.find(name);
326  if (it == m_files.end()) {
327  stringstream ss;
328  ss << "No file \"" << name << "\" in project \"" << m_path << "\"";
329  throw Exception(ss.str());
330  }
331  Remove(it);
332 }
333 
334 template <class FileType, const std::string& index_file>
335 void Project<FileType, index_file>::Remove(IProject::FileIterator it)
336 {
337  // Iterator will be invalidated after remove, store name.
338  string name = it->first;
339  QFile::remove(QString::fromStdString(it->second->GetPath()));
340  m_files.erase(it);
342  {Event::ProjectChanged::LeafRemoved, name});
343 }
344 
345 template <class FileType, const std::string& index_file>
347 {
348  if (!m_session) {
349  throw Exception("Called Session() while project was not opened.");
350  }
351  return *m_session.get();
352 }
353 
354 template <class FileType, const std::string& index_file>
356 {
357  m_filesystem_watcher.SetActive(a);
358 }
359 
360 template <class FileType, const std::string& index_file>
361 void Project<FileType, index_file>::SetUserData(const string& user, const ptree& p)
362 {
363  m_user_data.put_child(user, p);
364  Store();
365 }
366 
367 template <class FileType, const std::string& index_file>
369 {
370  ptree pt_project;
371  pt_project.put_child("project.user_data", m_user_data);
372  write_xml(m_path + '/' + index_file, pt_project, std::locale(), XmlWriterSettings::GetTab());
373 }
374 
375 } // namespace
376 } // namespace
377 
378 #endif // end_of_inclde_guard
Implementation of IPreferences.
Definition: Preferences.h:35
virtual FileIterator Add(const std::string &name)
Definition: Project_def.h:82
Interface for IFile.
STL namespace.
Interface for project-like behavior.
Definition: IProject.h:59
Namespace for miscellaneous utilities.
Definition: PTreeFile.cpp:44
virtual bool IsWatchingDirectory() const
Definition: Project_def.h:252
virtual Session::ISession & Session() const
Definition: Project_def.h:346
virtual void Remove(const std::string &name)
Definition: Project_def.h:323
virtual void SetWatchingDirectory(bool)
Definition: Project_def.h:355
virtual std::shared_ptr< IFile > Get(const std::string &name)
Definition: Project_def.h:178
Abstraction of project in workspace on file system.
boost::property_tree::ptree m_user_data
User data. Mutable because a GetUserData() with non-existing argument will create an empty user data ...
virtual std::string GetSessionFileName() const
Definition: Project_def.h:222
Extremely simple Exception root class.
Definition: Exception.h:28
virtual bool IsLeaf(const std::string &name) const
Definition: Project_def.h:240
Project(const std::string &path, const std::string &prefs_file, const std::shared_ptr< IWorkspace > &w)
Constructor.
virtual FileIterator begin()
Definition: Project_def.h:110
virtual bool IsOpened() const
Definition: Project_def.h:246
virtual std::shared_ptr< Session::ISession > GetSession() const
Definition: Project_def.h:214
virtual std::shared_ptr< IFile > Back()
Definition: Project_def.h:97
virtual FileIterator end()
Definition: Project_def.h:134
std::string m_path
Path of project directory.
virtual void SetUserData(const std::string &user, const boost::property_tree::ptree &)
Definition: Project_def.h:361
FileMap m_files
Mapping from file name to file objects.
Subject in Observer pattern.
Definition: Subject.h:34
virtual std::shared_ptr< IFile > Front()
Definition: Project_def.h:166
virtual const std::string & GetPath() const
Definition: Project_def.h:208
Header file for Exception class.
virtual void Close()
Definition: Project_def.h:124
Xml writer settings class.
virtual void Open()
Definition: Project_def.h:258
virtual const std::string & GetIndexFile() const
Definition: Project_def.h:202
Namespace for generic graphical shell for simulators.
Definition: SimSession.h:32
virtual void Refresh()
Definition: Project_def.h:279
virtual const boost::property_tree::ptree & GetUserData(const std::string &user) const
Definition: Project_def.h:228
Generic session interface.
Definition: ISession.h:53
virtual FileIterator Find(const std::string &name)
Definition: Project_def.h:148
Interface for Project.