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 "PairAlign.h"
23
24 #include <QMessageBox>
25 #include <QString>
26 #include <QStringList>
27
28 #include <U2Algorithm/AlignmentAlgorithmsRegistry.h>
29 #include <U2Algorithm/BuiltInDistanceAlgorithms.h>
30 #include <U2Algorithm/MSADistanceAlgorithm.h>
31 #include <U2Algorithm/MSADistanceAlgorithmRegistry.h>
32 #include <U2Algorithm/PairwiseAlignmentTask.h>
33
34 #include <U2Core/AppContext.h>
35 #include <U2Core/AppSettings.h>
36 #include <U2Core/BaseDocumentFormats.h>
37 #include <U2Core/DNAAlphabet.h>
38 #include <U2Core/GUrlUtils.h>
39 #include <U2Core/MultipleSequenceAlignmentObject.h>
40 #include <U2Core/Theme.h>
41 #include <U2Core/U2Alphabet.h>
42 #include <U2Core/U2DbiUtils.h>
43 #include <U2Core/U2Msa.h>
44 #include <U2Core/U2MsaDbi.h>
45 #include <U2Core/U2OpStatusUtils.h>
46 #include <U2Core/U2SafePoints.h>
47 #include <U2Core/U2SequenceDbi.h>
48 #include <U2Core/UserApplicationsSettings.h>
49
50 #include <U2Gui/SaveDocumentController.h>
51 #include <U2Gui/ShowHideSubgroupWidget.h>
52 #include <U2Gui/U2WidgetStateStorage.h>
53
54 #include <U2View/AlignmentAlgorithmGUIExtension.h>
55 #include <U2View/MSAEditor.h>
56 #include <U2View/MSAEditorSequenceArea.h>
57 #include <U2View/MaEditorNameList.h>
58
59 #include "ov_msa/view_rendering/MaEditorSelection.h"
60
61 #define BadAlphabetWarning 0
62 #define DuplicateSequenceWarning 1
63
getSequenceIdByRowId(U2::MSAEditor * msa,qint64 rowId,U2::U2OpStatus & os)64 inline U2::U2DataId getSequenceIdByRowId(U2::MSAEditor *msa, qint64 rowId, U2::U2OpStatus &os) {
65 const U2::MultipleSequenceAlignmentRow row = msa->getMaObject()->getMsa()->getMsaRowByRowId(rowId, os);
66 CHECK_OP(os, U2::U2DataId());
67 return row->getRowDbInfo().sequenceId;
68 }
69
70 namespace U2 {
71
PairAlign(MSAEditor * _msa)72 PairAlign::PairAlign(MSAEditor *_msa)
73 : msa(_msa), pairwiseAlignmentWidgetsSettings(_msa->getPairwiseAlignmentWidgetsSettings()),
74 distanceCalcTask(nullptr), settingsWidget(nullptr),
75 showHideSequenceWidget(nullptr), showHideSettingsWidget(nullptr), showHideOutputWidget(nullptr),
76 saveController(nullptr), savableTab(this, GObjectViewUtils::findViewByName(_msa->getName())),
77 showSequenceWidget(_msa->getPairwiseAlignmentWidgetsSettings()->showSequenceWidget),
78 showAlgorithmWidget(_msa->getPairwiseAlignmentWidgetsSettings()->showAlgorithmWidget),
79 showOutputWidget(_msa->getPairwiseAlignmentWidgetsSettings()->showOutputWidget),
80 firstSequenceSelectionOn(false), secondSequenceSelectionOn(false),
81 sequencesChanged(true), sequenceNamesIsOk(false), alphabetIsOk(false) {
82 SAFE_POINT(nullptr != msa, "MSA Editor is NULL.", );
83 SAFE_POINT(nullptr != pairwiseAlignmentWidgetsSettings, "pairwiseAlignmentWidgetsSettings is NULL.", );
84
85 setupUi(this);
86
87 firstSeqSelectorWC = new SequenceSelectorWidgetController(msa);
88 firstSeqSelectorWC->setObjectName("firstSeqSelectorWC");
89 secondSeqSelectorWC = new SequenceSelectorWidgetController(msa);
90 secondSeqSelectorWC->setObjectName("secondSeqSelectorWC");
91
92 firstSequenceLayout->addWidget(firstSeqSelectorWC);
93 secondSequenceLayout->addWidget(secondSeqSelectorWC);
94
95 initLayout();
96 initSaveController();
97 initParameters();
98
99 U2WidgetStateStorage::restoreWidgetState(savableTab);
100
101 connectSignals();
102
103 checkState();
104 }
105
initLayout()106 void PairAlign::initLayout() {
107 showHideSequenceWidget = new ShowHideSubgroupWidget("PA_SEQUENCES", tr("Sequences"), sequenceContainerWidget, showSequenceWidget);
108 showHideSettingsWidget = new ShowHideSubgroupWidget("PA_SETTINGS", tr("Algorithm settings"), settingsContainerWidget, showAlgorithmWidget);
109 showHideOutputWidget = new ShowHideSubgroupWidget("PA_OUTPUT", tr("Output settings"), outputContainerWidget, showOutputWidget);
110
111 mainLayout->insertWidget(0, showHideSequenceWidget);
112 mainLayout->insertWidget(1, showHideSettingsWidget);
113 mainLayout->insertWidget(2, showHideOutputWidget);
114 }
115
isValidSequenceId(qint64 sequenceId) const116 bool PairAlign::isValidSequenceId(qint64 sequenceId) const {
117 return msa->getMaObject()->getRowPosById(sequenceId) >= 0;
118 }
119
initParameters()120 void PairAlign::initParameters() {
121 const MaEditorSelection &selection = msa->getSelection();
122 QList<int> selectedViewRowIndexes = selection.getSelectedRowIndexes();
123 if (selectedViewRowIndexes.size() == 2) {
124 qint64 firstRowId = msa->getRowByViewRowIndex(selectedViewRowIndexes[0])->getRowId();
125 firstSeqSelectorWC->setSequenceId(firstRowId);
126 qint64 secondRowId = msa->getRowByViewRowIndex(selectedViewRowIndexes[1])->getRowId();
127 secondSeqSelectorWC->setSequenceId(secondRowId);
128 } else {
129 if (isValidSequenceId(pairwiseAlignmentWidgetsSettings->firstSequenceId)) {
130 firstSeqSelectorWC->setSequenceId(pairwiseAlignmentWidgetsSettings->firstSequenceId);
131 }
132 if (isValidSequenceId(pairwiseAlignmentWidgetsSettings->secondSequenceId)) {
133 secondSeqSelectorWC->setSequenceId(pairwiseAlignmentWidgetsSettings->secondSequenceId);
134 }
135 }
136
137 inNewWindowCheckBox->setChecked(pairwiseAlignmentWidgetsSettings->inNewWindow);
138
139 QString outputFileName = pairwiseAlignmentWidgetsSettings->resultFileName;
140 if (outputFileName.isEmpty()) {
141 saveController->setPath(getDefaultFilePath()); // controller will roll file name here
142 } else {
143 outputFileLineEdit->setText(outputFileName);
144 }
145 outputFileLineEdit->setEnabled(inNewWindowCheckBox->isChecked());
146 outputFileSelectButton->setEnabled(inNewWindowCheckBox->isChecked());
147
148 canDoAlign = false;
149
150 AlignmentAlgorithmsRegistry *par = AppContext::getAlignmentAlgorithmsRegistry();
151 SAFE_POINT(par != nullptr, "AlignmentAlgorithmsRegistry is NULL.", );
152 QStringList algList = par->getAvailableAlgorithmIds(PairwiseAlignment);
153 algorithmListComboBox->setEnabled(algList.length() > 0);
154 CHECK(algList.length() > 0, );
155 algorithmListComboBox->addItems(algList);
156 if (pairwiseAlignmentWidgetsSettings->algorithmName.isEmpty()) {
157 pairwiseAlignmentWidgetsSettings->algorithmName = algList[0];
158 } else {
159 int index = algorithmListComboBox->findText(pairwiseAlignmentWidgetsSettings->algorithmName);
160 if (index != -1) {
161 algorithmListComboBox->setCurrentIndex(index);
162 } else {
163 pairwiseAlignmentWidgetsSettings->algorithmName = algList[0];
164 }
165 }
166 sl_algorithmSelected(pairwiseAlignmentWidgetsSettings->algorithmName);
167
168 lblMessage->setStyleSheet("color: " + Theme::errorColorLabelStr() + ";"
169 "font: bold;"
170 "padding-top: 15px;");
171 sl_alignmentChanged();
172 }
173
updateWarningMessage(int type)174 void PairAlign::updateWarningMessage(int type) {
175 QString text;
176 switch (type) {
177 case DuplicateSequenceWarning:
178 text = tr("Please select 2 different sequences to align");
179 break;
180 case BadAlphabetWarning: {
181 QString alphabetName = msa->getMaObject()->getAlphabet()->getName();
182 text = tr("Pairwise alignment is not available for alignments with \"%1\" alphabet.").arg(alphabetName);
183 break;
184 }
185 default:
186 text = tr("Unexpected error");
187 }
188 lblMessage->setText(text);
189 }
190
initSaveController()191 void PairAlign::initSaveController() {
192 SaveDocumentControllerConfig config;
193 config.defaultFormatId = BaseDocumentFormats::CLUSTAL_ALN;
194 config.fileDialogButton = outputFileSelectButton;
195 config.fileNameEdit = outputFileLineEdit;
196 config.parentWidget = this;
197 config.saveTitle = tr("Save file");
198
199 const QList<DocumentFormatId> formats = QList<DocumentFormatId>() << BaseDocumentFormats::CLUSTAL_ALN;
200
201 saveController = new SaveDocumentController(config, formats, this);
202 saveController->setPath(getDefaultFilePath()); // controller will roll file name here
203 }
204
getDefaultFilePath()205 QString PairAlign::getDefaultFilePath() {
206 return GUrlUtils::getDefaultDataPath() + "/" + PairwiseAlignmentTaskSettings::DEFAULT_NAME;
207 }
208
connectSignals()209 void PairAlign::connectSignals() {
210 connect(showHideSequenceWidget, SIGNAL(si_subgroupStateChanged(QString)), SLOT(sl_subwidgetStateChanged(QString)));
211 connect(showHideSettingsWidget, SIGNAL(si_subgroupStateChanged(QString)), SLOT(sl_subwidgetStateChanged(QString)));
212 connect(showHideOutputWidget, SIGNAL(si_subgroupStateChanged(QString)), SLOT(sl_subwidgetStateChanged(QString)));
213 connect(algorithmListComboBox, SIGNAL(currentIndexChanged(QString)), SLOT(sl_algorithmSelected(QString)));
214 connect(inNewWindowCheckBox, SIGNAL(clicked(bool)), SLOT(sl_inNewWindowCheckBoxChangeState(bool)));
215 connect(alignButton, SIGNAL(clicked()), SLOT(sl_alignButtonPressed()));
216 connect(outputFileSelectButton, SIGNAL(clicked()), SLOT(sl_checkState()));
217 connect(outputFileLineEdit, SIGNAL(textChanged(QString)), SLOT(sl_outputFileChanged()));
218
219 connect(firstSeqSelectorWC, SIGNAL(si_selectionChanged()), SLOT(sl_selectorTextChanged()));
220 connect(secondSeqSelectorWC, SIGNAL(si_selectionChanged()), SLOT(sl_selectorTextChanged()));
221 connect(msa->getMaObject(), SIGNAL(si_lockedStateChanged()), SLOT(sl_checkState()));
222 connect(msa->getMaObject(), SIGNAL(si_alignmentChanged(const MultipleAlignment &, const MaModificationInfo &)), SLOT(sl_alignmentChanged()));
223 }
224
sl_checkState()225 void PairAlign::sl_checkState() {
226 checkState();
227 }
228
sl_alignmentChanged()229 void PairAlign::sl_alignmentChanged() {
230 const DNAAlphabet *dnaAlphabet = msa->getMaObject()->getAlphabet();
231 SAFE_POINT(dnaAlphabet != nullptr, "Alignment alphabet is not defined.", );
232
233 pairwiseAlignmentWidgetsSettings->customSettings.insert("alphabet", dnaAlphabet->getId());
234
235 QString curAlgorithmId = pairwiseAlignmentWidgetsSettings->algorithmName;
236 AlignmentAlgorithm *alg = getAlgorithmById(curAlgorithmId);
237 SAFE_POINT(alg != nullptr, QString("Algorithm %1 not found.").arg(curAlgorithmId), );
238 alphabetIsOk = alg->checkAlphabet(dnaAlphabet);
239
240 if (settingsWidget != nullptr) {
241 settingsWidget->updateWidget();
242 }
243 checkState();
244 }
245
checkState()246 void PairAlign::checkState() {
247 SAFE_POINT((firstSequenceSelectionOn && secondSequenceSelectionOn) == false,
248 tr("Either addFirstButton and addSecondButton are pressed. Sequence selection mode works incorrect."), );
249
250 sequenceNamesIsOk = checkSequenceNames();
251
252 outputFileLineEdit->setEnabled(inNewWindowCheckBox->isChecked());
253 outputFileSelectButton->setEnabled(inNewWindowCheckBox->isChecked());
254
255 if (sequencesChanged) {
256 updatePercentOfSimilarity();
257 }
258
259 qint64 firstSequenceId = firstSeqSelectorWC->sequenceId();
260 qint64 secondSequenceId = secondSeqSelectorWC->sequenceId();
261 bool sameSequenceInBothSelectors = firstSequenceId == secondSequenceId && firstSequenceId != U2MsaRow::INVALID_ROW_ID;
262 if (!alphabetIsOk) {
263 updateWarningMessage(BadAlphabetWarning);
264 } else if (sameSequenceInBothSelectors) {
265 updateWarningMessage(DuplicateSequenceWarning);
266 }
267 lblMessage->setVisible(!alphabetIsOk || sameSequenceInBothSelectors);
268
269 showHideSettingsWidget->setEnabled(alphabetIsOk);
270 showHideOutputWidget->setEnabled(alphabetIsOk);
271
272 bool readOnly = msa->getMaObject()->isStateLocked();
273 canDoAlign = ((U2MsaRow::INVALID_ROW_ID != firstSequenceId) && (U2MsaRow::INVALID_ROW_ID != secondSequenceId) && (firstSequenceId != secondSequenceId) && sequenceNamesIsOk && alphabetIsOk && (!readOnly || inNewWindowCheckBox->isChecked()));
274
275 alignButton->setEnabled(canDoAlign);
276
277 pairwiseAlignmentWidgetsSettings->firstSequenceId = firstSequenceId;
278 pairwiseAlignmentWidgetsSettings->secondSequenceId = secondSequenceId;
279 pairwiseAlignmentWidgetsSettings->algorithmName = algorithmListComboBox->currentText();
280 pairwiseAlignmentWidgetsSettings->inNewWindow = inNewWindowCheckBox->isChecked();
281 pairwiseAlignmentWidgetsSettings->resultFileName = saveController->getSaveFileName();
282 pairwiseAlignmentWidgetsSettings->showSequenceWidget = showSequenceWidget;
283 pairwiseAlignmentWidgetsSettings->showAlgorithmWidget = showAlgorithmWidget;
284 pairwiseAlignmentWidgetsSettings->showOutputWidget = showOutputWidget;
285 pairwiseAlignmentWidgetsSettings->sequenceSelectionModeOn = firstSequenceSelectionOn || secondSequenceSelectionOn;
286 }
287
updatePercentOfSimilarity()288 void PairAlign::updatePercentOfSimilarity() {
289 similarityValueLabel->setText(tr("Not defined"));
290 similarityWidget->setVisible(false);
291 sequencesChanged = false;
292 if (!sequenceNamesIsOk) {
293 return;
294 }
295
296 MSADistanceAlgorithmRegistry *distanceReg = AppContext::getMSADistanceAlgorithmRegistry();
297 SAFE_POINT(distanceReg != nullptr, "MSADistanceAlgorithmRegistry is NULL.", );
298 MSADistanceAlgorithmFactory *distanceFactory = distanceReg->getAlgorithmFactory(BuiltInDistanceAlgorithms::SIMILARITY_ALGO);
299 SAFE_POINT(distanceFactory != nullptr, QString("%1 algorithm factory not found.").arg(BuiltInDistanceAlgorithms::SIMILARITY_ALGO), );
300
301 U2OpStatusImpl os;
302 MultipleSequenceAlignment ma;
303 const MultipleSequenceAlignment currentAlignment = msa->getMaObject()->getMultipleAlignment();
304 ma->addRow(firstSeqSelectorWC->text(), currentAlignment->getMsaRowByRowId(firstSeqSelectorWC->sequenceId(), os)->getData(), -1);
305 ma->addRow(secondSeqSelectorWC->text(), currentAlignment->getMsaRowByRowId(secondSeqSelectorWC->sequenceId(), os)->getData(), -1);
306 distanceCalcTask = distanceFactory->createAlgorithm(ma);
307 distanceCalcTask->setExcludeGaps(true);
308 connect(distanceCalcTask, SIGNAL(si_stateChanged()), SLOT(sl_distanceCalculated()));
309 AppContext::getTaskScheduler()->registerTopLevelTask(distanceCalcTask);
310 }
311
checkSequenceNames()312 bool PairAlign::checkSequenceNames() {
313 QList<qint64> rowIds = msa->getMaObject()->getMultipleAlignment()->getRowsIds();
314 return (rowIds.contains(firstSeqSelectorWC->sequenceId()) && rowIds.contains(secondSeqSelectorWC->sequenceId()));
315 }
316
getAlgorithmById(const QString & algorithmId)317 AlignmentAlgorithm *PairAlign::getAlgorithmById(const QString &algorithmId) {
318 AlignmentAlgorithmsRegistry *par = AppContext::getAlignmentAlgorithmsRegistry();
319 SAFE_POINT(par != nullptr, "AlignmentAlgorithmsRegistry is NULL.", nullptr);
320 return par->getAlgorithm(algorithmId);
321 }
322
sl_algorithmSelected(const QString & algorithmName)323 void PairAlign::sl_algorithmSelected(const QString &algorithmName) {
324 if (settingsWidget != nullptr) {
325 delete settingsWidget;
326 settingsWidget = nullptr;
327 }
328
329 AlignmentAlgorithm *alg = getAlgorithmById(algorithmName);
330 SAFE_POINT(alg != nullptr, QString("Algorithm %1 not found.").arg(algorithmName), );
331 QString firstAlgorithmRealization = alg->getRealizationsList().first();
332 alphabetIsOk = alg->checkAlphabet(msa->getMaObject()->getAlphabet());
333
334 AlignmentAlgorithmGUIExtensionFactory *algGUIFactory = alg->getGUIExtFactory(firstAlgorithmRealization);
335 SAFE_POINT(algGUIFactory != nullptr, QString("Algorithm %1 GUI factory not found.").arg(firstAlgorithmRealization), );
336 settingsWidget = algGUIFactory->createMainWidget(this, &pairwiseAlignmentWidgetsSettings->customSettings);
337 connect(msa, SIGNAL(destroyed()), settingsWidget, SLOT(sl_externSettingsInvalide()));
338 settingsContainerWidgetLayout->addWidget(settingsWidget);
339
340 checkState();
341 }
342
sl_subwidgetStateChanged(const QString & id)343 void PairAlign::sl_subwidgetStateChanged(const QString &id) {
344 if (id == "PA_SEQUENCES") {
345 showSequenceWidget = showHideSequenceWidget->isSubgroupOpened();
346 }
347 if (id == "PA_SETTINGS") {
348 showAlgorithmWidget = showHideSettingsWidget->isSubgroupOpened();
349 }
350 if (id == "PA_OUTPUT") {
351 showOutputWidget = showHideOutputWidget->isSubgroupOpened();
352 }
353 checkState();
354 }
355
sl_inNewWindowCheckBoxChangeState(bool newState)356 void PairAlign::sl_inNewWindowCheckBoxChangeState(bool newState) {
357 Q_UNUSED(newState);
358 checkState();
359 }
360
sl_alignButtonPressed()361 void PairAlign::sl_alignButtonPressed() {
362 firstSequenceSelectionOn = false;
363 secondSequenceSelectionOn = false;
364 checkState();
365 SAFE_POINT(canDoAlign, "Invalid state of PairAlign options panel widget. startAlignButton is not disabled.", );
366
367 U2OpStatus2Log os;
368 U2EntityRef msaRef = msa->getMaObject()->getEntityRef();
369 DbiConnection con(msaRef.dbiRef, os);
370 CHECK_OP(os, );
371
372 U2DataId firstSeqId = getSequenceIdByRowId(msa, pairwiseAlignmentWidgetsSettings->firstSequenceId, os);
373 CHECK_OP(os, );
374 U2EntityRef firstSequenceRef = U2EntityRef(msaRef.dbiRef, firstSeqId);
375
376 U2DataId secondSeqId = getSequenceIdByRowId(msa, pairwiseAlignmentWidgetsSettings->secondSequenceId, os);
377 CHECK_OP(os, );
378 U2EntityRef secondSequenceRef = U2EntityRef(msaRef.dbiRef, secondSeqId);
379
380 PairwiseAlignmentTaskSettings settings;
381 settings.algorithmId = algorithmListComboBox->currentText();
382
383 if (!saveController->getSaveFileName().isEmpty()) {
384 settings.resultFileName = GUrl(saveController->getSaveFileName());
385 } else {
386 settings.resultFileName = GUrl(AppContext::getAppSettings()->getUserAppsSettings()->getCurrentProcessTemporaryDirPath() +
387 "/" + PairwiseAlignmentTaskSettings::DEFAULT_NAME);
388 }
389 GUrlUtils::validateLocalFileUrl(settings.resultFileName, os);
390 if (os.hasError()) {
391 QMessageBox::warning(this, tr("Error"), tr("Please, change the output file.") + "\n" + os.getError());
392 outputFileLineEdit->setFocus(Qt::MouseFocusReason);
393 return;
394 }
395
396 settings.inNewWindow = inNewWindowCheckBox->isChecked();
397 settings.msaRef = msaRef;
398 settings.alphabet = U2AlphabetId(msa->getMaObject()->getAlphabet()->getId());
399 settings.firstSequenceRef = firstSequenceRef;
400 settings.secondSequenceRef = secondSequenceRef;
401 settingsWidget->getAlignmentAlgorithmCustomSettings(true);
402 settings.appendCustomSettings(pairwiseAlignmentWidgetsSettings->customSettings);
403 settings.convertCustomSettings();
404
405 if (!pairwiseAlignmentWidgetsSettings->pairwiseAlignmentTask.isNull()) {
406 disconnect(this, SLOT(sl_alignComplete()));
407 pairwiseAlignmentWidgetsSettings->pairwiseAlignmentTask->cancel();
408 pairwiseAlignmentWidgetsSettings->pairwiseAlignmentTask.clear();
409 }
410
411 AlignmentAlgorithmsRegistry *par = AppContext::getAlignmentAlgorithmsRegistry();
412 SAFE_POINT(par != nullptr, "AlignmentAlgorithmsRegistry is NULL.", );
413 AbstractAlignmentTaskFactory *factory = par->getAlgorithm(settings.algorithmId)->getFactory(settings.realizationName);
414 SAFE_POINT(factory != nullptr, QString("Task factory for algorithm %1, realization %2 not found.").arg(settings.algorithmId, settings.realizationName), );
415
416 PairwiseAlignmentTask *task = qobject_cast<PairwiseAlignmentTask *>(factory->getTaskInstance(&settings));
417 SAFE_POINT(task != nullptr, "Task is null!", );
418 connect(task, SIGNAL(si_stateChanged()), SLOT(sl_alignComplete()));
419 pairwiseAlignmentWidgetsSettings->pairwiseAlignmentTask = task;
420 AppContext::getTaskScheduler()->registerTopLevelTask(task);
421
422 con.close(os);
423 checkState();
424 }
425
sl_outputFileChanged()426 void PairAlign::sl_outputFileChanged() {
427 if (saveController->getSaveFileName().isEmpty()) {
428 saveController->setPath(getDefaultFilePath());
429 }
430 checkState();
431 }
432
sl_distanceCalculated()433 void PairAlign::sl_distanceCalculated() {
434 if (distanceCalcTask == nullptr) {
435 return;
436 }
437 if (distanceCalcTask->isFinished()) {
438 const MSADistanceMatrix &distanceMatrix = distanceCalcTask->getMatrix();
439 similarityValueLabel->setText(QString::number(distanceMatrix.getSimilarity(0, 1, true)) + "%");
440 similarityWidget->setVisible(true);
441 distanceCalcTask = nullptr;
442 }
443 }
444
sl_alignComplete()445 void PairAlign::sl_alignComplete() {
446 CHECK(pairwiseAlignmentWidgetsSettings->pairwiseAlignmentTask == sender(), );
447 SAFE_POINT(!pairwiseAlignmentWidgetsSettings->pairwiseAlignmentTask.isNull(), "Can't process an unexpected align task", );
448 if (pairwiseAlignmentWidgetsSettings->pairwiseAlignmentTask->isFinished()) {
449 if (!inNewWindowCheckBox->isChecked()) {
450 MaModificationInfo mi;
451 mi.rowListChanged = false;
452 mi.modifiedRowIds.append(pairwiseAlignmentWidgetsSettings->firstSequenceId);
453 mi.modifiedRowIds.append(pairwiseAlignmentWidgetsSettings->secondSequenceId);
454 msa->getMaObject()->updateCachedMultipleAlignment(mi);
455 }
456 pairwiseAlignmentWidgetsSettings->pairwiseAlignmentTask.clear();
457 }
458 checkState();
459 }
460
sl_selectorTextChanged()461 void PairAlign::sl_selectorTextChanged() {
462 sequencesChanged = true;
463 checkState();
464 }
465
466 } // namespace U2
467