1 /*
2 # PostgreSQL Database Modeler (pgModeler)
3 #
4 # Copyright 2006-2020 - Raphael Araújo e Silva <raphael@pgmodeler.io>
5 #
6 # This program is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation version 3.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14 #
15 # The complete text of GPLv3 is at LICENSE file on source code root directory.
16 # Also, you can get the complete GNU General Public License at <http://www.gnu.org/licenses/>
17 */
18 
19 /**
20 \ingroup libobjrenderer
21 \class BaseTableView
22 \brief Base class shared by the classes TableView and GraphicalView
23 */
24 
25 #ifndef BASE_TABLE_VIEW_H
26 #define BASE_TABLE_VIEW_H
27 
28 #include "baseobjectview.h"
29 #include "basetable.h"
30 #include "tabletitleview.h"
31 #include "tableobjectview.h"
32 #include "roundedrectitem.h"
33 #include "baserelationship.h"
34 #include "textpolygonitem.h"
35 #include "attributestoggleritem.h"
36 
37 class BaseTableView: public BaseObjectView {
38 	private:
39 		Q_OBJECT
40 
41 		/*! \brief This timer is used to control the selection enabling of the object
42 		 * in mouse presse event in order to avoid select it instead of a child.
43 		 * See mousePressEvent() for details */
44 		QTimer sel_enabler_timer;
45 
46 		/*! \brief Stores the references to the relationships connected to this table. */
47 		vector<BaseRelationship *> connected_rels;
48 
49 	protected:
50 		//! \brief Stores the selected child objects in order to retrieve them in ObjectScene/ModelWidget
51 		QList<TableObjectView *> sel_child_objs;
52 
53 		/*! \brief This attributes indicates that the object's geometry update is pending demanding a
54 		 * call to configureObject(). This attribute is set to true only when the objects is invisible
55 		 * the the configureObject is called. Once the object gets visible again this attribute is set
56 		 * to false and the geometry updated immediately (see BaseTableView::itemChange()) */
57 		bool pending_geom_update;
58 
59 		//! \brief Item groups that stores columns and extended attributes, respectively
60 		QGraphicsItemGroup *columns,
61 
62 		*ext_attribs;
63 
64 		//! brief Indicates if the extended attributes body should be hidden
65 		static bool hide_ext_attribs,
66 
67 		//! brief Indicates if the tag object should be hidden
68 		hide_tags;
69 
70 		//! brief Controls the maximum amount of attributes visible per page (columns/references + extended attributes)
71 		static unsigned attribs_per_page[2];
72 
73 		//! \brief Polygonal object that defines the table body
74 		RoundedRectItem *body,
75 
76 		//! \brief Extended table attributes (indexes, rules, triggers) section body
77 		*ext_attribs_body;
78 
79 		AttributesTogglerItem *attribs_toggler;
80 
81 		TextPolygonItem *tag_item;
82 
83 		//! \brief Stores the reference to the child object currently selected on table
84 		TableObjectView *sel_child_obj_view;
85 
86 		//! \brief Table title
87 		TableTitleView *title;
88 
89 		//! \brief Stores the original table's tool tip
90 		QString table_tooltip;
91 
92 		QVariant itemChange(GraphicsItemChange change, const QVariant &value);
93 
94 		void addConnectedRelationship(BaseRelationship *base_rel);
95 
96 		void removeConnectedRelationship(BaseRelationship *base_rel);
97 
98 		/*! \brief Returns the index of the relationship in the list of the connected relationships
99 		 * If 'only_self_rels' is true then only self relationship are searched */
100 		int getConnectedRelationshipIndex(BaseRelationship *base_rel, bool only_self_rels = false);
101 
102 		//! \brief Configures the tag object when the source object has one.
103 		void configureTag();
104 
105 		/*! \brief Configures basic attributes of the table. A width need to be provided so
106 		the extended attributes section can follow the same width as the body and title */
107 		void __configureObject(double width);
108 
109 		//! \brief Determines the table width based upon its subsection (title, body and extended attribs)
110 		double calculateWidth();
111 
112 		/*! \brief This as an auxiliary method called before the object changes its dimensions and it causes
113 		 * the object to not being selectable. This method is called whenever one of the signals are captured
114 		 * from the attributes toggler: s_paginationToggled s_currentPageChanged s_collapseModeChanged */
115 		void startGeometryUpdate();
116 
117 		/*! \brief This auxiliary method is called after any geometry change finishes forcing the update of the object
118 		 * and in some cases the schema box which contains it */
119 		void finishGeometryUpdate();
120 
121 		/*! \brief Determines the pagination paramenters for a section of the table. The input parameters are
122 		 * the section (BaseTable::AttribsSection | ExtAttribsSection) and the total amount of attributes in the section.
123 		 * The other paramenters start_attr and end_attr are reference parameters that will hold the indexes of items
124 		 * to be displayed in the current page. See configureObject() on TableView and GraphicalView */
125 		bool configurePaginationParams(unsigned page_id, unsigned total_attrs, unsigned &start_attr, unsigned &end_attr);
126 
127 	public:
128 		static constexpr unsigned LeftConnPoint=0,
129 		RightConnPoint=1;
130 
131 		BaseTableView(BaseTable *base_tab);
132 		virtual ~BaseTableView();
133 
134 		void hoverLeaveEvent(QGraphicsSceneHoverEvent *);
135 		void hoverMoveEvent(QGraphicsSceneHoverEvent *event);
136 		void mousePressEvent(QGraphicsSceneMouseEvent *event);
137 
138 		//! brief Defines the amount of attributes per page to be displayed
139 		static void setAttributesPerPage(unsigned section_id, unsigned value);
140 
141 		//! brief Returns the current amount of attributes per page to be displayed
142 		static unsigned getAttributesPerPage(unsigned section_id);
143 
144 		//! \brief Hides the table's extended attributes (rules, triggers, indexes). This applies to all table/view instances
145 		static void setHideExtAttributes(bool value);
146 
147 		//! \brief Hides the table tags. This applies to all table instances
148 		static void setHideTags(bool value);
149 
150 		//! \brief Returns the current visibility state of extended attributes
151 		static bool isExtAttributesHidden();
152 
153 		//! \brief Returns the current visibility state of tags
154 		static bool isTagsHidden();
155 
156 		//! \brief Returns the current count of connected relationships
157 		int getConnectRelsCount();
158 
159 		//! \brief This method just emits the signal to indicate that the relationships attached must be updated
160 		void requestRelationshipsUpdate();
161 
162 		//! \brief Toggles the placeholder object when there is at least one relationship connected to the object
163 		virtual void togglePlaceholder(bool value);
164 
165 		unsigned getConnectedRelsCount(BaseTable *src_tab, BaseTable *dst_tab);
166 
167 		//! \brief Configures the shadow for the table
168 		void configureObjectShadow();
169 
170 		//! \brief Returns a list of selected children objects
171 		QList<TableObjectView *> getSelectedChidren();
172 
173 		//! \brief Clear the selection over all selected children
174 		void clearChildrenSelection();
175 
176 	private slots:
177 		/*! \brief This slot reconfigures the table when the attributes toggler emits the signal s_collapseModeChanged
178 		 * hiding or exposing the sections related to the current collapse mode */
179 		void configureCollapsedSections(CollapseMode coll_mode);
180 
181 		//! \brief This slot reconfigures the table when the attributes toggler emits the signal s_paginationToggled
182 		void togglePagination(bool enabled);
183 
184 		/*! \brief This slot reconfigures the table when the attributes toggler emits the signal s_currentPageChanged
185 		 * causing the the attributes of the current page to be displayed */
186 		void configureCurrentPage(unsigned section_id, unsigned page);
187 
188 	signals:
189 		//! \brief Signal emitted when a table is moved over the scene
190 		void s_objectMoved();
191 
192 		//! \brief Signal emitted to indicate that the relationships attached to the table need to be updated
193 		void s_relUpdateRequest();
194 
195 		//! \brief Signal emitted when the user right-click a focused table child object requesting a popup menu
196 		void s_popupMenuRequested(TableObject *);
197 
198 		//! \brief Signal emitted when the user clicks a focused table child object and holding Control+Shift
199 		void s_childrenSelectionChanged();
200 
201 		//! \brief Signal emitted when the user toggles the table's collapse mode
202 		void s_collapseModeChanged();
203 
204 		//! \brief Signal emitted when the user toggles the table's attributes pagination
205 		void s_paginationToggled();
206 
207 		//! \brief Signal emitted when the user changes the current table's attributes page
208 		void s_currentPageChanged();
209 
210 		//! \brief Signal emitted when the object need the scene to clear its selection
211 		void s_sceneClearRequested();
212 
213 		friend class RelationshipView;
214 };
215 
216 #endif
217