Tulip  5.3.1
Large graphs analysis and drawing
Perspective.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 _PERSPECTIVE_H
21 #define _PERSPECTIVE_H
22 
23 #include <tulip/PluginContext.h>
24 #include <tulip/Plugin.h>
25 #include <tulip/TlpQtTools.h>
26 
27 #include <QString>
28 #include <QVariantMap>
29 #include <QSet>
30 #include <QMenu>
31 
32 class QMainWindow;
33 class QTcpSocket;
34 
35 namespace tlp {
36 
37 class PluginProgress;
38 class TulipProject;
39 
40 static const std::string PERSPECTIVE_CATEGORY = "Perspective";
41 
42 /**
43  * @ingroup Plugins
44  * @brief A context data structure for tlp::Perspective instances.
45  *
46  * @see tlp::Perspective
47  */
48 class TLP_QT_SCOPE PerspectiveContext : public tlp::PluginContext {
49 public:
50  PerspectiveContext() : mainWindow(nullptr), project(nullptr), tulipPort(0) {}
51  QMainWindow *mainWindow;
52  TulipProject *project;
53  QString externalFile;
54  QVariantMap parameters;
55  quint64 tulipPort;
56  unsigned int id;
57 };
58 
59 /**
60  * @ingroup Plugins
61  * @brief A Perspective is a Tulip plugin that completely re-defines the user interface.
62  *
63  * A Perspective aims at using the multiple features available in Tulip to create a complete,
64  * coherent workflow dedicated to a particular use-case.
65  * Perspectives are chosen by the user when first running the Tulip agent. The main perspective is
66  * called "Tulip". This perspective unveils all the Tulip features and aims at being a protyping and
67  * researching platform.
68  *
69  * A Perspective always acts in its own process and communicate with the Tulip agent via TCP
70  * sockets.
71  * Thus, it is the Perspective's responsibility to offer the possibility to display graphs, run
72  * plugins, etc. A lot of helper classes can be found into the tulip-gui API like pre-made widgets,
73  * Qt models, etc.
74  *
75  * Perspective's data is stored into a TulipProject. A TulipProject is an archive capable of
76  * containing heterogeneous data (like multiple graphs, textures, extra files, etc). When a
77  * TulipProject gets saved by a perspective, it is linked to it in its meta-information.
78  * Creating a Perspective primarily into implementing the start() method that builds the GUI. This
79  * method will be called by the overleying system when a new perspective is launched. The rest of
80  * the logic implementation is left to the developer.
81  */
82 class TLP_QT_SCOPE Perspective : public QObject, public tlp::Plugin {
83  Q_OBJECT
84 
85  static tlp::Perspective *_instance;
86  QSet<QString> _reservedProperties;
87  QTcpSocket *_agentSocket;
88  unsigned int _perspectiveId;
89  bool _maximised;
90  void sendAgentMessage(const QString &);
91  void notifyProjectLocation(const QString &path);
92 
93 protected:
94  /**
95  * @brief The project associated to this perspective. This project can be empty or contain data
96  * depending on how the Perspective was launched:
97  * To launch a perspective, the tulip_perspective executable is called with the following
98  * arguments:
99  * @code
100  * tulip_perspective [--perspective=Name] [file_path]
101  * @endcode
102  * @list
103  * @li The --perspective argument forces Tulip to start the "Name" perspective. Even if the
104  * project states otherwise. If this argument is not specified, Tulip will look in the project's
105  * meta-data to dertermine the perspective to launch.
106  * @li file_path is the absolute path of the project archive to associate with the perspective. If
107  * file_path is not given, the --perspective argument must be declared in order for Tulip to know
108  * what perspective to launch. In this case, _project will point to an empty (but valid!) project.
109  * @endlist
110  */
111  TulipProject *_project;
112 
113  /**
114  * @brief The main window on which the perspective should build the GUI.
115  *
116  * It is not the Perspective's responsibility to destroy the main window when the application gets
117  * closed. Generally speaking, destorying the _mainWindow pointer could lead to undefined
118  * behavior.
119  */
120  QMainWindow *_mainWindow;
121 
122  /**
123  * If the user provided a file to the tulip_perspective but this file is not recognized as a valid
124  * TulipProject, the full path of the file will be stored into the _externalFile member.
125  * @note Remember that perspectives should always store their data into TulipProject in order to
126  * keep a consistent workflow.
127  */
128  QString _externalFile;
129 
130  /**
131  * @brief Contains extra parameters that have not been parsed by the overleying system. Those are
132  * considered to be Perspective-specific and are forwarded into this variable.
133  */
134  QVariantMap _parameters;
135  bool checkSocketConnected();
136 
137 public:
138  enum ProgressOption {
139  NoProgressOption = 0x0,
140  IsPreviewable = 0x1,
141  IsCancellable = 0x2,
142  IsStoppable = 0x4
143  };
144  Q_DECLARE_FLAGS(ProgressOptions, ProgressOption)
145 
146  std::string category() const override {
147  return PERSPECTIVE_CATEGORY;
148  }
149  std::string icon() const override {
150  return ":/tulip/gui/icons/32/plugin_controller.png";
151  }
152 
153  /**
154  * @brief Called at the beginning of the tulip_perspective to set the Perspective singleton.
155  * @see instance()
156  */
157  static void setInstance(tlp::Perspective *);
158 
159  /**
160  * Since a Perspective has its own process to work in, there can be only one perspective instance
161  * by process.
162  * In order to ease the development process, Perspective are available as a singleton in order for
163  * child widgets and plugins to be able to access to the features of a Perspective.
164  * This architecture was added for developers who want to create an application containing several
165  * plugins grouped into Perspective.
166  * @return The perspective singleton
167  */
168  static tlp::Perspective *instance();
169 
170  /**
171  * @return A typed instance of the perspective singleton.
172  */
173  template <typename T>
174  static T *typedInstance() {
175  return dynamic_cast<T *>(instance());
176  }
177 
178  /**
179  * @brief Constructs a perspective object
180  * @warning There should not be any logic implemented into the Perspective's constructor. See the
181  * start method instead.
182  */
184  ~Perspective() override;
185 
186  /**
187  * @brief Build the main window GUI and starts the workflow.
188  * When this method is called, it means that the Perspective is reponsible of the application
189  * workflow until the application is closed by the user.
190  * @param progress A progress handler
191  */
192  virtual void start(tlp::PluginProgress *progress) = 0;
193 
194  /**
195  * @brief Creates a progress handler and returns it.
196  * This method allows lower-level widgets to create top-level progress bars directly from the
197  * Perspective.
198  * @return
199  */
200  virtual PluginProgress *
201  progress(ProgressOptions options = ProgressOptions(IsPreviewable | IsStoppable | IsCancellable));
202 
203  /**
204  * @return The Perspective's main window.
205  */
206  QMainWindow *mainWindow() const;
207 
208  /**
209  * @brief Checks if the name corresponds to a reserved properties.
210  * Perspectives are allowed to reserve graph properties. A reserved graph properties is a core
211  * property that cannot be deleted by the user and cannot be renamed.
212  * @return true if the perspective is registered.
213  */
214  bool isReservedPropertyName(QString name);
215 
216  /**
217  * @brief Sets a new property name as registered
218  */
219  void registerReservedProperty(QString);
220 
221  /**
222  * @brief Tells the perspective that the graph visualizations should be redrawn.
223  * @param center if true, visualization should also be centered (eg. the layout has been changed)
224  */
225  virtual void redrawPanels(bool center = false) = 0;
226 
227  /**
228  * @brief Tells the perspective that the visualizations for a given graph should be centered.
229  * @note By default, this method does nothing.
230  */
231  virtual void centerPanelsForGraph(tlp::Graph *);
232 
233  void resetTitle() {
234  emit resetWindowTitle();
235  }
236 
237  /**
238  * @brief a static function to ease the display of messages
239  * on mainWindow()->statusBar()
240  */
241  static void showStatusMessage(const QString &);
242 
243  /**
244  * @brief a static function to ease the display of messages
245  * on mainWindow()->statusBar()
246  */
247  static void showStatusMessage(const std::string &msg) {
248  showStatusMessage(tlp::tlpStringToQString(msg));
249  }
250 
251  /**
252  * @brief a static function to enable the redirection of the statusTip or toolTip of menu actions
253  * on mainWindow->statusBar()
254  */
255  static void redirectStatusTipOfMenu(QMenu *menu);
256 
257 public slots:
258  /**
259  * @brief Called when the user wants to close the application.
260  * @return Returning false prevents the window from being closed but the Perspective will have to
261  * implement its own way of closing the application.
262  */
263  virtual bool terminated() {
264  return true;
265  }
266 
267 signals:
268  void resetWindowTitle();
269 
270 protected slots:
271  /**
272  * @brief Send a message to the Tulip agent to make him display the Plugins Center page.
273  */
274  void showPluginsCenter();
275 
276  /**
277  * @brief Call this slot to swith to full screen or windowed mode
278  * @param f is true, switch to full screen mode. If false, switch to windowed mode
279  */
280  void showFullScreen(bool f);
281 
282  /**
283  * @brief Send a message to the Tulip agent to make him display the Projects page.
284  */
285  void showProjectsPage();
286 
287  /**
288  * @brief Send a message to the Tulip agent to make him display the "About us" page.
289  */
290  void showAboutPage();
291 
292  /**
293  * @brief Send a message to the Tulip agent to make him display a message in the system
294  * notification area.
295  * @param s The message to display.
296  */
297  void showTrayMessage(const QString &s);
298 
299  /**
300  * @brief Send a message to the Tulip agent to make him display an error message that will be
301  * shown in the system notification as well as on the welcome page.
302  * @param title The message's title.
303  * @param s The message to display.
304  */
305  void showErrorMessage(const QString &title, const QString &s);
306 
307  /**
308  * @brief Send a message to the Tulip agent to make him open a new Tulip Project.
309  * @param path the absolute path of the project file.
310  */
311  virtual void openProjectFile(const QString &path);
312 
313  /**
314  * @brief Send a message to the Tulip agent to make him open a new Perspective without a project.
315  * @param name The name of the PErspective to create.
316  */
317  void createPerspective(const QString &name);
318 
319  /**
320  * @brief Show the statusTip (or the toolTip) of an action on mainWindow()->statusBar()
321  * @param action a QAction
322  */
323  void showStatusTipOf(QAction *action);
324 
325 public:
326  /**
327  * @brief usage Displays a usage message when called from the tulip_perspective executable
328  */
329 #if TULIP_INT_MM_VERSION > 503
330 #error "The declaration of Perspective::usage() can now be moved"
331 #endif
332  // As this method has been added in Tulip 5.3.1,
333  // in order to maximize the binary compatibility with Tulip 5.3.0
334  // it must be added after all the preexisting virtual methods;
335  // and we must ensure that tulipRelease() != "5.3.0"
336  // before calling it (cf usage() in software/tulip_perspective/src/main.cpp)
337  virtual void usage(std::string &usage_str) const {
338  usage_str = "No options for this perspective.";
339  }
340 };
341 Q_DECLARE_OPERATORS_FOR_FLAGS(Perspective::ProgressOptions)
342 } // namespace tlp
343 
344 #endif //_PERSPECTIVE_H
QVariantMap _parameters
Contains extra parameters that have not been parsed by the overleying system. Those are considered to...
Definition: Perspective.h:134
virtual void usage(std::string &usage_str) const
usage Displays a usage message when called from the tulip_perspective executable
Definition: Perspective.h:337
QMainWindow * _mainWindow
The main window on which the perspective should build the GUI.
Definition: Perspective.h:120
Definition: TlpTools.h:48
QString _externalFile
Definition: Perspective.h:128
TulipProject * _project
The project associated to this perspective. This project can be empty or contain data depending on ho...
Definition: Perspective.h:111
virtual bool terminated()
Called when the user wants to close the application.
Definition: Perspective.h:263
Contains runtime parameters for a plugin.
Definition: PluginContext.h:42
static T * typedInstance()
Definition: Perspective.h:174
A context data structure for tlp::Perspective instances.
Definition: Perspective.h:48
Top-level interface for plug-ins.
Definition: Plugin.h:85
PluginProcess subclasses are meant to notify about the progress state of some process (typically a pl...
A Perspective is a Tulip plugin that completely re-defines the user interface.
Definition: Perspective.h:82
QString tlpStringToQString(const std::string &toConvert)
Convert a Tulip UTF-8 encoded std::string to a QString.
Definition: TlpQtTools.h:55
std::string icon() const override
The icon (preferably a thumbnail) of the plugin.
Definition: Perspective.h:149
static void showStatusMessage(const std::string &msg)
a static function to ease the display of messages on mainWindow()->statusBar()
Definition: Perspective.h:247