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_MSA_EDITOR_H_
23 #define _U2_MSA_EDITOR_H_
24 
25 #include <U2Core/MultipleSequenceAlignmentObject.h>
26 #include <U2Core/U2Msa.h>
27 
28 #include "MaEditor.h"
29 #include "MsaEditorWgt.h"
30 #include "phy_tree/MSAEditorTreeManager.h"
31 
32 namespace U2 {
33 
34 class PairwiseAlignmentTask;
35 class U2SequenceObject;
36 
37 class PairwiseAlignmentWidgetsSettings {
38 public:
PairwiseAlignmentWidgetsSettings()39     PairwiseAlignmentWidgetsSettings()
40         : firstSequenceId(U2MsaRow::INVALID_ROW_ID),
41           secondSequenceId(U2MsaRow::INVALID_ROW_ID), inNewWindow(true),
42           showSequenceWidget(true), showAlgorithmWidget(false),
43           showOutputWidget(false), sequenceSelectionModeOn(false) {
44     }
45 
46     qint64 firstSequenceId;
47     qint64 secondSequenceId;
48     QString algorithmName;
49     bool inNewWindow;
50     QString resultFileName;
51     QPointer<PairwiseAlignmentTask> pairwiseAlignmentTask;
52     bool showSequenceWidget;
53     bool showAlgorithmWidget;
54     bool showOutputWidget;
55     bool sequenceSelectionModeOn;
56 
57     QVariantMap customSettings;
58 };
59 
60 /** Variants of the group sort modes supported by UGENE. */
61 enum class GroupsSortOrder {
62     /** Groups are not sorted at all. This is default behaviour of UGENE. */
63     Original,
64 
65     /** Small groups go first in the name list. */
66     Ascending,
67 
68     /** Large groups go first in the name list. */
69     Descending,
70 };
71 
72 class U2VIEW_EXPORT MSAEditor : public MaEditor {
73     Q_OBJECT
74     Q_DISABLE_COPY(MSAEditor)
75 
76     friend class MSAEditorTreeViewerUI;
77     friend class SequenceAreaRenderer;
78     friend class SequenceWithChromatogramAreaRenderer;
79 
80 public:
81     MSAEditor(const QString &viewName, MultipleSequenceAlignmentObject *obj);
82     ~MSAEditor();
83 
getSettingsRoot()84     QString getSettingsRoot() const override {
85         return MSAE_SETTINGS_ROOT;
86     }
87 
getMaObject()88     MultipleSequenceAlignmentObject *getMaObject() const override {
89         return qobject_cast<MultipleSequenceAlignmentObject *>(maObject);
90     }
91 
92     /** Returns selection controller instance. The instance is always defined and is never null. */
93     MaEditorSelectionController *getSelectionController() const override;
94 
95     void buildStaticToolbar(QToolBar *tb) override;
96 
97     void buildMenu(QMenu *m, const QString &type) override;
98 
99     MsaEditorWgt *getUI() const override;
100 
101     // Return alignment row that is displayed on target line in MSAEditor
102     MultipleSequenceAlignmentRow getRowByViewRowIndex(int viewRowIndex) const;
103 
getPairwiseAlignmentWidgetsSettings()104     PairwiseAlignmentWidgetsSettings *getPairwiseAlignmentWidgetsSettings() const {
105         return pairwiseAlignmentWidgetsSettings;
106     }
107 
getTreeManager()108     MSAEditorTreeManager *getTreeManager() {
109         return &treeManager;
110     }
111 
112     void buildTree();
113 
114     QString getReferenceRowName() const override;
115 
116     char getReferenceCharAt(int pos) const override;
117 
118     void sortSequences(const MultipleAlignment::SortType &sortType, const MultipleAlignment::Order &sortOrder);
119 
120     /** Forces complete re-computation of the active collapse model based on the current MSA editor state. */
121     void updateCollapseModel();
122 
123     void setRowOrderMode(MaEditorRowOrderMode mode) override;
124 
125     /** Returns current set of free-mode markers. */
126     const QSet<QObject *> &getFreeModeMasterMarkersSet() const;
127 
128     /** Adds new marker object into freeModeMasterMarkersSet. */
129     void addFreeModeMasterMarker(QObject *marker);
130 
131     /** Removes the given marker object from the freeModeMasterMarkersSet. */
132     void removeFreeModeMasterMarker(QObject *marker);
133 
134 protected slots:
135     void sl_onContextMenuRequested(const QPoint &pos) override;
136 
137     void sl_buildTree();
138     void sl_align();
139     void sl_addToAlignment();
140     void sl_searchInSequences();
141     void sl_searchInSequenceNames();
142     void sl_realignSomeSequences();
143     void sl_setSeqAsReference();
144     void sl_unsetReferenceSeq();
145 
146     void sl_showTreeOP();
147     void sl_hideTreeOP();
148     void sl_rowsRemoved(const QList<qint64> &rowIds);
149     void sl_updateRealignAction();
150     void sl_showCustomSettings();
151     void sl_sortSequencesByName();
152     void sl_sortSequencesByLength();
153     void sl_sortSequencesByLeadingGap();
154 
155     /**
156      * Slot for sortByLeadingGap(Ascending/Descending)Action.
157      * Re-sorts group of sequences based on the sender action: using ascending or descending order.
158      */
159     void sl_sortGroupsBySize();
160 
161     /** Converts from DNA to RNA alphabet and back. */
162     void sl_convertBetweenDnaAndRnaAlphabets();
163 
164     /** Converts from RAW to DNA alphabet. Replaces all unknown chars with 'N' and 'U' with 'T'. */
165     void sl_convertRawToDnaAlphabet();
166 
167     /** Converts from RAW to Amino alphabet. Replaces all unknown chars with 'X'. */
168     void sl_convertRawToAminoAlphabet();
169 
170     /** Shows 'Export Image' dialog. */
171     void sl_exportImage();
172 
173 protected:
174     QWidget *createWidget() override;
175     bool eventFilter(QObject *o, QEvent *e) override;
176     bool onObjectRemoved(GObject *obj) override;
177     void onObjectRenamed(GObject *obj, const QString &oldName) override;
178     bool onCloseEvent() override;
179 
180     void addCopyPasteMenu(QMenu *m) override;
181     void addEditMenu(QMenu *m) override;
182     void addSortMenu(QMenu *m);
183     void addExportMenu(QMenu *m) override;
184     void addAppearanceMenu(QMenu *m);
185     void addColorsMenu(QMenu *m);
186     void addHighlightingMenu(QMenu *m);
187     void addNavigationMenu(QMenu *m);
188     void addTreeMenu(QMenu *m);
189     void addAdvancedMenu(QMenu *m);
190     void addStatisticsMenu(QMenu *m);
191 
192     void updateActions() override;
193 
194     void initDragAndDropSupport();
195 
196 public:
197     QAction *buildTreeAction = nullptr;
198     QAction *alignAction = nullptr;
199     QAction *alignSequencesToAlignmentAction = nullptr;
200     QAction *realignSomeSequenceAction = nullptr;
201     QAction *setAsReferenceSequenceAction = nullptr;
202     QAction *unsetReferenceSequenceAction = nullptr;
203     QAction *gotoAction = nullptr;
204     QAction *searchInSequencesAction = nullptr;
205     QAction *searchInSequenceNamesAction = nullptr;
206     QAction *openCustomSettingsAction = nullptr;
207     QAction *sortByNameAscendingAction = nullptr;
208     QAction *sortByNameDescendingAction = nullptr;
209     QAction *sortByLengthAscendingAction = nullptr;
210     QAction *sortByLengthDescendingAction = nullptr;
211     QAction *sortByLeadingGapAscendingAction = nullptr;
212     QAction *sortByLeadingGapDescendingAction = nullptr;
213 
214     /** Initiates a dialog to export the alignment using some image format. */
215     QAction *saveScreenshotAction = nullptr;
216 
217     /**
218      * Sorts collapsing groups by number of sequences in ascending order.
219      * The action is only enabled in 'MaEditorRowOrderMode::Sequence' mode when there are groups of length >=2.
220      */
221     QAction *sortGroupsBySizeAscendingAction = nullptr;
222 
223     /**
224      * Sorts collapsing groups by number of sequences in descending descending order.
225      * The action is only enabled in 'MaEditorRowOrderMode::Sequence' mode when there are groups of length >=2.
226      */
227     QAction *sortGroupsBySizeDescendingAction = nullptr;
228 
229     QAction *convertDnaToRnaAction = nullptr;
230     QAction *convertRnaToDnaAction = nullptr;
231     QAction *convertRawToDnaAction = nullptr;
232     QAction *convertRawToAminoAction = nullptr;
233 
234 private:
235     PairwiseAlignmentWidgetsSettings *pairwiseAlignmentWidgetsSettings = nullptr;
236     MSAEditorTreeManager treeManager;
237 
238     /**
239      * Sort order for groups.
240      * Default is 'Descending' - groups with the most sequences are on top.
241      */
242     GroupsSortOrder groupsSortOrder = GroupsSortOrder::Original;
243 
244     /**
245      * Set of 'marker' objects from the 'master' components that requested Free ordering mode to be ON are responsible for the 'free' mode ordering.
246      * Free mode can be active only if there is at least one 'marker' in the set.
247      *
248      * When the last marker object is removed from the set the ordering automatically switches to the 'Original'.
249      * Example of master components: multiple synchronized phy-tree views that manage the order of MSA.
250      *
251      * MSAEditor can any time reset this set and switch to 'Original' or 'Sequence' mode.
252      */
253     QSet<QObject *> freeModeMasterMarkersSet;
254 
255     /** Selection state controller. */
256     MaEditorSelectionController *selectionController;
257 };
258 
259 /** Set of custom menu actions in MSA editor. */
260 class U2VIEW_EXPORT MsaEditorMenuType : public GObjectViewMenuType {
261 public:
262     /** "Align" button menu identifier. */
263     const static QString ALIGN;
264 
265     /** "Align sequence(s) to this alignment" menu identifier. */
266     const static QString ALIGN_SEQUENCES_TO_ALIGNMENT;
267 };
268 
269 }  // namespace U2
270 
271 #endif  // _U2_MSA_EDITOR_H_
272