1 /*
2 For general Scribus (>=1.3.2) copyright and licensing information please refer
3 to the COPYING file provided with the program. Following this notice may exist
4 a copyright and/or license notice that predates the release of Scribus 1.3.2
5 for which a new license (GPL+exception) is in place.
6 */
7 /***************************************************************************
8 	copyright            : (C) 2005 by Craig Bradney
9 	email                : cbradney@zip.com.au
10 ***************************************************************************/
11 
12 /***************************************************************************
13 *                                                                         *
14 *   This program is free software; you can redistribute it and/or modify  *
15 *   it under the terms of the GNU General Public License as published by  *
16 *   the Free Software Foundation; either version 2 of the License, or     *
17 *   (at your option) any later version.                                   *
18 *                                                                         *
19 ***************************************************************************/
20 #ifndef SELECTION_H
21 #define SELECTION_H
22 
23 #include <QList>
24 #include <QMap>
25 #include <QObject>
26 #include <QPointer>
27 #include <QRectF>
28 
29 #include "pageitem.h"
30 #include "scribusapi.h"
31 
32 typedef QList< QPointer<PageItem> > SelectionList;
33 
34 class SCRIBUS_API Selection : public QObject
35 {
36 	Q_OBJECT
37 	public:
38 		/**
39 		 * \brief Create an empty selection that is not a GUI selection
40 		 * @param  parent QObject
41 		 */
42 		explicit Selection(QObject* parent);   // otherwise implicit conversion Selection* -> Selection& is possible
43 		/**
44 		 * \brief Create an empty selection that may be a GUI selection
45 		 * @param  parent QObject
46 		 * @param  guiSelection If the selection is to be a GUI selection
47 		 */
48 		Selection(QObject* parent, bool guiSelection);
49 		/**
50 		 * \brief Copy a selection
51 		 * \note We are leaving the connections of the items in place
52 		 * and the isGUISelection set in the copy. We cannot disconnect them
53 		 * as they may be connected via the main GUI selection.
54 		 * @param  other selection
55 		 */
56 		Selection(const Selection& other);
57 		Selection& operator=( const Selection & );
58 		~Selection();
59 
60 		/**
61 		 * \brief Copy the selection of items from one selection to another
62 		 */
63 		void copy(Selection& other, bool emptyOther);
64 
65 		bool connectItemToGUI();
66 		/**
67 		 * \brief Disconnect all items from the GUI slots.
68 		 * This should not really be necessary if all things are going ok
69 		 * except for within the clearAll function.
70 		 * @return bool true on success
71 		 */
72 		bool disconnectAllItemsFromGUI();
73 		/**
74 		 * @brief Add an item to the selection.
75 		 * If its added to a GUI selection selection and its item 0, its connected to the GUI too
76 		 * @param item Item to add
77 		 * @param ignoreGUI Don't connect Item To GUI even if this is a GUI selection
78 		 * @return If the item was added
79 		 */
80 		bool addItem(PageItem *item, bool ignoreGUI=false);
81 		/**
82 		 * @brief Add items to the selection.
83 		 * If its added to a GUI selection selection and its item 0, its connected to the GUI too
84 		 * @param item Item to add
85 		 * @return If any item was added
86 		 */
87 		bool addItems(QList<PageItem *> items);
88 		/**
89 		 * @brief Prepend an item to the selection.
90 		 * If its added to a GUI selection selection and its item 0, its connected to the GUI too
91 		 * @param item Item to add
92 		 * @param doEmit call emitAllToGUI()
93 		 * @return If the item was added
94 		 */
95 		bool prependItem(PageItem *item);
96 
containsItem(PageItem * item)97 		bool containsItem(PageItem *item) const { return m_SelList.contains(item); }
98 
99 		/**
100 		 * \brief Remove an item from list
101 		 * @param item page item
102 		 */
103 		bool removeItem(PageItem *item);
104 		/**
105 		 * \brief Remove items from specified layer
106 		 */
107 		bool removeItemsOfLayer(int layedID);
108 		/**
109 		 * \brief Remove the first item from the list
110 		 * @return If the remove was successful
111 		 */
112 		bool removeFirst();
113 		/**
114 		 * \brief Unused
115 		 */
116 		bool removeGroup();
117 
118 		/**
119 		 * Replace item in selection by another
120 		 */
121 		void replaceItem(PageItem* oldItem, PageItem* newItem);
122 
123 		/**
124 		 * \brief Remove an item from list listNumber and return a pointer to it
125 		 * @param itemIndex Index of the item in the list
126 		 * @return Item
127 		 */
128 		PageItem* takeItem(int itemIndex);
129 		/**
130 		 * \brief Find an item from the selection and return an index to it
131 		 * @param item Item pointer to find in the list
132 		 * @return Item
133 		 */
findItem(PageItem * item)134 		int findItem(PageItem *item) const { return m_SelList.indexOf(item); }
135 		/**
136 		 * \brief Return the count of the selection
137 		 */
count()138 		int count() const { return m_SelList.count(); }
139 		/**
140 		 * \brief Check if the selection is empty.
141 		 */
isEmpty()142 		bool isEmpty() const { return m_SelList.count() == 0; }
143 		/**
144 		 * \brief Clear a list
145 		 */
146 		bool clear();
147 		/**
148 		 * \brief See if the first selected item is "me", usually called from an item object with "this".
149 		 * @param item PageItem reference
150 		 */
primarySelectionIs(const PageItem * item)151 		bool primarySelectionIs(const PageItem* item) const { return (!m_SelList.isEmpty() && (item==m_SelList.first())); }
selectionList()152 		const SelectionList& selectionList() const {return m_SelList;}
153 		PageItem *itemAt(int index=0) { return itemAt_(index); }
154 		const PageItem *itemAt(int index=0) const { return const_cast<Selection*>(this)->itemAt_(index); }
155 		QList<PageItem*> items() const;
156 		QStringList getSelectedItemsByName() const;
isMultipleSelection()157 		bool isMultipleSelection() const { return (m_SelList.count() > 1); }
isGUISelection()158 		bool isGUISelection() const { return m_isGUISelection; }
159 		double width() const;
160 		double height() const;
161 		//set the group rectangle properties
162 		void setGroupRect();
163 		void getGroupRect(double *x, double *y, double *w, double *h);
164 		QRectF getGroupRect();
165 		void getVisualGroupRect(double *x, double *y, double *w, double *h);
166 		QRectF getVisualGroupRect();
167 		//!\brief Test if selection contains object of specified item type
168 		bool containsItemType(PageItem::ItemType type) const;
169 		//!\brief Test to see if all items in the selection are the same typedef
170 		bool itemsAreSameType() const;
171 		//!\brief Test to see if all items in the selection are on same page
172 		bool itemsAreOnSamePage() const;
173 
174 		/**
175 		 * \brief get the layer ID of items in the selection
176 		 * @return the layer ID or -1 if items do not belong to the same layer
177 		 */
178 		int objectsLayer() const;
179 
180 		/**
181 		 * \brief detect if selected object have all same parent (doc or group)
182 		 * @return true if objects share same parent, false otherwise
183 		 */
184 		bool objectsHaveSameParent() const;
185 
186 		bool signalsDelayed();
187 		void delaySignalsOn();
188 		void delaySignalsOff();
189 
190 	protected:
191 		PageItem *itemAt_(int index=0);
192 		SelectionList m_SelList;
193 		bool m_isGUISelection;
194 		double m_groupX;
195 		double m_groupY;
196 		double m_groupW;
197 		double m_groupH;
198 
199 		double m_visualGX;
200 		double m_visualGY;
201 		double m_visualGW;
202 		double m_visualGH;
203 
204 		int  m_delaySignals;
205 		bool m_sigSelectionChanged;
206 
207 		void sendSignals(bool guiConnect = true);
208 
209 	signals:
210 		void selectionChanged();
211 };
212 
213 #endif
214