1 // -*- C++ -*-
2 
3 /*
4  * GChemPaint library
5  * application.h
6  *
7  * Copyright (C) 2004-2012 Jean Bréfort <jean.brefort@normalesup.org>
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License as
11  * published by the Free Software Foundation; either version 3 of the
12  * License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
22  * USA
23  */
24 
25 #ifndef GCHEMPAINT_APPLICATION_H
26 #define GCHEMPAINT_APPLICATION_H
27 
28 #include <gcugtk/application.h>
29 #include <gcu/macros.h>
30 #include <libxml/parser.h>
31 #include <set>
32 #include <string>
33 #include <map>
34 #include <stdexcept>
35 
36 namespace gccv {
37 	class Canvas;
38 }
39 
40 namespace gcu {
41 	class Dialog;
42 	class Object;
43 }
44 
45 /*!\file*/
46 /*!\namespace gcp
47 \brief GChemPaint specific C++ classes
48 
49 The namespace used for the C++ classes used by GChemPaint.
50 */
51 
52 namespace gcp {
53 
54 /*!\struct ToolDesc
55 Structure to use as button descriptors for tools.
56 See gcp::Application::AddTools() for information about its use.
57 */
58 typedef struct
59 {
60 /*!
61 The tool name.
62 */
63 	char const *name;
64 /*!
65 The tool tip.
66 */
67 	char const *tip;
68 /*!
69 The tool bar number
70 */
71 	unsigned bar;
72 /*!
73 The tool group inside the toolbar. This field helps merging toolbars with tools
74 from different plugins.
75 */
76 	unsigned group;
77 /*!
78 The name of the icon to add to the button.
79 */
80 	char const *icon_name;
81 /*!
82 The widget to add to the tool button, if NULL the icon with %icon_name will
83 be used. If both are NULL, the tool button will not be added.
84 */
85 	GtkWidget *widget;
86 } ToolDesc;
87 
88 // standard toolbars
89 enum {
90 	SelectionToolbar,
91 	AtomToolbar,
92 	BondToolbar,
93 	RingToolbar,
94 	ArrowToolbar,
95 	MaxToolbar
96 };
97 
98 class Target;
99 class NewFileDlg;
100 class Tool;
101 class Document;
102 typedef void (*BuildMenuCb) (gcu::UIManager *UIManager);
103 
104 /*!
105 @brief Cursors.
106 
107 Enumerates known cursors.
108 */
109 typedef enum {
110 /*!Cursor used when a click would have no effect.*/
111 	CursorUnallowed,
112 /*!Cursor used when a click would start drawing operation.*/
113 	CursorPencil,
114 /*!Maximum value, does not correspond to a valid cursor.*/
115 	CursorMax
116 } CursorId;
117 
118 /*!\class Application gcp/application.h
119 \brief GChemPaint application base class.
120 
121 This class is used to represent a GChemPaint application.
122 It is a virtual class since at least one method is pure virtual (gcp::Application::GetWindow)
123 */
124 class Application: public gcugtk::Application
125 {
126 friend class ApplicationPrivate;
127 public:
128 /*!
129 The default constructor.
130 */
131 	Application (gcugtk::CmdContextGtk *cc = NULL);
132 /*!
133 The destructor.
134 */
135 	virtual ~Application ();
136 
137 /*!
138 @param toolname the name of the tool.
139 @param activate whether to activate or deactivate.
140 
141 Activates or deactivates a tool in the GChempaint tool box.
142 
143 To activate the selection tool:
144 \code
145 		 ActivateTool ("Select", true);
146 \endcode
147 */
148 	void ActivateTool (const std::string& toolname, bool activate);
149 
150 /*!
151 @param path the path to activate.
152 @param activate whether to activate or deactivate.
153 
154 Activates or deactivates the menu item corresponding to \a path according
155 to the value of \a activate.
156 
157 To deactivate the "Paste" menu item, use:
158 \code
159 		 ActivateWindowsActionWidget ("/MainMenu/EditMenu/Paste", false);
160 \endcode
161 
162 Calls gcp::Window::ActivateActionWidget.
163 */
164 	void ActivateWindowsActionWidget (const char *path, bool activate);
165 /*!
166 Clears the message in the status bar.
167 */
168 	virtual void ClearStatus ();
169 /*!
170 @param text a text to display
171 
172 Displays \a text in the status bar.
173 */
174 	virtual void SetStatusText (const char* text);
175 /*!
176 This pure virtual method must be overloaded by derived classes.
177 @return the current active top level window if any, or NULL.
178 */
179 	virtual GtkWindow* GetWindow () = 0;
180 /*!
181 @return the active tool.
182 */
GetActiveTool()183 	Tool* GetActiveTool () {return m_pActiveTool;}
184 /*!
185 @return the active document.
186 */
GetActiveDocument()187 	gcp::Document* GetActiveDocument () {return m_pActiveDoc;}
188 /*!
189 @param pDoc the document becoming active.
190 
191 Sets the new active document.
192 */
SetActiveDocument(gcp::Document * pDoc)193 	void SetActiveDocument (gcp::Document* pDoc) {m_pActiveDoc = pDoc;}
194 /*!
195 @param name the name of a tool
196 @return the Tool corresponding to \a name.
197 */
GetTool(const std::string & name)198 	Tool* GetTool (const std::string& name) {return m_Tools[name];}
199 /*!
200 @param toolname the name of a new tool.
201 @param tool the new Tool.
202 
203 Adds a new tool to the tools box. This method is called from the Tool
204 constructor.
205 */
SetTool(const std::string & toolname,Tool * tool)206 	void SetTool (const std::string& toolname, Tool* tool) {m_Tools[toolname] = tool;}
207 /*!
208 @param name the name of a tool
209 @return the GtkWidget corresponding to the Tool named \a name.
210 */
GetToolItem(const std::string & name)211 	GtkWidget* GetToolItem(const std::string& name) {return ToolItems[name];}
212 /*!
213 @param name the name of a new tool.
214 @param w a GtkWidget.
215 
216 Associates \a w to the Tool named \a name. SetTool() will return this widget
217 when its argument is \a name.
218 */
SetToolItem(const std::string & name,GtkWidget * w)219 	void SetToolItem (const std::string& name, GtkWidget* w) {ToolItems[name] = w;}
220 /*!
221 @param Z the new current atomic number.
222 
223 Sets the new current atomic number. This number is used for new atoms.
224 */
SetCurZ(int Z)225 	void SetCurZ (int Z) {m_CurZ = Z;}
226 /*!
227 @return the current atomic number.
228 */
GetCurZ()229 	int GetCurZ () {return m_CurZ;}
230 /*!
231 Open the file save as dialog to save the current document with a new name.
232 */
233 	void OnSaveAs ();
234 /*!
235 @param filename the URI of the file to save or open.
236 @param mime_type the mime type.
237 @param bSave true when saving and false when opening.
238 @param window a parent GtkWindow which is used for messabe boxes if any.
239 @param pDoc a document (might be NULL when loading.
240 
241 Callback called when the user clicks on the Save or Open button in the file
242 chooser to process the file.
243 @return false on success, true otherwise.
244 */
245 	bool FileProcess (const gchar* filename, const gchar* mime_type, bool bSave, GtkWindow *window, gcu::Document *pDoc = NULL);
246 /*!
247 @param filename the URI of the file to save.
248 @param pDoc the document to save.
249 
250 Saves the active document in the native GChemPaint format.
251 */
252 	void SaveGcp (std::string const &filename, gcp::Document* pDoc);
253 /*!
254 @param filename the URI of the file to load.
255 @param pDoc a document or NULL.
256 
257 Loads a GChemPaint document.
258 */
259 	void OpenGcp (std::string const &filename, gcp::Document* pDoc);
260 /*!
261 @return a xmlDocPtr used for some undo/redo related operations. The text
262 tools use it.
263 */
GetXmlDoc()264 	xmlDocPtr GetXmlDoc () {return XmlDoc;}
265 /*!
266 Saves the active view as an image.
267 */
268 	void OnSaveAsImage ();
269 /*!
270 @return true if InChIs can be evaluated for molecules.
271 */
HaveInChI()272 	bool HaveInChI () {return m_Have_InChI;}
273 /*!
274 @return the number of opened documents.
275 */
GetDocsNumber()276 	int GetDocsNumber () {return m_Docs.size ();}
277 /*!
278 @param zoom the new zoom level.
279 
280 Sets the zoom level for the active document window.
281 */
282 	void Zoom (double zoom);
283 /*!
284 @param tools an array with the new tools descriptions, last one having its name set to #NULL.
285 
286 Adds new tools, typically from a plugin.
287 */
288 	void AddTools (ToolDesc const *tools);
289 /*!
290 @param name the name of the toolbar.
291 @param index the rank of the toolbar in the toolbox.
292 
293 Adds a new toolbar to the tools box. See the documentation of
294 gcp::Application::AddActions() for a case use.
295 */
296 	void RegisterToolbar (char const *name, int index);
297 /*!
298 @param new_tool_name the activated tool name.
299 
300 Call by the framework when the active tool changed.
301 */
302 	void OnToolChanged (char const *new_tool_name);
303 /*!
304 @param target the Target to add.
305 
306 Adds a Target to the list of known Targets and displays the tools box next to
307 the Target.
308 */
309 	void AddTarget (Target *target);
310 /*!
311 @param target the Target to delete.
312 
313 Deletes a Target from the list of known Targets. The tools box will be hidden
314 if no Target remains active.
315 */
316 	void DeleteTarget (Target *target);
317 /*!
318 @param iconified whether the currently active Target is iconified or not.
319 
320 If \a iconified is true, the tools box will be hidden if no Target remains
321 active, otherwise it will be displayed next to the active Target.
322 */
323 	void NotifyIconification (bool iconified);
324 /*!
325 @param has_focus whether the Target has focus or not.
326 @param target the Target for which the event occured.
327 
328 Shows the tools box next to \a target if \a has_focus is true and if \a target
329 is not NULL.
330 */
331 	void NotifyFocus (bool has_focus, Target *target = NULL);
332 /*!
333 Closes all open documents and ends the application.
334 */
335 	void CloseAll ();
336 /*!
337 @return a list of supported mime types.
338 */
GetSupportedMimeTypes()339 	std::list<std::string> &GetSupportedMimeTypes () {return m_SupportedMimeTypes;}
340 /*!
341 @param node the GONode which changed.
342 @param name the name of the key.
343 
344 Called by the framework when the configuration entry has changed to update a
345 running application preferences if the system allows such callbacks.
346 */
347 	void OnConfigChanged (GOConfNode *node, gchar const *name);
348 /*!
349 @param mime_type a mime type.
350 @return the list of file name extensions corresponding to the mime type.
351 */
352 	std::list<std::string> &GetExtensions(std::string &mime_type);
353 
354 /*!
355 Called by the framework after a change of a theme name. Ensure evrything is
356 correctly updated.
357 */
358 	void OnThemeNamesChanged ();
359 
360 /*!
361 @param cb: the BuildMenuCb callback to call when building the menu.
362 
363 adds a callback for adding entries to the windows menus.
364 */
365 	void AddMenuCallback (BuildMenuCb cb);
366 
367 /*!
368 @param manager: the gcu::UIManager to populate.
369 
370 Populates the user interface by calling all callbacks registered
371 with AddMenuCallback.
372 */
373 	void BuildMenu (gcu::UIManager *manager);
374 
375 /*!
376 Creates a new document using the default theme.
377 @return the newly created document.
378 */
379 	gcu::Document *CreateNewDocument ();
380 
381 	// virtual menus actions:
382 /*!
383 @param Theme a gcp::Theme or NULL.
384 
385 Creates a new document using the given theme or the default theme if
386 \a Theme is NULL. This method must be overloaded by derived classes since
387 it is pure virtual.
388 */
389 	virtual void OnFileNew (char const *Theme = NULL) = 0;
390 
391 /*!
392 @param id a CursorId
393 
394 @return the corresponding GdkCursor if any.
395 */
GetCursor(CursorId id)396 	GdkCursor *GetCursor (CursorId id)  {return m_Cursors[id];}
397 
398 /*!
399 @return true if an appropriate 3D viewer is available.
400 */
Have3DSupport()401 	bool Have3DSupport () {return m_HaveGhemical | m_HaveGChem3D | m_HaveAvogadro;}
402 /*!
403 @param clipboard a clipboard.
404 @param selection_data the available data
405 
406 Used as callback as gtk_clipboard_request_contents().
407 */
408 	void ReceiveTargets (GtkClipboard *clipboard, GtkSelectionData *selection_data);
409 /*!
410 @return the list of the registered tools descriptions.
411 */
GetToolDescriptions()412 	std::list < ToolDesc const * > const &GetToolDescriptions () const {return m_ToolDescriptions;}
413 
414 protected:
415 /*!
416 Initialize the tools box so that the selection tool is active. This method is
417 called only once aafter startup by the framework.
418 */
419 	void InitTools();
420 /*!
421 Builds the tools box. This method is
422 called only once after startup by the framework.
423 */
424 	void BuildTools () throw (std::runtime_error);
425 /*!
426 @param visible whether the tools box should be visible or not
427 
428 Shows or hides the tools box.
429 */
430 	void ShowTools (bool visible);
431 
432 private:
433 	void TestSupportedType (char const *mime_type, char const* babel_type = NULL, bool writeable = false);
434 	void AddMimeType (std::list<std::string> &l, std::string const& mime_type);
435 	void UpdateAllTargets ();
436 
437 protected:
438 /*!
439 The active document.
440 */
441 	gcp::Document *m_pActiveDoc;
442 /*!
443 The active target.
444 */
445 	Target *m_pActiveTarget;
446 /*!
447 Used to add a number to new files default names.
448 */
449 	unsigned m_NumWindow; //used for new files (Untitled%d)
450 
451 private:
452 	int m_CurZ;
453 	std::map <std::string, GtkWidget*> ToolItems;
454 	std::map <std::string, GtkWidget*> Toolbars;
455 	std::map <std::string, Tool*> m_Tools;
456 	Tool* m_pActiveTool;
457 	static bool m_bInit;
458 	static bool m_Have_InChI;
459 	xmlDocPtr XmlDoc;
460 	GtkIconFactory *IconFactory;
461 	std::list<char const*> UiDescs;
462 	GtkRadioActionEntry* RadioActions;
463 	int m_entries;
464 	std::map<int, std::string> ToolbarNames;
465 	unsigned m_NumDoc; //used to build the name of the action associated with the menu
466 	std::set<Target*> m_Targets;
467 	int visible_windows;
468 	std::list<std::string> m_SupportedMimeTypes;
469 	std::list<std::string> m_WriteableMimeTypes;
470 	GOConfNode *m_ConfNode;
471 	guint m_NotificationId;
472 	gcu::Object *m_Dummy;
473 	std::list<BuildMenuCb> m_MenuCbs;
474 	GdkCursor *m_Cursors[CursorMax];
475 	std::list < ToolDesc const * > m_ToolDescriptions;
476 
477 /*!\fn GetHaveGhemical
478 @return true if ghemical is usable on startup.
479 */
480 	GCU_RO_STATIC_PROP (bool, HaveGhemical)
481 /*!\fn GetHaveGChem3D
482 @return true if gchem3d is usable on startup.
483 */
484 	GCU_RO_STATIC_PROP (bool, HaveGChem3D)
485 /*!\fn GetHaveAvogadro
486 @return true if avogadro is usable on startup.
487 */
488 	GCU_RO_STATIC_PROP (bool, HaveAvogadro)
489 /*!\fn GetUseAtomColors
490 @return true if atomic symbols are displayed using the element symbolic color.
491 */
492 	GCU_RO_PROP (bool, UseAtomColors)
493 };
494 
495 }	// namespace gcp
496 
497 #endif //GCHEMPAINT_APPLICATION_H
498