1 /***************************************************************************
2  *   Copyright (C) 2005-2006 David Saxton <david@bluehaze.org>             *
3  *                                                                         *
4  *   This program is free software; you can redistribute it and/or modify  *
5  *   it under the terms of the GNU General Public License as published by  *
6  *   the Free Software Foundation; either version 2 of the License, or     *
7  *   (at your option) any later version.                                   *
8  ***************************************************************************/
9 
10 #ifndef VIEWCONTAINER_H
11 #define VIEWCONTAINER_H
12 
13 // #include <q3dragobject.h>
14 #include <QMap>
15 #include <QSplitter>
16 #include <QList>
17 #include <QPointer>
18 
19 class KConfigGroup;
20 class KTechlab;
21 class View;
22 class ViewArea;
23 class ViewContainer;
24 
25 class KConfig;
26 class QHBoxLayout;
27 class QLayout;
28 class QSplitter;
29 
30 typedef QMap< uint, ViewArea* > ViewAreaMap;
31 typedef QList<int> IntList;
32 
33 /**
34 Before a ViewAre has been given a view, this is shown.
35 \author David Saxton
36 */
37 class EmptyViewArea : public QWidget
38 {
39 	Q_OBJECT
40 	public:
41 		EmptyViewArea( ViewArea * parent );
42 		~EmptyViewArea() override;
43 
44 	protected slots:
45 		void openDocument();
46 
47 	protected:
48 		ViewArea * m_pViewArea;
49 };
50 
51 
52 /**
53 Contains either exactly one View, or two ViewAreas, separated by a QSplitter.
54 If it contains one view, then the value returned in id() is that of the view.
55 If it contains two ViewAreas, then the value returned by id() is -1.
56 @author David Saxton
57 */
58 class ViewArea : public QSplitter
59 {
60 Q_OBJECT
61 public:
62 	enum Position
63 	{
64 		Right,
65 		Bottom
66 	};
67 
68 	ViewArea( QWidget *parent, ViewContainer *viewContainer, int id, bool showOpenButton, const char * name = nullptr );
69 	~ViewArea() override;
70 
viewContainer()71 	ViewContainer *viewContainer() const { return p_viewContainer; }
id()72 	int id() const { return m_id; }
73 	/**
74 	 * Splits this ViewArea into two, and returns a pointer to the new ViewArea
75 	 * @param showOpenButton Whether to present the user with the EmptyViewArea
76 	 * widget (i.e. the new ViewArea is not destined to be immediately filled
77 	 * with a view).
78 	 */
79 	ViewArea *createViewArea( Position position, uint id, bool showOpenButton );
80 	/**
81 	 * Adds the given View to the main part of the layout
82 	 */
83 	void setView( View *view );
84 	/**
85 	 * Saves the state of this ViewArea and any contained ViewAreas
86 	 */
87 	void saveState( KConfigGroup *config );
88 	/**
89 	 * Restores the state of this ViewArea and any contained ViewAreas
90 	 * @param groupName e.g. "ViewContainer 1"
91 	 */
92 	void restoreState( KConfigGroup *config, int id, const QString &groupName );
93 	/**
94 	 * Returns true if this ViewArea can save useful information as to its state
95 	 * (i.e. it's children can save useful information about their state, or has
96 	 * a view with a url in it)
97 	 */
98 	bool canSaveUsefulStateInfo() const;
99 
100 	static QString fileKey( int id );
101 	static QString containsKey( int id );
102 	static QString orientationKey( int id );
103 
view()104 	View * view() const { return p_view; }
105 
106 protected slots:
107 	void viewAreaDestroyed( QObject *obj );
108 	void viewDestroyed();
109 
110 protected:
111 	int m_id;
112 	EmptyViewArea * m_pEmptyViewArea;
113 	QPointer<View> p_view;
114 	ViewArea *p_viewArea1;
115 	ViewArea *p_viewArea2;
116 	ViewContainer *p_viewContainer;
117 };
118 
119 /**
120 @author David Saxton
121 */
122 class ViewContainer : public QWidget
123 {
124 Q_OBJECT
125 public:
126 	/**
127 	 * Constructs a new ViewContainer, along with a default ViewArea ready for
128 	 * parenting a View, with an id of 0. parent is only used if ktechlab is
129 	 * null; otherwise the parent widget is ktechlab's tabWidget()
130 	 */
131 	ViewContainer( const QString & caption, QWidget * parent = nullptr );
132 	~ViewContainer() override;
133 
134 	/**
135 	 * Returns the view in the ViewArea with the given id
136 	 */
137 	View *view( uint id ) const;
138 	/**
139 	 * Returns the ViewArea with the given id
140 	 */
141 	ViewArea *viewArea( uint id ) const;
142 	/**
143 	 * The active view area is the one that is focused.
144 	 */
145 	void setActiveViewArea( uint id );
146 	/**
147 	 * Returns the id of the active ViewArea
148 	 */
activeViewArea()149 	uint activeViewArea() const { return m_activeViewArea; }
150 	/**
151 	 * Returns a pointer to the view of the active view area
152 	 */
activeView()153 	View *activeView() const { return view( activeViewArea() ); }
154 	/**
155 	 * Attempts to close the given viewarea, returning true if successful (i.e
156 	 * if the user did not object to the close request )
157 	 */
158 	bool closeViewArea( uint id );
159 	/**
160 	 * Creates a view area (parent QWidget, splitter et al) ready for inclusion
161 	 * of a view.
162 	 * @param relativeViewArea the viewarea to position the new viewarea next to, if -1 then is taken to be the active view area
163 	 * @param position Top, Right, Bottom or Left of given relativeViewArea
164 	 * @returns id of the view area, or -1 if unsucessful
165 	 * @param showOpenButton Whether to present the user with the EmptyViewArea
166 	 * widget (i.e. the new ViewArea is not destined to be immediately filled
167 	 * with a view).
168 	 */
169 	int createViewArea( int relativeViewArea, ViewArea::Position position, bool showOpenButton );
170 	/**
171 	 * Attempts to close each view area, returning false if any fail to be
172 	 * closed
173 	 */
174 	bool closeViewContainer();
175 	/**
176 	 * @returns number of views in this view container
177 	 */
viewCount()178 	uint viewCount() const { return m_viewAreaMap.size(); }
179 	/**
180 	 * Sets the pointer to the view area with the given id
181 	 */
182 	void setViewAreaId( ViewArea *viewArea, uint id );
183 	/**
184 	 * Removes a ViewArea from internal lists
185 	 */
186 	void setViewAreaRemoved( uint id );
187 	/**
188 	 * Sets the id to be "used"
189 	 */
190 	void setIdUsed( int id );
191 	/**
192 	 * Writes the state of the View Container (layout of views and view URLs)
193 	 * to the given KConfig. Doesn't change the group - so preset it if
194 	 * needed!
195 	 */
196 	void saveState( KConfigGroup *config );
197 	/**
198 	 * Reads in the saved config state (as written by saveState), and restores
199 	 * the ViewContainer with all appropriate views open
200 	 * @param groupName e.g. "ViewContainer 1"
201 	 */
202 	void restoreState( KConfigGroup *config, const QString &groupName );
203 	/**
204 	 * Returns a unique id (negative) for a ViewArea that is now a Parent of other ViewAreas
205 	 */
206 	int uniqueParentId();
207 	/**
208 	 * Returns a unique id (positive) for a new ViewArea
209 	 */
210 	int uniqueNewId();
211 	/**
212 	 * Returns true if this ViewArea can save useful information as to its state
213 	 * (i.e. it's children can save useful information about their state, or has
214 	 * a view with a url in it)
215 	 */
216 	bool canSaveUsefulStateInfo() const;
217 
218 public slots:
219 	/**
220 	 * Sets the tab caption et al from the contents of this ViewContainer
221 	 */
222 	void updateCaption();
223 
224 protected slots:
225 	void baseViewAreaDestroyed( QObject *obj );
226 
227 protected:
228 	void restoreViewArea( KConfigGroup *config, int id, ViewArea *viewArea );
229 	void findActiveViewArea();
230 	int m_activeViewArea;
231 	ViewArea *m_baseViewArea;
232 	ViewAreaMap m_viewAreaMap;
233 	IntList m_usedIDs;
234 	bool b_deleted;
235 };
236 
237 #endif
238