BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
projectmanagerdecorator.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // qt-mvvm: Model-view-view-model framework for large GUI applications
4 //
5 //! @file mvvm/model/mvvm/project/projectmanagerdecorator.cpp
6 //! @brief Implements class CLASS?
7 //!
8 //! @homepage http://www.bornagainproject.org
9 //! @license GNU General Public License v3 or higher (see COPYING)
10 //! @copyright Forschungszentrum Jülich GmbH 2020
11 //! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS)
12 //
13 // ************************************************************************************************
14 
19 #include <stdexcept>
20 
21 using namespace ModelView;
22 
23 namespace {
24 const bool succeeded = true;
25 const bool failed = false;
26 } // namespace
27 
31  std::unique_ptr<ProjectManager> project_manager;
32 
34  : m_project_context(std::move(project_context)), m_user_context(std::move(user_context))
35  {
36  project_manager = std::make_unique<ProjectManager>(m_project_context);
37  }
38 
39  //! Returns true if the project has directory already defined.
40  bool projectHasDir() const { return !project_manager->currentProjectDir().empty(); }
41 
42  //! Saves project in project directory. If directory is not defined, will acquire
43  //! directory susing callback provided.
45  {
46  // Feature FIXME?: already saved project (i.e. isModified=false) will be saved again.
47  // Files will be same, but creation date will be changed.
48 
49  auto save_dir =
50  projectHasDir() ? project_manager->currentProjectDir() : acquireNewProjectDir();
51  return saveCurrentProjectAs(save_dir);
52  }
53 
54  //! Saves current project under directory selected.
55  bool saveCurrentProjectAs(const std::string& dirname)
56  {
57  // empty dirname varible means 'cancel' during directory selection
58  return dirname.empty() ? failed : project_manager->saveProjectAs(dirname);
59  }
60 
61  std::string currentProjectDir() const { return project_manager->currentProjectDir(); }
62 
63  bool isModified() const { return project_manager->isModified(); }
64 
65  //! Performs saving of previous project before creating a new one.
67  {
68  if (isModified()) {
69  switch (acquireSaveChangesAnswer()) {
71  return saveCurrentProject();
73  return failed; // saving was interrupted by the 'cancel' button
75  project_manager->closeCurrentProject();
76  return succeeded;
77  default:
78  throw std::runtime_error("Error in ProjectManager: unexpected answer.");
79  }
80  }
81  return succeeded;
82  }
83 
84  //! Asks the user whether to save/cancel/discard the project using callback provided.
86  {
88  throw std::runtime_error("Error in ProjectManager: absent save_callback");
90  }
91 
92  //! Acquire the name of the new project directory using callback provided.
93  std::string acquireNewProjectDir()
94  {
96  throw std::runtime_error("Error in ProjectManager: absent creat_dir callback.");
98  }
99 
100  //! Acquire the name of the existing project directory using callback provided.
102  {
104  throw std::runtime_error("Error in ProjectManager: absent open_dir callback.");
106  }
107 };
108 
109 //! Constructor for ProjectManagerDecorator.
110 
112  const UserInteractionContext& user_context)
113  : p_impl(std::make_unique<ProjectManagerImpl>(project_context, user_context))
114 {
115 }
116 
118 
119 //! Creates a new project in the directory 'dirname', returns 'true' in the case of success.
120 //! The directory should exist.
121 //! If provided name is empty, will call directory selector dialog using callback provided.
122 //! If current project is in unsaved state, will perform 'save-before-closing' procedure before
123 //! proceeding further.
124 
125 bool ProjectManagerDecorator::createNewProject(const std::string& dirname)
126 {
127  if (!p_impl->saveBeforeClosing())
128  return failed;
129 
130  auto project_dir = dirname.empty() ? p_impl->acquireNewProjectDir() : dirname;
131  // empty project_dir string denotes 'cancel' during directory creation dialog
132  return project_dir.empty() ? failed : p_impl->project_manager->createNewProject(project_dir);
133 }
134 
135 //! Saves current project, returns 'true' in the case of success.
136 //! The project should have a project directory defined, if it is not the case, it will
137 //! launch the procedure of directory selection using callback provided.
138 
140 {
141  return p_impl->saveCurrentProject();
142 }
143 
144 //! Saves the project under a given directory, returns true in the case of success.
145 //! The directory should exist already. If provided 'dirname' variable is empty,
146 //! it will acquire a new project directory using dialog provided.
147 
148 bool ProjectManagerDecorator::saveProjectAs(const std::string& dirname)
149 {
150  auto project_dir = dirname.empty() ? p_impl->acquireNewProjectDir() : dirname;
151  // empty project_dir variable denotes 'cancel' during directory creation dialog
152  return project_dir.empty() ? failed : p_impl->saveCurrentProjectAs(project_dir);
153 }
154 
155 //! Opens existing project, returns 'true' in the case of success.
156 //! If provided name is empty, will call directory selector dialog using callback provided.
157 //! If current project is in unsaved state, it will perform 'save-before-closing' procedure before
158 //! proceeding further.
159 
160 bool ProjectManagerDecorator::openExistingProject(const std::string& dirname)
161 {
162  if (!p_impl->saveBeforeClosing())
163  return failed;
164  auto project_dir = dirname.empty() ? p_impl->acquireExistingProjectDir() : dirname;
165  // empty project_dir variable denotes 'cancel' during directory selection dialog
166  return project_dir.empty() ? failed : p_impl->project_manager->openExistingProject(project_dir);
167 }
168 
169 //! Returns current project directory.
170 
172 {
173  return p_impl->currentProjectDir();
174 }
175 
176 //! Returns true if project was modified since last save.
177 
179 {
180  return p_impl->isModified();
181 }
182 
183 //! Closes current project, returns 'true' if succeeded.
184 //! Will show the dialog, via callback provided, asking the user whether to save/discard/cancel.
185 //! Returns 'false' only if user has selected 'cancel' button.
186 
188 {
189  if (!p_impl->saveBeforeClosing())
190  return failed;
191  return succeeded;
192 }
ProjectManagerDecorator(const ProjectContext &project_context, const UserInteractionContext &user_context)
Constructor for ProjectManagerDecorator.
std::unique_ptr< ProjectManagerImpl > p_impl
bool closeCurrentProject() const override
Closes current project, returns 'true' if succeeded.
bool createNewProject(const std::string &dirname={}) override
Creates a new project in the directory 'dirname', returns 'true' in the case of success.
bool saveProjectAs(const std::string &dirname={}) override
Saves the project under a given directory, returns true in the case of success.
std::string currentProjectDir() const override
Returns current project directory.
bool saveCurrentProject() override
Saves current project, returns 'true' in the case of success.
bool isModified() const override
Returns true if project was modified since last save.
bool openExistingProject(const std::string &dirname={}) override
Opens existing project, returns 'true' in the case of success.
Defines class CLASS?
materialitems.h Collection of materials to populate MaterialModel.
SaveChangesAnswer
Possible user answers on question "Project was modified".
Definition: project_types.h:28
Definition: filesystem.h:81
Defines class CLASS?
Defines class CLASS?
Defines class CLASS?
Provides necessary information for Project construction.
Definition: project_types.h:32
Defines the context to interact with the user regarding save/save-as/create-new project scenarious.
Definition: project_types.h:48
select_dir_callback_t m_select_dir_callback
Definition: project_types.h:58
create_dir_callback_t m_create_dir_callback
Definition: project_types.h:59
answer_callback_t m_answer_callback
Definition: project_types.h:60
ProjectManagerImpl(ProjectContext project_context, UserInteractionContext user_context)
bool projectHasDir() const
Returns true if the project has directory already defined.
SaveChangesAnswer acquireSaveChangesAnswer() const
Asks the user whether to save/cancel/discard the project using callback provided.
std::string acquireNewProjectDir()
Acquire the name of the new project directory using callback provided.
std::string acquireExistingProjectDir()
Acquire the name of the existing project directory using callback provided.
bool saveCurrentProjectAs(const std::string &dirname)
Saves current project under directory selected.
bool saveCurrentProject()
Saves project in project directory.
bool saveBeforeClosing()
Performs saving of previous project before creating a new one.