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_ANNOTATED_DNA_VIEW_H_
23 #define _U2_ANNOTATED_DNA_VIEW_H_
24 
25 #include <QPointer>
26 #include <QSplitter>
27 #include <QTextEdit>
28 
29 #include <U2Core/Annotation.h>
30 #include <U2Core/Task.h>
31 
32 #include <U2Gui/ObjectViewModel.h>
33 
34 class QScrollArea;
35 class QVBoxLayout;
36 
37 namespace U2 {
38 
39 class AnnotatedDNAView;
40 class AnnotatedDNAViewState;
41 class U2SequenceObject;
42 class AnnotationTableObject;
43 class Annotation;
44 class GSequenceLineView;
45 class AnnotationsTreeView;
46 class AnnotationSelection;
47 class AnnotationGroupSelection;
48 class Task;
49 class ADVClipboard;
50 class ADVSequenceWidget;
51 class ADVSplitWidget;
52 class ADVSequenceObjectContext;
53 class PositionSelector;
54 class GObjectReference;
55 class ADVSyncViewManager;
56 class ADVObjectHandler;
57 class ADVGlobalAction;
58 class AutoAnnotationObject;
59 class AutoAnnotationsUpdater;
60 class OptionsPanel;
61 
62 class CodonTableView;
63 
64 class U2VIEW_EXPORT AnnotatedDNAView : public GObjectView {
65     Q_OBJECT
66     friend class DetViewSequenceEditor;  // TODO_SVEDIT: remove this
67 public:
68     AnnotatedDNAView(const QString &viewName, const QList<U2SequenceObject *> &dnaObjects);
69     ~AnnotatedDNAView();
70 
71     void buildStaticToolbar(QToolBar *tb) override;
72 
73     void buildMenu(QMenu *menu, const QString &type) override;
74 
75     Task *updateViewTask(const QString &stateName, const QVariantMap &stateData) override;
76 
77     QVariantMap saveState() override;
78 
79     OptionsPanel *getOptionsPanel() override;
80 
81     // view content
getSequenceContexts()82     const QList<ADVSequenceObjectContext *> &getSequenceContexts() const {
83         return seqContexts;
84     }
85 
86     QList<U2SequenceObject *> getSequenceObjectsWithContexts() const;
87 
88     QList<GObject *> getSequenceGObjectsWithContexts() const;
89 
90     QList<AnnotationTableObject *> getAnnotationObjects(bool includeAutoAnnotations = false) const;
91 
getAnnotationsSelection()92     AnnotationSelection *getAnnotationsSelection() const {
93         return annotationSelection;
94     }
95 
getAnnotationsGroupSelection()96     AnnotationGroupSelection *getAnnotationsGroupSelection() const {
97         return annotationGroupSelection;
98     }
99 
getSequenceWidgets()100     const QList<ADVSequenceWidget *> getSequenceWidgets() const {
101         return seqViews;
102     }
103 
104     bool canAddObject(GObject *obj) override;
105 
106     void addSequenceWidget(ADVSequenceWidget *widgetToAdd);
107 
108     void removeSequenceWidget(ADVSequenceWidget *sequenceWidget);
109 
110     void insertWidgetIntoSplitter(ADVSplitWidget *widget);
111 
112     void unregisterSplitWidget(ADVSplitWidget *widget);
113 
114     QString addObject(GObject *o) override;
115 
116     void saveWidgetState() override;
117 
118     ADVSequenceObjectContext *getSequenceContext(AnnotationTableObject *obj) const;
119 
120     ADVSequenceObjectContext *getSequenceContext(U2SequenceObject *) const;
121 
122     ADVSequenceObjectContext *getSequenceContext(const GObjectReference &r) const;
123 
getScrolledWidget()124     QWidget *getScrolledWidget() const {
125         return scrolledWidget;
126     }
127 
128     /** Returns active sequence widget. See 'activeSequenceWidget' docs. */
129     ADVSequenceWidget *getActiveSequenceWidget() const;
130 
131     /** Returns context of the active sequence widget. See 'activeSequenceWidget' docs. */
132     ADVSequenceObjectContext *getActiveSequenceContext() const;
133 
134     /** Sets sequence widget as active. See 'activeSequenceWidget' docs. */
135     void setActiveSequenceWidget(ADVSequenceWidget *sequenceWidget);
136 
137     QList<ADVSequenceObjectContext *> findRelatedSequenceContexts(GObject *obj) const;
138 
139     void updateState(const AnnotatedDNAViewState &s);
140 
getCreateAnnotationAction()141     QAction *getCreateAnnotationAction() const {
142         return createAnnotationAction;
143     }
144 
145     void addADVAction(ADVGlobalAction *a);
146 
getAnnotationsView()147     AnnotationsTreeView *getAnnotationsView() {
148         return annotationsView;
149     }
150 
151     void updateAutoAnnotations();
152 
153     /**
154      * Returns "true" if all input annotations are within the bounds of the associated sequences.
155      * Returns "true" in case of an error.
156      * Otherwise, returns "false", i.e. the method returns "false", even if an annotation intersects a sequence only partially.
157      */
158     bool areAnnotationsInRange(const QList<Annotation *> &toCheck);
159 
160     /**
161      * Tries to add object to the view. Uses GUI functions to ask user if some data if needed
162      * Returns error message if failed.
163      * If object is unloaded - intitiates async object loading
164      */
165     QString tryAddObject(GObject *obj);
166 
getCodonTableView()167     const CodonTableView *getCodonTableView() const {
168         return codonTableView;
169     }
170 
171 protected:
172     QWidget *createWidget() override;
173     bool onObjectRemoved(GObject *o) override;
174     void onObjectRenamed(GObject *obj, const QString &oldName) override;
175     bool eventFilter(QObject *, QEvent *) override;
176     void timerEvent(QTimerEvent *e) override;
177 
178     bool isChildWidgetObject(GObject *o) const;
179     virtual void addAnalyseMenu(QMenu *m);
180     virtual void addAddMenu(QMenu *m);
181     virtual void addExportMenu(QMenu *m);
182     virtual void addAlignMenu(QMenu *m);
183     virtual void addRemoveMenu(QMenu *m);
184     virtual void addEditMenu(QMenu *m);
185 
186     bool onCloseEvent() override;
187 
188 signals:
189     void si_sequenceAdded(ADVSequenceObjectContext *c);
190     void si_sequenceRemoved(ADVSequenceObjectContext *c);
191 
192     void si_annotationObjectAdded(AnnotationTableObject *obj);
193     void si_annotationObjectRemoved(AnnotationTableObject *obj);
194 
195     void si_sequenceWidgetAdded(ADVSequenceWidget *w);
196     void si_sequenceWidgetRemoved(ADVSequenceWidget *w);
197 
198     /** Emitted every time active sequence widget is changed. See docs for 'activeSequenceWidget'. */
199     void si_activeSequenceWidgetChanged(ADVSequenceWidget *oldActiveWidget, ADVSequenceWidget *newActiveWidget);
200 
201     /** Emitted when a part was added to a sequence, or it was removed or replaced */
202     void si_sequenceModified(ADVSequenceObjectContext *);
203     void si_onClose(AnnotatedDNAView *v);
204 
205 public slots:
206     void sl_onPosChangeRequest(int pos);
207 
208 private slots:
209     void sl_onContextMenuRequested();
210     void sl_onFindPatternClicked();
211     void sl_onShowPosSelectorRequest();
212     void sl_toggleHL();
213     void sl_splitterMoved(int, int);
214     void sl_onSequenceWidgetTitleClicked(ADVSequenceWidget *seqWidget);
215 
216     void sl_editSettings();
217     void sl_addSequencePart();
218     void sl_removeSequencePart();
219     void sl_replaceSequencePart();
220     void sl_sequenceModifyTaskStateChanged();
221 
222     void sl_paste();
223 
224     void sl_reverseComplementSequence();
225     void sl_reverseSequence();
226     void sl_complementSequence();
227     void sl_selectionChanged();
228     void sl_aminoTranslationChanged();
229     void sl_updatePasteAction();
230     void sl_relatedObjectRelationChanged();
231 
232     void sl_onDocumentAdded(Document *) override;
233     void sl_onDocumentLoadedStateChanged() override;
234 
235     virtual void sl_removeSelectedSequenceObject();
236 
237 private:
238     void updateScrollAreaHeight();
239     void updateMultiViewActions();
240 
241     void addRelatedAnnotations(ADVSequenceObjectContext *seqCtx);
242     void addAutoAnnotations(ADVSequenceObjectContext *seqCtx);
243     void removeAutoAnnotations(ADVSequenceObjectContext *seqCtx);
244     void cancelAutoAnnotationUpdates(AutoAnnotationObject *aaObj, bool *existsRemovedTasks = nullptr);
245     void addGraphs(ADVSequenceObjectContext *seqCtx);
246     void importDocAnnotations(Document *doc);
247     void seqWidgetMove(const QPoint &pos);
248     void finishSeqWidgetMove();
249     void createCodonTableAction();
250 
251     void reverseComplementSequence(bool reverse = true, bool complement = true);
252 
253     static QAction *getEditActionFromSequenceWidget(ADVSequenceWidget *seqWgt);
254 
255     QAction *createPasteAction();
256 
257     QSplitter *mainSplitter;
258     QScrollArea *scrollArea;
259     QWidget *scrolledWidget;
260     QVBoxLayout *scrolledWidgetLayout;
261 
262     CodonTableView *codonTableView;
263 
264     QAction *createAnnotationAction;
265     QAction *findPatternAction;
266     QAction *posSelectorAction;
267     QAction *toggleHLAction;
268     QAction *posSelectorWidgetAction;
269     QAction *removeAnnsAndQsAction;
270 
271     QAction *editSettingsAction;
272     QAction *addSequencePart;
273     QAction *removeSequencePart;
274     QAction *replaceSequencePart;
275     QAction *removeSequenceObjectAction;
276 
277     QAction *reverseComplementSequenceAction;
278     QAction *reverseSequenceAction;
279     QAction *complementSequenceAction;
280 
281     PositionSelector *posSelector;
282 
283     QList<ADVSequenceObjectContext *> seqContexts;
284     QList<AnnotationTableObject *> annotations;
285     QList<ADVObjectHandler *> handlers;
286     QList<ADVGlobalAction *> advActions;
287 
288     QMap<ADVSequenceObjectContext *, AutoAnnotationObject *> autoAnnotationsMap;
289 
290     AnnotationsTreeView *annotationsView;
291     QList<ADVSequenceWidget *> seqViews;
292     QList<ADVSplitWidget *> splitWidgets;
293 
294     AnnotationSelection *annotationSelection;
295     AnnotationGroupSelection *annotationGroupSelection;
296 
297     ADVClipboard *clipb;
298     ADVSyncViewManager *syncViewManager;
299 
300     /*
301      * activeSequenceWidget serves as a target for all view-global widgets.
302      * AnnotatedDNAView always has at least some 'active' sequence widget unless it is in the destroying phase.
303      */
304     ADVSequenceWidget *activeSequenceWidget;
305 
306     ADVSequenceWidget *replacedSeqWidget;  // not NULL when any sequence widget is dragging to the new place.
307 
308     int timerId;
309 
310     // Used to detect 'expandable sequences' <-> 'fixed sequences' transition event for the mainSplitter.
311     bool hadExpandableSequenceWidgetsLastResize;
312     // Used to restore mainSplitter state on 'fixed sequences'-> 'expandable sequences' transition.
313     QList<int> savedMainSplitterSizes;
314 };
315 
316 }  // namespace U2
317 
318 #endif
319