1 /*
2  * QGuidoItemContainer.h
3  *
4  * Created by Christophe Daudin on 12/05/09.
5  * Copyright 2009 Grame. All rights reserved.
6  *
7  * GNU Lesser General Public License Usage
8  * Alternatively, this file may be used under the terms of the GNU Lesser
9  * General Public License version 2.1 as published by the Free Software
10  * Foundation and appearing in the file LICENSE.LGPL included in the
11  * packaging of this file.  Please review the following information to
12  * ensure the GNU Lesser General Public License version 2.1 requirements
13  * will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
14  *
15  *
16  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
17  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18  */
19 #ifndef GUIDO_ITEM_CONTAINER_H
20 #define GUIDO_ITEM_CONTAINER_H
21 
22 #include "QLanguageItem.h"
23 
24 #include "QGuidoGraphicsItem.h"
25 #include "QSwitcher.h"
26 
27 #include <QObject>
28 #include <QGraphicsRectItem>
29 #include <QPrinter>
30 #include <QDomElement>
31 #include <QDrag>
32 #include <QMimeData>
33 #include <QAction>
34 #include <QMenu>
35 #include <QDataStream>
36 #include <QKeyEvent>
37 
38 #define GMN_CONTAINER_MIME_PROPORTIONAL_ON		"GMNContainerMimeTypeProportionalOn"
39 #define GMN_CONTAINER_MIME_OPTIMAL_PAGE_FILL_ON	"GMNContainerMimeTypeOptimalPageFillOn"
40 #define GMN_CONTAINER_MIME_RESIZE_PAGE_ON		"GMNContainerMimeTypeResizePageOn"
41 #define GMN_CONTAINER_MIME_DISPLAY_TYPE			"GMNContainerMimeTypeDisplayType"
42 #define GMN_CONTAINER_MIME_SCALE				"GMNContainerMimeTypeScale"
43 
44 #define DOM_GUIDO_ITEM_PAGE_MODE			"mode"
45 #define DOM_GUIDO_ITEM_ORIENTATION			"orientation"
46 #define DOM_GUIDO_ITEM_OPTIMAL_PAGE_FILL	"optimalPageFill"
47 #define DOM_GUIDO_ITEM_PROPORTIONAL_LAYOUT	"proportionalLayout"
48 #define DOM_GUIDO_ITEM_RESIZE_PAGE_ON		"resizePage"
49 #define DOM_GUIDO_ITEM_DISPLAY_TYPE			"displayType"
50 #define DOM_GUIDO_ITEM_SCALE				"scale"
51 
52 //#define BASE_RGB					125,200,245
53 #define BASE_RGB					197,214,255
54 #define INVALID_RGB					250,20,20
55 #define BASE_COLOR					QColor(BASE_RGB)
56 #define ALPHA_0						150
57 #define ALPHA_1						80
58 #define ALPHA_2						50
59 #define ALPHA_3						20
60 #define SELECTED_PEN				QPen( QColor( BASE_RGB ) )
61 #define SELECTED_BRUSH				QBrush( QColor( BASE_RGB , ALPHA_1 ) )
62 #define HIGHLIGHTED_PEN				QPen( QColor( BASE_RGB ) )
63 #define HIGHLIGHTED_BRUSH			QBrush( QColor( BASE_RGB , ALPHA_2 ) )
64 //#define STANDARD_PEN				QPen( QColor( BASE_RGB , ALPHA_0 ) )
65 #define STANDARD_PEN				Qt::NoPen
66 #define STANDARD_BRUSH				Qt::NoBrush
67 #define INVALID_PEN					Qt::NoPen
68 #define INVALID_STANDARD_BRUSH		QBrush( QColor( INVALID_RGB , ALPHA_3 ) )
69 #define INVALID_HIGHLIGHTED_BRUSH	QBrush( QColor( INVALID_RGB , ALPHA_2 ) )
70 #define INVALID_BRUSH_SELECTED		QBrush( QColor( INVALID_RGB , ALPHA_1 ) )
71 #define ROUNDED_RECT_RADIUS			5
72 
73 #define CONTEXT_MENU_LAYOUT	"Layout"
74 
75 #ifdef USES_GUIDO_AR
76 	class QPaletteItem;
77 	class QPaletteItemDropper;
78 
79 #define PALETTE_GUIDO_ELEMENT	1
80 
81 #endif
82 
83 class QPageTurnerItem;
84 class QTextPathItem;
85 class QItemResizer;
86 
87 /**
88 *	\brief A specialization of QSelectionItem that only works with QGuidoItem.
89 *	It ads functionnalities to its child QGuidoItem :
90 *
91 *		- adds a contextual menu to navigate through the pages of the score when
92 *		the decorated item is a QGuidoPageGraphicsItem
93 *		- adds a contextual menu to switch the pagesAlignment of the decorated item
94 *		- adds a contextual menu to emit a switchMode signal, requesting for a change
95 *		of the decorated class. (QGuidoItem <-> QGuidoPageGraphicsItem)
96 *
97 *	You can dynamically add a QResizerItem or a QPaletteItem, in which case the QGuidoItemContainer
98 *	will emit the rescaleItem & combineItem signals when necessary.
99 *
100 *	\note In order that the QGuidoItemContainer catches UI events (mouse & keyboard) for the
101 *	the decorated QGuidoItem, the decorated QGuidoItem flags
102 *	QGraphicsItem::ItemIsSelectable and QGraphicsItem::ItemIsFocusable must remain disabled.
103 */
104 class QGuidoItemContainer : public QLanguageItem
105 {
106 	Q_OBJECT
107 
108 	public:
109 
110 		/**
111 		*	\brief Constructor.
112 		*/
113 		QGuidoItemContainer(QGraphicsItem * parent);
114 		QGuidoItemContainer(const QMimeData * mimeData			, QGraphicsItem * parent);
115 		QGuidoItemContainer(const QDomElement * domElement		, QGraphicsItem * parent);
116 		QGuidoItemContainer(const QGuidoItemContainer * other	, QGraphicsItem * parent);
117 
118 		virtual ~QGuidoItemContainer();
119 
120 		/**
121 		*	\brief Exports the Guido Score to pdf-file 'fileName'.
122 		*/
123 		void exportToPdf(const QString& fileName);
124 
125 		/*!
126 		*	\brief Create a new QDomElement storing the properties of the QGuidoItemContainer.
127 		*
128 		*	\note The QDomElement may be further used to setup another QGuidoItemContainer, using QGuidoItemContainer::loadFromDomElement.
129 		*/
130 		virtual QDomElement saveToDomElement( QDomDocument * doc);
131 		static bool recognizes(const QMimeData * data);
132 		static bool recognizes( const QDomElement * e );
133 
134 		virtual bool	setCode( const QString& code );
code()135 		virtual QString	code() const						{ return guidoItem()->gmnCode(); }
136 
isValid()137 		virtual bool isValid() const						{ return guidoItem()->isGMNValid(); }
lastErrorMessage()138 		virtual QString lastErrorMessage() const			{ return guidoItem()->getLastErrorMessage(); }
139 
currentScale()140 		float	currentScale() const						{ return guidoItem()->transform().m11(); }
141 
142 		/*!
143 		*	\brief QGuidoItemContainer comparator.
144 		*/
145 		virtual bool isEqualTo( QLanguageItem * item ) const;
146 
147 		/**
148 		*	\brief Getter to the contained QGuidoItem.
149 		*/
150 		//Note : hack. Will be removed when the Qt bug with linux & QGraphicsItem::setCacheMode will be solved.
151 		virtual QGuidoGraphicsItem * guidoItem() const;
152 
153 		/*!
154 		*	\brief	Sets the min/max scale used to set bounds to the QItemResizer.
155 		*/
156 		void setMinMaxScale(float min , float max);
157 
158 		void keyPressEvent ( QKeyEvent * event );
159 
160 		void setResizer( QItemResizer* resizer );
161 
162 	public Q_SLOTS :
163 
164 		void resized(const QRectF& newRect);
165 
166 		void switchOptimalPageFill();
167 		void switchProportional();
168 		void switchResizePage();
169 
170 		void firstPage();
171 		void previousPage();
172 		void nextPage();
173 		void lastPage();
174 
175 	protected Q_SLOTS :
176 
177 		virtual void guidoGeometryChanged();
178 		void descriptiveNameHasChanged();
179 
180 	Q_SIGNALS:
181 
182 		/*!
183 		*	\brief Emitted when the item asks to be exported.
184 		*/
185 		void exportItem();
186 
187  	protected:
188 
189 		virtual void init();
190 		void init(const QMimeData * mimeData);
191 		void init(const QDomElement * domElement);
192 		void init(const QGuidoItemContainer * other);
193 
194 		/*!
195 		*	\brief Sets the properties of the QGuidoItemContainer according to the content of the QDomElement.
196 		*
197 		*	\note QGuidoItemContainer::saveToDomElement is the symmetrical function.
198 		*	This method never fails, thanks to a default-value policy.
199 		*/
200 		virtual void loadFromDomElement( const QDomElement * );
201 
202 		/*!
203 		*	\brief Sets the properties of the QGuidoItemContainer according to the content of the QMimeData.
204 		*
205 		*	\note QGuidoItemContainer::buildMimeData is the symmetrical function.
206 		*	This method never fails, thanks to a default-value policy.
207 		*/
208 		virtual void loadFromMimeData( const QMimeData * mimeData );
209 
210 		/*!
211 		*	\brief Sets the properties of the QGuidoItemContainer according to the content of the otherContainer.
212 		*
213 		*	It doesn't matter if the other QGuidoItemContainer is a different derived class : in this case,
214 		*	only the common attributes are imported.
215 		*/
216 		virtual void loadFromOtherContainer( const QGuidoItemContainer * otherContainer );
217 
218 		/*!
219 		*	\brief Returns the action list for contextual menu. Subclasses may extend this function.
220 		*/
221 		virtual QMenu* buildContextMenu();
222 
223 		/*!
224 		*	\brief QLanguageItem implementation.
225 		*/
226 		QImage* buildDragImage();
227 
228 		/*!
229 		*	\brief Print the contained QGuidoItem on the QPrinter. Pure virtual.
230 		*/
231 		void exportToPdf( QPrinter * printer );
232 
233 		/*!
234 		*	\brief Updates the layoutSettings of the contained QGuidoItem according to mIsProportionalOn and mIsOptimalPageFillOn.
235 		*/
236 		void updateLayoutSettings();
237 
238 		void setOptimalPageFill(bool isOptimalPageFillOn);
239 		void setProportional(bool isProportionalOn);
240 		void setResizePageToMusic(bool isResizePageOn);
241 
242 		/*!
243 		*	\brief Builds the QMimeData containing the properties of the QGuidoItemContainer.
244 		*
245 		*	Subclasses may extend this function.
246 		*
247 		*	\note QGuidoItemContainer::loadFromMimeData is the symmetrical function.
248 		*/
249 		virtual QMimeData *	buildMimeData();
250 
251 		void updateTitleBarVisibility();
252 		void updateTitleBar();
253 		void updateTitleText();
254 		void updateSyntaxErrorItem();
255 		void updateSelectionItem();
256 		void updatePageItemsVisibility();
257 		void updatePageIndexLabel();
258 		void updateResizerColor();
259 		void setCurrentPage(int page);
260 		void setFile(const QString& fileName);
261 		QVariant itemChange( GraphicsItemChange change, const QVariant& value );
262 		void hoverEnterEvent ( QGraphicsSceneHoverEvent * e );
263 		void hoverLeaveEvent ( QGraphicsSceneHoverEvent * e );
264 		void guidoUpdateGeometry(const QRectF& r);
265 
266 		void resize( float xScale , float yScale );
267 
268 		QGuidoGraphicsItem * mGuidoItem;
269 
270 		bool mIsProportionalOn;
271 		bool mIsOptimalPageFillOn;
272 
273 		float mMinScale, mMaxScale;
274 
275 		QPageTurnerItem * mNextPageTurner;
276 		QPageTurnerItem * mPreviousPageTurner;
277 		QTextPathItem * mPageLabelItem;
278 
279 		QTextPathItem * mHeadBar;
280 //		QTextPathItem * mSyntaxErrorItem;
281 		struct PenBrush {
282 			QPen mPen;
283 			QBrush mBrush;
284 			PenBrush(const QPen& p = QPen() , const QBrush& b = QBrush())
285 			{
286 				mPen = p; mBrush = b;
287 			}
288 		};
289 		QSwitcher<PenBrush> mPenBrushSwitcher;
290 		QGraphicsPathItem * mSelectionItem;
291 
292 		QItemResizer* mResizer;
293 		enum ResizeMode {
294 			RESIZE_NORMAL = 0,
295 			RESIZE_GRID = 1,
296 			RESIZE_FORMAT = 2
297 		};
298 		int mResizeMode;
299 
300 #ifdef USES_GUIDO_AR
301 
302 	public :
303 
304 		virtual void play();
305 		virtual void pause();
306 		virtual void stop();
307 
308 		int mMidiRef;
309 		typedef enum PlayerState {
310 			PLAYING , PAUSED , STOPPED
311 		} PlayerState;
312 		PlayerState mPlayerState;
313 #endif
314 
315 };
316 
317 #endif //GUIDO_ITEM_DECOARTOR_H
318