Tulip  5.2.0
Large graphs analysis and drawing
TulipProject.h
1 /*
2  *
3  * This file is part of Tulip (http://tulip.labri.fr)
4  *
5  * Authors: David Auber and the Tulip development Team
6  * from LaBRI, University of Bordeaux
7  *
8  * Tulip is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License
10  * as published by the Free Software Foundation, either version 3
11  * of the License, or (at your option) any later version.
12  *
13  * Tulip is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16  * See the GNU General Public License for more details.
17  *
18  */
19 
20 #ifndef TULIPPROJECT_H
21 #define TULIPPROJECT_H
22 
23 #include <QDir>
24 #include <QString>
25 #include <QStringList>
26 #include <QDate>
27 #include <QObject>
28 #include <QIODevice>
29 
30 #include <tulip/tulipconf.h>
31 
32 #include <fstream>
33 
34 namespace tlp {
35 
36 class PluginProgress;
37 
38 /**
39  @ingroup Plugins
40 
41  @brief The TulipProject object handles the content of a Tulip project.
42 
43  All tulip projects contain a set of defined static meta-information:
44  @list
45  @li name (QString): the name of the project
46  @li description (QString): Comments about the project
47  @li author (QString): the author of the project
48  @li perspective (QString): the name of the perspective plugin associated to the project
49  @li date (QDate): the date of project's last modification
50  @li version (QString): the version of the Tulip project format
51  @endlist
52 
53  Alongside this information, one can store any kind of file into a Tulip project. Since a project
54  is meant to be associated to a specific perspective, the responisbility of those file
55  is left to the perspective.
56 
57  A TulipProject DOES NOT automatically save to disk. One will have to call the write() method to
58  serialize data.
59  @warning Precise implementation of the TulipProject object should NOT be known or used by the user
60  since it could be subject to changes.
61 
62  If something wrong happens when calling a method from TulipProject, this method will return either
63  false or a invalid result (see specific method documentation). The last error message can be
64  retrieved with the lastError() method.
65 
66  After opening and before saving a project, user will be able to list/delete files and directories
67  available in the project and open them using std filestreams or Qt's QIODevice.
68  Files can be opened using the stdFileStram and fileStream methods. They will always be opened in
69  Read/Write mode.
70 
71  Files in a tulip project are identified by their path. Those path ar similar to the path of a
72  standard file system and use the "/" character as a separator.
73  The root directory is identified by "/".
74 
75  @warning TulipProject path ALWAYS use the "/" character as a directory separator. This is
76  OS-independant.
77 
78  @note A file called graph.tlp located at the top-level directory will be identified by the
79  "/graph.tlp" path while the file "graph.tlp" located in the "data" directory will be identified by
80  "/data/graph.tlp".
81  */
82 class TLP_QT_SCOPE TulipProject : public QObject {
83  Q_OBJECT
84 
85  TulipProject();
86  TulipProject(const QString &);
87 
88 public:
89  ~TulipProject() override;
90 
91  /**
92  @brief Starts a new TulipProject from scratch
93 
94  This method builds up a new TulipProject file without taking any input.
95  @see openProject()
96  */
97  static TulipProject *newProject();
98 
99  /**
100  @brief Opens a previously saved tulip project file and returns the corresponding project
101 
102  This method will unpack a tulip project file into some directory and allow the user to
103  manipulate the files.
104  @see TulipProject::save()
105  @param file The file to open.
106  @param progress A progress handler.
107  @return a pointer to a TulipProject object.
108  */
109  static TulipProject *openProject(const QString &file, tlp::PluginProgress *progress = nullptr);
110 
111  /**
112  @brief Opens a previously saved tulip project file
113 
114  This method unpacks a tulip project file into some directory and allow the user to manipulate
115  the files.
116  @see TulipProject::save()
117  @param file The file to open.
118  @param progress A progress handler.
119  @return true if the file has been successfully opened
120  */
121  bool openProjectFile(const QString &file, tlp::PluginProgress *progress = nullptr);
122 
123  /**
124  @brief Restores a project which has already been extracted into path
125 
126  @warning Using several TulipProject instances on the same directory may result in undefined
127  behavior. This method should only be used for crash handling purposes.
128  @param path The path where the archive was previously extracted
129  @return a pointer to a TulipProject object.
130  */
131  static TulipProject *restoreProject(const QString &path);
132 
133  /**
134  * @brief Removes all files in the project and unset project file if any
135  *
136  * @since Tulip 5.0
137  */
138  void clearProject();
139 
140  /**
141  * @brief Sets the file where to save the project
142  * @param projectFile absolute path to a .tlpx file
143  *
144  * @since Tulip 5.0
145  */
146  void setProjectFile(const QString &projectFile);
147 
148  /**
149  @brief Writes files in the TulipProject into a packed archive.
150 
151  This method packs every file in the project into a single archive.
152  @note This method DOES NOT close the project. It only commits changes to the specified file. A
153  TulipProject is only closed when destroyed.
154  @param file Absolute path where files should be packed.
155  @param progress A progress handler
156  @return False if method failed
157  */
158  bool write(const QString &file, tlp::PluginProgress *progress = nullptr);
159 
160  /**
161  @brief Lists entries in a directory
162 
163  @see QDir documentation for a complete description of filtering arguments
164  @param path The path to scan. @see TulipProject
165  @return The list of files and directories present in the given directory
166  */
167  QStringList entryList(const QString &path, QDir::Filters filters = QDir::NoFilter,
168  QDir::SortFlags sort = QDir::NoSort);
169 
170  /**
171  @brief Lists entries in a directory
172 
173  @see QDir documentation for a complete description of filtering arguments
174  @param path The path to scan. @see TulipProject
175  @return The list of files and directories present in the given directory
176  */
177  QStringList entryList(const QString &path, const QStringList &nameFilters,
178  QDir::Filters filters = QDir::NoFilter,
179  QDir::SortFlags sort = QDir::NoSort);
180 
181  /**
182  @brief Checks if the specified file/folder exists
183 
184  @param path The path to check.
185  @return true if the path exists.
186  */
187  bool exists(const QString &path);
188 
189  /**
190  @brief Recursively creates the specified path.
191 
192  Created folders will be empty
193  @return true if path was successfully created.
194  */
195  bool mkpath(const QString &path);
196 
197  /**
198  @brief Checks if the given path is a directory.
199 
200  @param path The path to check. @see TulipProject
201  @return true/false wether the path is a directory.
202  */
203  bool isDir(const QString &path);
204 
205  /**
206  @brief Removes a file from the project.
207 
208  If the given path points to a directory, or if the file does not exist, this method will fail
209  and return false
210  @param path The path to delete. @see TulipProject
211  */
212  bool removeFile(const QString &path);
213 
214  /**
215  @brief Removes a directory from the project.
216 
217  If the given file points to a file, or if the directory does not exist, or if the directory is
218  not empty, this method will fail and return false.
219  @see removeAllDir to remove a non-empty directory.
220  @param path The path to delete. @see TulipProject
221  */
222  bool removeDir(const QString &path);
223 
224  /**
225  @brief Removes a directory and all its content from the project.
226 
227  If the given file points to a file, or if the directory does not exist, this method will fail
228  and return false.
229  @warning This will remove every file stored in the specified directory.
230  @param path The path to delete. @see TulipProject
231  */
232  bool removeAllDir(const QString &path);
233 
234  /**
235  @brief Copies a file from the local filesystem into the project
236 
237  @param source The absolute path of the file to copy
238  @param destination The project path where to copy the file
239  @return false if copy failed
240  */
241  bool copy(const QString &source, const QString &destination);
242 
243  /**
244  @brief Creates an empty file
245 
246  This method is similar to the UNIX's touch shell command. Except it won't renew the file's
247  creation date if the file already exists.
248  @param file the file to create
249  @return true if file creation was sucessful.
250  */
251  bool touch(const QString &path);
252 
253  /**
254  @brief Gets a STL file stream (default to R/W access mode) to the given path.
255 
256  @warning This method does not check if the given path is a directory or a file. User might get
257  an invalid filestream.
258  @warning It is up to the user to delete the std::fstream returned.
259  @param path The path to open. @see TulipProject
260  @return an opened filestream on the given path.
261  */
262  std::fstream *stdFileStream(const QString &path, std::ios_base::openmode = std::fstream::in |
263  std::fstream::out |
264  std::fstream::app);
265 
266  /**
267  @brief Gets a Qt I/O device (default to R/W access mode) to the given path.
268 
269  @warning This method does not check if the given path is a directory or a file. User might get
270  an invalid filestream.
271  @warning User SHOULD NOT cast the QIODevice returned by this method into any of its subclass
272  since the implementation might change in future versions.
273  @warning It is up to the user to delete the QIODevice returned.
274  @param path The path to open. @see TulipProject
275  @param mode The opening mode as described in the Qt documentation.
276  @return an opened Qt device on the given path.
277  */
278  QIODevice *fileStream(const QString &path, QIODevice::OpenMode mode = QIODevice::ReadWrite);
279 
280  /**
281  @brief Returns the last error raised.
282 
283  @note The returned string is empty if no error was raised.
284  */
285  QString lastError() const {
286  return _lastError;
287  }
288 
289  /**
290  @brief Checks if the object is a valid TulipProject.
291 
292  @warning Calling methods on invalid TulipProject instances may result in undefined behavior.
293  */
294  bool isValid() const {
295  return _isValid;
296  }
297 
298  /**
299  @brief Returns the archive file associated with this project.
300 
301  If the project has been opened from an existing file or if the write method has already been
302  called, this method will return the last file path specified.
303  In other cases, this method will return an empty string.
304  */
305  QString projectFile() const {
306  return _projectFile;
307  }
308 
309  /**
310  @brief This method returns the real absolute path corresponding to / in the TulipProject.
311 
312  This can be used to create a TulipProject directly from a path.
313  @warning Using several TulipProject instances at the same time on the same path may result in
314  undefined behavior.
315  */
316  QString absoluteRootPath() const;
317 
318  // Developer note: Every field in the TulipProject tagged as a Q_PROPERTY will automaticaly be
319  // serialized in the project.xml file
320  /**
321  @brief the name of the project
322  */
323  Q_PROPERTY(QString name READ name WRITE setName)
324  /**
325  * @see name
326  */
327  QString name() const;
328 
329  /**
330  @brief User-written description of the project
331  */
332  Q_PROPERTY(QString description READ description WRITE setDescription)
333  /**
334  * @see description
335  */
336  QString description() const;
337 
338  /**
339  @brief Name of the author
340  */
341  Q_PROPERTY(QString author READ author WRITE setAuthor)
342  /**
343  * @see author
344  */
345  QString author() const;
346 
347  /**
348  @brief Name of the perspective associated to the project.
349 
350  When the user open a project from Tulip, this porperty is first read to identify find kind of
351  perspective plugin should be launched to
352  open the project
353 
354  @warning If the perspective name associated to the project is invalid or correspond to a missing
355  plugin, tulip may not be able to open the file.
356  */
357  Q_PROPERTY(QString perspective READ perspective WRITE setPerspective)
358  /**
359  * @see perspective
360  */
361  QString perspective() const;
362 
363  /**
364  @brief The version of the Tulip project format with which the file was created.
365  Project from older format version will be always saved into the newest version available.
366  */
367  QString version() const;
368 
369  /**
370  @brief Returns the absolute filesystem path used to store the file
371  @warning Be cautious though since directly modifying project files without using TulipProject
372  methods could result in undefined behavior.
373  */
374  QString toAbsolutePath(const QString &relativePath);
375 
376 signals:
377  void projectFileChanged(const QString &projectFile);
378 
379 public slots:
380  /**
381  * @see name
382  */
383  void setName(const QString &);
384  /**
385  * @see description
386  */
387  void setDescription(const QString &);
388  /**
389  * @see author
390  */
391  void setAuthor(const QString &);
392  /**
393  * @see perspective
394  */
395  void setPerspective(const QString &);
396 
397 private:
398  static QString temporaryPath();
399 
400  bool writeMetaInfo();
401  bool readMetaInfo();
402 
403  bool removeAllDirPrivate(const QString &path, bool removeRootDir = true);
404 
405  // Core fileset
406  QDir _rootDir;
407  QDir _dataDir;
408  QString _projectFile;
409 
410  // Meta information
411  QString _author;
412  QString _name;
413  QString _description;
414  QString _perspective;
415 
416  // Error handling
417  QString _lastError;
418  bool _isValid;
419 };
420 }
421 #endif // TULIPPROJECT_H
The TulipProject object handles the content of a Tulip project.
Definition: TulipProject.h:82
QString lastError() const
Returns the last error raised.
Definition: TulipProject.h:285
PluginProcess subclasses are meant to notify about the progress state of some process (typically a pl...
QString projectFile() const
Returns the archive file associated with this project.
Definition: TulipProject.h:305
bool isValid() const
Checks if the object is a valid TulipProject.
Definition: TulipProject.h:294