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_MA_EDITOR_H_
23 #define _U2_MA_EDITOR_H_
24 
25 #include <U2Gui/ObjectViewModel.h>
26 
27 namespace U2 {
28 
29 #define MSAE_SETTINGS_ROOT QString("msaeditor/")
30 #define MCAE_SETTINGS_ROOT QString("mcaeditor/")
31 
32 #define MSAE_MENU_APPEARANCE "MSAE_MENU_APPEARANCE"
33 #define MSAE_MENU_NAVIGATION "MSAE_MENU_NAVIGATION"
34 #define MSAE_MENU_COPY "MSAE_MENU_COPY"
35 #define MSAE_MENU_EDIT "MSAE_MENU_EDIT"
36 #define MSAE_MENU_EXPORT "MSAE_MENU_EXPORT"
37 #define MSAE_MENU_SORT "MSAE_MENU_SORT"
38 #define MSAE_MENU_ALIGN "MSAE_MENU_ALIGN"
39 #define MSAE_MENU_TREES "MSAE_MENU_TREES"
40 #define MSAE_MENU_STATISTICS "MSAE_MENU_STATISTICS"
41 #define MSAE_MENU_ADVANCED "MSAE_MENU_ADVANCED"
42 #define MSAE_MENU_LOAD "MSAE_MENU_LOAD_SEQ"
43 
44 #define MOBJECT_MIN_COLUMN_WIDTH 1
45 
46 #define MOBJECT_SETTINGS_COLOR_NUCL "color_nucl"
47 #define MOBJECT_SETTINGS_COLOR_AMINO "color_amino"
48 #define MOBJECT_SETTINGS_FONT_FAMILY "font_family"
49 #define MOBJECT_SETTINGS_FONT_SIZE "font_size"
50 #define MOBJECT_SETTINGS_FONT_ITALIC "font_italic"
51 #define MOBJECT_SETTINGS_FONT_BOLD "font_bold"
52 #define MOBJECT_SETTINGS_ZOOM_FACTOR "zoom_factor"
53 
54 #define MOBJECT_DEFAULT_FONT_FAMILY "Verdana"
55 #define MOBJECT_DEFAULT_FONT_SIZE 10
56 #define MOBJECT_DEFAULT_ZOOM_FACTOR 1.0
57 
58 class MaEditorWgt;
59 class MultipleAlignmentObject;
60 class MaEditorSelection;
61 class MaEditorSelectionController;
62 class MultipleAlignment;
63 class MaCollapseModel;
64 class MaModificationInfo;
65 
66 class SNPSettings {
67 public:
68     SNPSettings();
69     QPoint clickPoint;
70     qint64 seqId;
71     QVariantMap highlightSchemeSettings;
72 };
73 
74 /** Set of row ordering modes supported by MaEditor. */
75 enum class MaEditorRowOrderMode {
76     /**
77      * The default order of sequences in the MA: same as in the original source file.
78      * Note: there are no collapsible groups support in this mode.
79      */
80     Original,
81 
82     /**
83      * Rows are ordered by sequence content similarity.
84      * Sequences with the equal content are joined into collapsible groups.
85      * This mode is managed/supported internally by MA editor: MA editor automatically rebuilds groups when MA content changes.
86      * The order is not saved to the file and is kept in the view memory only.
87      * This mode allows to re-order read-only MA objects.
88      */
89     Sequence,
90 
91     /**
92      * Sequences are ordered by some external manager (e.g. tree-view) and can be re-ordered by user (e.g. drag & drop).
93      * The order is not saved to the file and is kept in the view memory only.
94      * This mode allows to re-order read-only MA objects.
95      */
96     Free
97 };
98 
99 class U2VIEW_EXPORT MaEditor : public GObjectView {
100     Q_OBJECT
101     friend class OpenSavedMaEditorTask;
102     friend class MaEditorState;
103 
104 public:
105     enum ResizeMode {
106         ResizeMode_FontAndContent,
107         ResizeMode_OnlyContent
108     };
109     static const float zoomMult;  // SANGER_TODO: should be dependable on the view
110 
111 public:
112     MaEditor(GObjectViewFactoryId factoryId, const QString &viewName, MultipleAlignmentObject *obj);
113 
114     virtual QVariantMap saveState();
115 
116     virtual Task *updateViewTask(const QString &stateName, const QVariantMap &stateData);
117 
118     virtual QString getSettingsRoot() const = 0;
119 
getMaObject()120     virtual MultipleAlignmentObject *getMaObject() const {
121         return maObject;
122     }
123 
124     QList<qint64> getMaRowIds() const;
125 
getUI()126     virtual MaEditorWgt *getUI() const {
127         return ui;
128     }
129 
getOptionsPanel()130     virtual OptionsPanel *getOptionsPanel() {
131         return optionsPanel;
132     }
133 
getFont()134     const QFont &getFont() const {
135         return font;
136     }
137 
getResizeMode()138     ResizeMode getResizeMode() const {
139         return resizeMode;
140     }
141 
142     int getAlignmentLen() const;
143 
144     int getNumSequences() const;
145 
146     bool isAlignmentEmpty() const;
147 
148     /* Returns current selection controller. */
149     virtual MaEditorSelectionController *getSelectionController() const = 0;
150 
151     /* Returns current selection. */
152     const MaEditorSelection &getSelection() const;
153 
154     virtual int getRowContentIndent(int rowId) const;
155     int getSequenceRowHeight() const;  // SANGER_TODO: order the methods
156 
157     int getColumnWidth() const;
158 
159     QVariantMap getHighlightingSettings(const QString &highlightingFactoryId) const;
160 
161     void saveHighlightingSettings(const QString &highlightingFactoryId, const QVariantMap &settingsMap = QVariantMap());
162 
getReferenceRowId()163     qint64 getReferenceRowId() const {
164         return snp.seqId;
165     }
166 
167     virtual QString getReferenceRowName() const = 0;
168 
169     virtual char getReferenceCharAt(int pos) const = 0;
170 
171     void setReference(qint64 sequenceId);
172 
173     void updateReference();
174 
175     /** Sets row ordering mode to 'Original' and resets collapse model to the original row order. */
176     void resetCollapseModel();
177 
exportHighlighted()178     void exportHighlighted() {
179         sl_exportHighlighted();
180     }
181 
182     /** Returns current cursor position. */
183     const QPoint &getCursorPosition() const;
184 
185     /** Sets new cursor position. Emits si_cursorPositionChanged() signal. */
186     void setCursorPosition(const QPoint &cursorPosition);
187 
188     /** Sets selection to the given view rows. */
189     virtual void selectRows(int firstViewRowIndex, int numberOfRows);
190 
191     /** Returns a unified bounding rect for a single sequence character for the given font. */
192     QRect getUnifiedSequenceFontCharRect(const QFont &sequenceFont) const;
193 
194     /** Returns active row ordering mode. See docs for 'MaEditorRowOrderMode' enum for details. */
195     MaEditorRowOrderMode getRowOrderMode() const;
196 
197     /**
198      * Updates currently active row order mode.
199      * This is a trivial method with no other actions/callbacks.
200      */
201     virtual void setRowOrderMode(MaEditorRowOrderMode mode);
202 
203     /** Returns collapse model instance. The returned value is never null. */
204     MaCollapseModel *getCollapseModel() const;
205 
206 signals:
207     void si_fontChanged(const QFont &f);
208     void si_zoomOperationPerformed(bool resizeModeChanged);
209     void si_referenceSeqChanged(qint64 referenceId);
210     void si_sizeChanged(int newHeight, bool isMinimumSize, bool isMaximumSize);
211     void si_completeUpdate();
212     void si_updateActions();
213     void si_cursorPositionChanged(const QPoint &cursorPosition);
214 
215 protected slots:
216     virtual void sl_onContextMenuRequested(const QPoint &pos) = 0;
217 
218     void sl_zoomIn();
219     void sl_zoomOut();
220     void sl_zoomToSelection();
221     void sl_resetZoom();
222 
223     void sl_saveAlignment();
224     void sl_saveAlignmentAs();
225     void sl_changeFont();
226 
227     void sl_lockedStateChanged();
228 
229     void sl_exportHighlighted();
230     void sl_onClearActionTriggered();
231 
232     /** The slot is called each time alignment is changed. By default calls 'updateActions'. */
233     virtual void sl_onAlignmentChanged(const MultipleAlignment &ma, const MaModificationInfo &modInfo);
234 
235     /** The slot is called each time selection is changed. By default calls 'updateActions'. */
236     virtual void sl_selectionChanged(const MaEditorSelection &ma, const MaEditorSelection &modInfo);
237 
238 private slots:
239     void sl_resetColumnWidthCache();
240 
241 protected:
242     virtual QWidget *createWidget() = 0;
243     virtual void initActions();
244     virtual void initZoom();
245     virtual void initFont();
246     void updateResizeMode();
247 
248     virtual void addCopyPasteMenu(QMenu *m);
249     virtual void addEditMenu(QMenu *m) = 0;
250     virtual void addExportMenu(QMenu *m);
251     void addLoadMenu(QMenu *m);
252     void addAlignMenu(QMenu *m);  // SANGER_TODO: should the align menu exist in MCA?
253 
254     void setFont(const QFont &f);
255 
256     /** Updates font metrics like fontPixelToPointSize, minimum-font-size. Called on every font update. */
257     void updateFontMetrics();
258 
259     void setFirstVisiblePosSeq(int firstPos, int firstSeq);
260     void setZoomFactor(double newZoomFactor);
261 
262     virtual void updateActions();
263 
264     MultipleAlignmentObject *maObject;
265     MaEditorWgt *ui;
266 
267     QFont font;
268     ResizeMode resizeMode;
269 
270     /** Minimum font size to render a sequence. Then zoomed-out below this value no sequence text is shown. */
271     int minimumFontPointSize;
272 
273     /**
274      * Maximum font size to render a sequence. Then zoomed-in above this value sequence text stops to grow.
275      * Note: since MA editor does not allow a cell size to grow beyond the size defined by the maximumFontPointSize
276      *  this value indirectly defines the maximum zoom level.
277      */
278     int maximumFontPointSize;
279 
280     SNPSettings snp;
281     double zoomFactor;
282     double fontPixelToPointSize;
283     mutable int cachedColumnWidth;
284 
285     /** Current cursor position: 'x' is offset in alignment (0...len) and 'y' is a sequence index in the aligment. */
286     QPoint cursorPosition;
287 
288     /** Active row ordering mode in the view. */
289     MaEditorRowOrderMode rowOrderMode;
290 
291     /** Collapse model instance. Created in the constructor and is never changed. */
292     MaCollapseModel *const collapseModel;
293 
294 public:
295     QAction *saveAlignmentAction;
296     QAction *saveAlignmentAsAction;
297     QAction *zoomInAction;
298     QAction *zoomOutAction;
299     QAction *zoomToSelectionAction;
300     QAction *showOverviewAction;
301     QAction *changeFontAction;
302     QAction *resetZoomAction;
303     QAction *exportHighlightedAction;
304 
305     /** Clears selection in normal mode or exits from editing mode in the edit mode. */
306     QAction *clearSelectionAction;
307 
308     QAction *copyConsensusAction;
309     QAction *copyConsensusWithGapsAction;
310 };
311 
312 }  // namespace U2
313 
314 #endif  // _U2_MA_EDITOR_H_
315