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 #include "ExportAlignmentViewItems.h"
23 
24 #include <QDir>
25 #include <QMainWindow>
26 
27 #include <U2Core/AppContext.h>
28 #include <U2Core/BaseDocumentFormats.h>
29 #include <U2Core/DNAAlphabet.h>
30 #include <U2Core/DNATranslation.h>
31 #include <U2Core/DocumentUtils.h>
32 #include <U2Core/GObjectTypes.h>
33 #include <U2Core/GObjectUtils.h>
34 #include <U2Core/GUrlUtils.h>
35 #include <U2Core/MultipleSequenceAlignmentObject.h>
36 #include <U2Core/QObjectScopedPointer.h>
37 #include <U2Core/U2SafePoints.h>
38 
39 #include <U2Formats/ExportTasks.h>
40 
41 #include <U2Gui/DialogUtils.h>
42 #include <U2Gui/GUIUtils.h>
43 
44 #include <U2View/MSAEditor.h>
45 #include <U2View/MaCollapseModel.h>
46 #include <U2View/MaEditorFactory.h>
47 #include <U2View/MaEditorSelection.h>
48 
49 #include "ExportMSA2MSADialog.h"
50 #include "ExportUtils.h"
51 
52 namespace U2 {
53 
54 //////////////////////////////////////////////////////////////////////////
55 // ExportAlignmentViewItemsController
56 
ExportAlignmentViewItemsController(QObject * p)57 ExportAlignmentViewItemsController::ExportAlignmentViewItemsController(QObject *p)
58     : GObjectViewWindowContext(p, MsaEditorFactory::ID) {
59 }
60 
initViewContext(GObjectView * v)61 void ExportAlignmentViewItemsController::initViewContext(GObjectView *v) {
62     MSAEditor *msaed = qobject_cast<MSAEditor *>(v);
63     SAFE_POINT(msaed != nullptr, "Invalid GObjectView", );
64     MSAExportContext *mc = new MSAExportContext(msaed);
65     addViewResource(msaed, mc);
66 }
67 
buildStaticOrContextMenu(GObjectView * v,QMenu * m)68 void ExportAlignmentViewItemsController::buildStaticOrContextMenu(GObjectView *v, QMenu *m) {
69     QList<QObject *> resources = viewResources.value(v);
70     assert(resources.size() == 1);
71     QObject *r = resources.first();
72     MSAExportContext *mc = qobject_cast<MSAExportContext *>(r);
73     assert(mc != nullptr);
74     mc->buildMenu(m);
75 }
76 
77 //////////////////////////////////////////////////////////////////////////
78 // MSA view context
79 
MSAExportContext(MSAEditor * e)80 MSAExportContext::MSAExportContext(MSAEditor *e)
81     : editor(e) {
82     translateMSAAction = new QAction(tr("Amino translation..."), this);
83     translateMSAAction->setObjectName("amino_translation_of_alignment_rows");
84     translateMSAAction->setEnabled(!e->isAlignmentEmpty());
85     connect(e->getMaObject(), SIGNAL(si_alignmentBecomesEmpty(bool)), translateMSAAction, SLOT(setDisabled(bool)));
86     connect(translateMSAAction, SIGNAL(triggered()), SLOT(sl_exportNucleicMsaToAmino()));
87 }
88 
updateActions()89 void MSAExportContext::updateActions() {
90     translateMSAAction->setEnabled(editor->getMaObject()->getAlphabet()->isNucleic() &&
91                                    !editor->isAlignmentEmpty());
92 }
93 
buildMenu(QMenu * m)94 void MSAExportContext::buildMenu(QMenu *m) {
95     QMenu *exportMenu = GUIUtils::findSubMenu(m, MSAE_MENU_EXPORT);
96     SAFE_POINT(exportMenu != nullptr, "exportMenu is not found", );
97     MultipleSequenceAlignmentObject *mObject = editor->getMaObject();
98     if (mObject->getAlphabet()->isNucleic()) {
99         exportMenu->addAction(translateMSAAction);
100     }
101 }
102 
sl_exportNucleicMsaToAmino()103 void MSAExportContext::sl_exportNucleicMsaToAmino() {
104     MultipleSequenceAlignmentObject *maObject = editor->getMaObject();
105     const MultipleSequenceAlignment &ma = maObject->getMultipleAlignment();
106     SAFE_POINT(ma->getAlphabet()->isNucleic(), "Alignment alphabet is not nucleic", );
107 
108     GUrl msaUrl = maObject->getDocument()->getURL();
109     QString defaultUrl = GUrlUtils::getNewLocalUrlByFormat(msaUrl, maObject->getGObjectName(), BaseDocumentFormats::CLUSTAL_ALN, "_transl");
110 
111     bool isWholeAlignmentMode = editor->getSelection().isEmpty();
112     QObjectScopedPointer<ExportMSA2MSADialog> d = new ExportMSA2MSADialog(defaultUrl,
113                                                                           BaseDocumentFormats::CLUSTAL_ALN,
114                                                                           isWholeAlignmentMode,
115                                                                           AppContext::getMainWindow()->getQMainWindow());
116     int rc = d->exec();
117     CHECK(!d.isNull() && rc != QDialog::Rejected, );
118 
119     DNATranslation *translationTable = AppContext::getDNATranslationRegistry()->lookupTranslation(d->translationTable);
120     const MaEditorSelection &selection = editor->getSelection();
121     U2Region columnRegion(0, editor->getAlignmentLen());
122     QList<qint64> rowIds = ma->getRowsIds();
123     if (!selection.isEmpty() && d->exportWholeAlignment) {
124         columnRegion = selection.getColumnRegion();
125         QList<int> maRowIndexes = editor->getCollapseModel()->getMaRowIndexesFromSelectionRects(selection.getRectList());
126         rowIds = ma->getRowIdsByRowIndexes(maRowIndexes);
127         SAFE_POINT(!rowIds.isEmpty(), "No rows to export!", );
128     }
129 
130     bool convertUnknowToGaps = d->unknownAmino == ExportMSA2MSADialog::UnknownAmino::Gap;
131     bool reverseComplement = d->translationFrame < 0;
132     int baseOffset = qAbs(d->translationFrame) - 1;
133     auto exportTask = ExportUtils::wrapExportTask(new ExportMSA2MSATask(ma,
134                                                                         rowIds,
135                                                                         columnRegion,
136                                                                         d->file,
137                                                                         translationTable,
138                                                                         d->formatId,
139                                                                         !d->includeGaps,
140                                                                         convertUnknowToGaps,
141                                                                         reverseComplement,
142                                                                         baseOffset),
143                                                   d->addToProjectFlag);
144     AppContext::getTaskScheduler()->registerTopLevelTask(exportTask);
145 }
146 
147 }  // namespace U2
148