1 /**
2  * UGENE - Integrated Bioinformatics Tools.
3  * Copyright (C) 2008-2021 UniPro <ugene@unipro.ru>
4  * http://ugene.net
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19  * MA 02110-1301, USA.
20  */
21 
22 #ifndef _U2_QUERY_VIEW_ITEMS_H_
23 #define _U2_QUERY_VIEW_ITEMS_H_
24 
25 #include <QFlag>
26 #include <QFontMetricsF>
27 #include <QGraphicsItem>
28 #include <QGraphicsSceneMouseEvent>
29 #include <QGraphicsTextItem>
30 #include <QKeyEvent>
31 
32 #include <U2Lang/QDConstraint.h>
33 #include <U2Lang/QDScheme.h>
34 
35 #include "QDDocument.h"
36 #include "QueryPalette.h"
37 
38 #define GRID_STEP 40
39 
40 class QTextDocument;
41 
42 namespace U2 {
43 
44 class QueryViewController;
45 class QueryScene;
46 
47 enum {
48     QDElementType = QGraphicsItem::UserType + 1,
49     FootnoteItemType
50 };
51 
52 class QDElementDescription : public QGraphicsTextItem {
53     Q_OBJECT
54 public:
55     QDElementDescription(QGraphicsItem *parent = nullptr);
56     QRectF boundingRect() const;
57     void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
setHeight(qreal h)58     void setHeight(qreal h) {
59         height = h;
60     }
61 signals:
62     void linkClicked(const QString &link);
63 
64 protected:
65     bool sceneEvent(QEvent *event);
66     void mousePressEvent(QGraphicsSceneMouseEvent *event);
contextMenuEvent(QGraphicsSceneContextMenuEvent * event)67     void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
68         event->ignore();
69     }
70 
71 private:
72     qreal height;
73 };
74 
75 class Footnote;
76 class QDElement : public QGraphicsObject {
77     friend class QDElementDescription;
78     friend class Footnote;
79     friend class QueryViewController;
80     Q_OBJECT
81 public:
82     QDElement(QDSchemeUnit *_unit);
~QDElement()83     ~QDElement() {
84         assert(links.isEmpty());
85     }
setBoundingRect(const QRectF & r)86     void setBoundingRect(const QRectF &r) {
87         bound = r;
88     }
boundingRect()89     QRectF boundingRect() const {
90         return bound;
91     }
92     void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget /* = 0 */);
93 
94     void saveState(QDElementStatement *el) const;
95     void loadState(QDElementStatement *el);
96     // returns constraint's connection point in scene coords
97     QPointF getRightConnector();
98     QPointF getLeftConnector();
99     bool isLinkedWith(QDElement *other, QDDistanceType kind);
100 
getActor()101     QDActor *getActor() const {
102         return unit->getActor();
103     }
getSchemeUnit()104     QDSchemeUnit *getSchemeUnit() const {
105         return unit;
106     }
getFootnotes()107     const QList<Footnote *> &getFootnotes() const {
108         return links;
109     }
110     QList<Footnote *> getOutcomeFootnotes() const;
111     QList<Footnote *> getIncomeFootnotes() const;
112 
113     void adaptSize();
114     void rememberSize();
115 
116     bool highlighted;
117 
118     enum { Type = QDElementType };
type()119     int type() const {
120         return Type;
121     }
122     enum ResizeFlag {
123         ResizeRight = 1 << 1,
124         ResizeBottom = 1 << 2,
125         ResizeLeft = 1 << 3,
126         ResizeTop = 1 << 4,
127     };
128 public slots:
129     void sl_refresh();
130 private slots:
131     void sl_onHoverLink(const QString &link);
132 
133 protected:
134     void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
135     void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
136     QVariant itemChange(GraphicsItemChange change, const QVariant &value);
137     bool sceneEvent(QEvent *event);
138     void contextMenuEvent(QGraphicsSceneContextMenuEvent *event);
139 
140 private:
141     void updateDescription();
142     void updateFootnotes();
143     QString getHeaderString() const;
144 
145 private:
146     QDSchemeUnit *unit;
147     QFont font;
148     QRectF bound;
149     QPointF dragPoint;
150     bool dragging;
151     QList<Footnote *> links;
152     QTextDocument *doc;
153     qreal extendedHeight;
154 
155     typedef QFlags<ResizeFlag> ResizeFlags;
156     ResizeFlags itemResizeFlags;
157 
158     QDElementDescription *itemDescription;
159 };
160 
161 class Footnote : public QGraphicsObject {
162     friend class QDElement;
163     Q_OBJECT
164 public:
165     Footnote(QDElement *_from, QDElement *_to, QDDistanceType _distType, QDConstraint *parent, const QFont &_font = QFont());
166     ~Footnote();
167     void init();
168     QRectF boundingRect() const;
169     void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget /* = 0 */);
170     void updatePos();
171 
172     enum { Type = FootnoteItemType };
type()173     int type() const {
174         return Type;
175     }
176 
177     QPointF getSrcPoint() const;
178     QPointF getDstPoint() const;
getSrc()179     QDElement *getSrc() const {
180         return from;
181     }
getDst()182     QDElement *getDst() const {
183         return to;
184     }
185     QDElement *adjacent(QDElement *uv) const;
getConstraint()186     QDConstraint *getConstraint() const {
187         return constraint;
188     }
getDistType()189     QDDistanceType getDistType() const {
190         return distType;
191     }
192 public slots:
193     void sl_update();
194 
195 protected:
196     QVariant itemChange(GraphicsItemChange change, const QVariant &value);
197 
198 private:
199     void updateLines(const QPointF &p);
200     QString getText() const;
201 
202     QDElement *from;
203     QDElement *to;
204     QDDistanceType distType;
205     QDConstraint *constraint;
206     QFont font;
207     bool draging;
208     QGraphicsLineItem *leftRef;
209     QGraphicsLineItem *rightRef;
210 };
211 
212 class QDLabelItem : public QGraphicsTextItem {
213     Q_OBJECT
214 public:
215     QDLabelItem(const QString &text = "");
216     void keyPressEvent(QKeyEvent *event);
217     void focusOutEvent(QFocusEvent *event);
218     void mousePressEvent(QGraphicsSceneMouseEvent *event);
219 signals:
220     void si_editingFinished();
221 };
222 
223 class QDDescriptionItem : public QGraphicsTextItem {
224     Q_OBJECT
225 public:
226     QDDescriptionItem(const QString &text = "");
227     QRectF boundingRect() const;
228     void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
229     bool sceneEvent(QEvent *event);
230     void focusOutEvent(QFocusEvent *event);
231     void mousePressEvent(QGraphicsSceneMouseEvent *event);
232     QPainterPath shape() const;
233 
234 private:
235     int resize;
236 };
237 
238 class QDRulerItem : public QGraphicsObject {
239     Q_OBJECT
240 public:
QDRulerItem()241     QDRulerItem()
242         : leftPos(0), rightPos(0) {
243     }
244     void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget /* = 0 */);
245     QRectF boundingRect() const;
246 public slots:
247     void sl_updateGeometry();
248     void sl_updateText();
249 
250 protected:
251     QVariant itemChange(GraphicsItemChange change, const QVariant &value);
252 
253 private:
254     QRectF txtBound() const;
255 
256 private:
257     qreal leftPos;
258     qreal rightPos;
259     QString text;
260     QFont font;
261 };
262 
263 }  // namespace U2
264 
265 Q_DECLARE_METATYPE(U2::QDElement *);
266 
267 #endif
268