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 <drivers/GTKeyboardDriver.h>
23 #include <drivers/GTMouseDriver.h>
24 #include <primitives/GTScrollBar.h>
25 #include <primitives/GTToolbar.h>
26 #include <primitives/GTWidget.h>
27 #include <utils/GTThread.h>
28
29 #include <QLabel>
30 #include <QTextDocument>
31
32 #include <U2Core/AppContext.h>
33 #include <U2Core/U2SafePoints.h>
34
35 #include <U2View/MSAEditorOffsetsView.h>
36 #include <U2View/MaEditorFactory.h>
37 #include <U2View/McaEditor.h>
38 #include <U2View/McaEditorConsensusArea.h>
39 #include <U2View/McaEditorNameList.h>
40 #include <U2View/McaEditorReferenceArea.h>
41 #include <U2View/McaEditorSequenceArea.h>
42 #include <U2View/RowHeightController.h>
43 #include <U2View/ScrollController.h>
44
45 #include "GTUtilsMcaEditor.h"
46 #include "GTUtilsMcaEditorSequenceArea.h"
47 #include "GTUtilsMdi.h"
48
49 namespace U2 {
50 using namespace HI;
51
52 #define GT_CLASS_NAME "GTUtilsMcaEditor"
53
54 #define GT_METHOD_NAME "getActiveMcaEditorWindow"
getActiveMcaEditorWindow(GUITestOpStatus & os)55 QWidget *GTUtilsMcaEditor::getActiveMcaEditorWindow(GUITestOpStatus &os) {
56 QWidget *widget = GTUtilsMdi::getActiveObjectViewWindow(os, McaEditorFactory::ID);
57 GTThread::waitForMainThread();
58 return widget;
59 }
60 #undef GT_METHOD_NAME
61
62 #define GT_METHOD_NAME "checkMcaEditorWindowIsActive"
checkMcaEditorWindowIsActive(GUITestOpStatus & os)63 void GTUtilsMcaEditor::checkMcaEditorWindowIsActive(GUITestOpStatus &os) {
64 getActiveMcaEditorWindow(os);
65 }
66 #undef GT_METHOD_NAME
67
68 #define GT_METHOD_NAME "getEditor"
getEditor(GUITestOpStatus & os)69 McaEditor *GTUtilsMcaEditor::getEditor(GUITestOpStatus &os) {
70 McaEditorWgt *editorUi = getEditorUi(os);
71 McaEditor *editor = editorUi->getEditor();
72 GT_CHECK_RESULT(editor != nullptr, "MCA Editor is NULL", nullptr);
73 return editor;
74 }
75 #undef GT_METHOD_NAME
76
77 #define GT_METHOD_NAME "getEditorUi"
getEditorUi(GUITestOpStatus & os)78 McaEditorWgt *GTUtilsMcaEditor::getEditorUi(GUITestOpStatus &os) {
79 checkMcaEditorWindowIsActive(os);
80 McaEditorWgt *mcaEditorWgt = nullptr;
81 // For some reason McaEditorWgt is not within normal widgets hierarchy (wrong parent?), so can't use GTWidget::findWidget here.
82 for (int time = 0; time < GT_OP_WAIT_MILLIS && mcaEditorWgt == nullptr; time += GT_OP_CHECK_MILLIS) {
83 GTGlobals::sleep(time > 0 ? GT_OP_CHECK_MILLIS : 0);
84 MainWindow *mainWindow = AppContext::getMainWindow();
85 QWidget *activeWindow = mainWindow == nullptr ? nullptr : mainWindow->getMDIManager()->getActiveWindow();
86 if (activeWindow == nullptr) {
87 continue;
88 }
89 mcaEditorWgt = activeWindow->findChild<McaEditorWgt *>();
90 }
91 GT_CHECK_RESULT(mcaEditorWgt != nullptr, "MCA Editor widget is NULL", nullptr);
92 return mcaEditorWgt;
93 }
94 #undef GT_METHOD_NAME
95
96 #define GT_METHOD_NAME "getReferenceLabel"
getReferenceLabel(GUITestOpStatus & os)97 QLabel *GTUtilsMcaEditor::getReferenceLabel(GUITestOpStatus &os) {
98 QWidget *referenceLabelContainerWidget = GTWidget::findExactWidget<QWidget *>(os, "reference label container widget", getEditorUi(os));
99 GT_CHECK_RESULT(nullptr != referenceLabelContainerWidget, "Reference label not found", nullptr);
100 return GTWidget::findExactWidget<QLabel *>(os, "", referenceLabelContainerWidget);
101 }
102 #undef GT_METHOD_NAME
103
104 #define GT_METHOD_NAME "getNameListArea"
getNameListArea(GUITestOpStatus & os)105 McaEditorNameList *GTUtilsMcaEditor::getNameListArea(GUITestOpStatus &os) {
106 return GTWidget::findExactWidget<McaEditorNameList *>(os, "mca_editor_name_list", getEditorUi(os));
107 }
108 #undef GT_METHOD_NAME
109
110 #define GT_METHOD_NAME "getSequenceArea"
getSequenceArea(GUITestOpStatus & os)111 McaEditorSequenceArea *GTUtilsMcaEditor::getSequenceArea(GUITestOpStatus &os) {
112 return GTWidget::findExactWidget<McaEditorSequenceArea *>(os, "mca_editor_sequence_area", getEditorUi(os));
113 }
114 #undef GT_METHOD_NAME
115
116 #define GT_METHOD_NAME "getConsensusArea"
getConsensusArea(GUITestOpStatus & os)117 McaEditorConsensusArea *GTUtilsMcaEditor::getConsensusArea(GUITestOpStatus &os) {
118 QWidget *activeWindow = getActiveMcaEditorWindow(os);
119 return GTWidget::findExactWidget<McaEditorConsensusArea *>(os, "consArea", activeWindow);
120 }
121 #undef GT_METHOD_NAME
122
123 #define GT_METHOD_NAME "getReferenceArea"
getReferenceArea(GUITestOpStatus & os)124 McaEditorReferenceArea *GTUtilsMcaEditor::getReferenceArea(GUITestOpStatus &os) {
125 QWidget *activeWindow = getActiveMcaEditorWindow(os);
126 return GTWidget::findExactWidget<McaEditorReferenceArea *>(os, "mca_editor_reference_area", activeWindow);
127 }
128 #undef GT_METHOD_NAME
129
130 #define GT_METHOD_NAME "getHorizontalScrollBar"
getHorizontalScrollBar(GUITestOpStatus & os)131 QScrollBar *GTUtilsMcaEditor::getHorizontalScrollBar(GUITestOpStatus &os) {
132 return GTWidget::findExactWidget<QScrollBar *>(os, "horizontal_sequence_scroll", getEditorUi(os));
133 }
134 #undef GT_METHOD_NAME
135
136 #define GT_METHOD_NAME "getVerticalScrollBar"
getVerticalScrollBar(GUITestOpStatus & os)137 QScrollBar *GTUtilsMcaEditor::getVerticalScrollBar(GUITestOpStatus &os) {
138 return GTWidget::findExactWidget<QScrollBar *>(os, "vertical_sequence_scroll", getEditorUi(os));
139 }
140 #undef GT_METHOD_NAME
141
142 #define GT_METHOD_NAME "getMcaRow"
getMcaRow(GUITestOpStatus & os,int rowNum)143 MultipleAlignmentRowData *GTUtilsMcaEditor::getMcaRow(GUITestOpStatus &os, int rowNum) {
144 McaEditor *mcaEditor = GTUtilsMcaEditor::getEditor(os);
145 MultipleChromatogramAlignmentObject *maObj = mcaEditor->getMaObject();
146 GT_CHECK_RESULT(maObj != nullptr, "MultipleChromatogramAlignmentObject not found", nullptr);
147
148 MultipleAlignmentRow row = maObj->getRow(rowNum);
149 return row.data();
150 }
151 #undef GT_METHOD_NAME
152
153 #define GT_METHOD_NAME "getOffsetAction"
getOffsetAction(GUITestOpStatus & os)154 QAction *GTUtilsMcaEditor::getOffsetAction(GUITestOpStatus &os) {
155 McaEditorWgt *editorWgt = GTUtilsMcaEditor::getEditorUi(os);
156 GT_CHECK_RESULT(editorWgt != nullptr, "McaEditorWgt not found", nullptr);
157
158 MSAEditorOffsetsViewController *offsetController = editorWgt->getOffsetsViewController();
159 GT_CHECK_RESULT(offsetController != nullptr, "MSAEditorOffsetsViewController is NULL", nullptr);
160 return offsetController->toggleColumnsViewAction;
161 }
162
163 #undef GT_METHOD_NAME
164
165 #define GT_METHOD_NAME "getReferenceLabelText"
getReferenceLabelText(GUITestOpStatus & os)166 QString GTUtilsMcaEditor::getReferenceLabelText(GUITestOpStatus &os) {
167 QLabel *referenceLabel = getReferenceLabel(os);
168 GT_CHECK_RESULT(nullptr != referenceLabel, "Reference label is NULL", "");
169 if (referenceLabel->textFormat() != Qt::PlainText) {
170 QTextDocument textDocument;
171 textDocument.setHtml(referenceLabel->text());
172 return textDocument.toPlainText();
173 } else {
174 return referenceLabel->text();
175 }
176 }
177 #undef GT_METHOD_NAME
178
179 #define GT_METHOD_NAME "getReadsCount"
getReadsCount(GUITestOpStatus & os)180 int GTUtilsMcaEditor::getReadsCount(GUITestOpStatus &os) {
181 QWidget *statusBar = GTWidget::findWidget(os, "mca_editor_status_bar", getEditorUi(os));
182 QLabel *readsCountLabel = GTWidget::findExactWidget<QLabel *>(os, "Line", statusBar);
183
184 QRegExp readsCounRegExp("Ln \\d+|\\- / (\\d+)");
185 readsCounRegExp.indexIn(readsCountLabel->text());
186 const QString totalReadsCountString = readsCounRegExp.cap(1);
187
188 bool isNumber = false;
189 const int totalReadsCount = totalReadsCountString.toInt(&isNumber);
190 GT_CHECK_RESULT(isNumber, QString("Can't convert the reads count string to number: %1").arg(totalReadsCountString), -1);
191
192 return totalReadsCount;
193 }
194 #undef GT_METHOD_NAME
195
196 #define GT_METHOD_NAME "getReadsNames"
getReadsNames(GUITestOpStatus & os)197 const QStringList GTUtilsMcaEditor::getReadsNames(GUITestOpStatus &os) {
198 return getEditor(os)->getMaObject()->getMultipleAlignment()->getRowNames();
199 }
200 #undef GT_METHOD_NAME
201
202 #define GT_METHOD_NAME "getDirectReadsNames"
getDirectReadsNames(GUITestOpStatus & os)203 const QStringList GTUtilsMcaEditor::getDirectReadsNames(GUITestOpStatus &os) {
204 QStringList directReadsNames;
205 MultipleChromatogramAlignmentObject *mcaObject = getEditor(os)->getMaObject();
206 const int rowsCount = mcaObject->getNumRows();
207 for (int i = 0; i < rowsCount; i++) {
208 if (!mcaObject->getMcaRow(i)->isReversed()) {
209 directReadsNames << mcaObject->getMcaRow(i)->getName();
210 }
211 }
212 return directReadsNames;
213 }
214 #undef GT_METHOD_NAME
215
216 #define GT_METHOD_NAME "getReverseComplementReadsNames"
getReverseComplementReadsNames(GUITestOpStatus & os)217 const QStringList GTUtilsMcaEditor::getReverseComplementReadsNames(GUITestOpStatus &os) {
218 QStringList reverseComplementedReadsNames;
219 MultipleChromatogramAlignmentObject *mcaObject = getEditor(os)->getMaObject();
220 const int rowsCount = mcaObject->getNumRows();
221 for (int i = 0; i < rowsCount; i++) {
222 if (mcaObject->getMcaRow(i)->isReversed()) {
223 reverseComplementedReadsNames << mcaObject->getMcaRow(i)->getName();
224 }
225 }
226 return reverseComplementedReadsNames;
227 }
228 #undef GT_METHOD_NAME
229
230 #define GT_METHOD_NAME "getReadNameRect"
getReadNameRect(GUITestOpStatus & os,const QString & readName)231 QRect GTUtilsMcaEditor::getReadNameRect(GUITestOpStatus &os, const QString &readName) {
232 McaEditorNameList *nameList = getNameListArea(os);
233 GT_CHECK_RESULT(nullptr != nameList, "McaEditorNameList not found", QRect());
234
235 const QStringList names = GTUtilsMcaEditorSequenceArea::getVisibleNames(os);
236 const int rowNumber = names.indexOf(readName);
237 GT_CHECK_RESULT(0 <= rowNumber, QString("Read '%1' not found").arg(readName), QRect());
238 return getReadNameRect(os, rowNumber);
239 }
240 #undef GT_METHOD_NAME
241
242 #define GT_METHOD_NAME "getReadNameRect"
getReadNameRect(GUITestOpStatus & os,int rowNumber)243 QRect GTUtilsMcaEditor::getReadNameRect(GUITestOpStatus &os, int rowNumber) {
244 Q_UNUSED(os);
245 GT_CHECK_RESULT(0 <= rowNumber, QString("Read '%1' not found").arg(rowNumber), QRect());
246
247 McaEditorNameList *nameList = getNameListArea(os);
248 GT_CHECK_RESULT(nullptr != nameList, "McaEditorNameList not found", QRect());
249
250 const U2Region rowScreenRange = getEditorUi(os)->getRowHeightController()->getScreenYRegionByViewRowIndex(rowNumber);
251 return QRect(nameList->mapToGlobal(QPoint(0, rowScreenRange.startPos)), nameList->mapToGlobal(QPoint(nameList->width(), rowScreenRange.endPos())));
252 }
253 #undef GT_METHOD_NAME
254
255 #define GT_METHOD_NAME "scrollToRead"
scrollToRead(GUITestOpStatus & os,const QString & readName)256 void GTUtilsMcaEditor::scrollToRead(GUITestOpStatus &os, const QString &readName) {
257 scrollToRead(os, readName2readNumber(os, readName));
258 }
259 #undef GT_METHOD_NAME
260
261 #define GT_METHOD_NAME "scrollToRead"
scrollToRead(GUITestOpStatus & os,int readNumber)262 void GTUtilsMcaEditor::scrollToRead(GUITestOpStatus &os, int readNumber) {
263 McaEditorWgt *mcaEditorWgt = getEditorUi(os);
264 const U2Region rowRange = mcaEditorWgt->getRowHeightController()->getGlobalYRegionByViewRowIndex(readNumber);
265 CHECK(!U2Region(mcaEditorWgt->getScrollController()->getScreenPosition().y(), getNameListArea(os)->height()).contains(rowRange), );
266 GTScrollBar::moveSliderWithMouseToValue(os, getVerticalScrollBar(os), rowRange.center() - mcaEditorWgt->getSequenceArea()->height() / 2);
267 }
268 #undef GT_METHOD_NAME
269
270 #define GT_METHOD_NAME "moveToReadName"
moveToReadName(GUITestOpStatus & os,const QString & readName)271 void GTUtilsMcaEditor::moveToReadName(GUITestOpStatus &os, const QString &readName) {
272 moveToReadName(os, readName2readNumber(os, readName));
273 }
274 #undef GT_METHOD_NAME
275
276 #define GT_METHOD_NAME "moveToReadName"
moveToReadName(GUITestOpStatus & os,int readNumber)277 void GTUtilsMcaEditor::moveToReadName(GUITestOpStatus &os, int readNumber) {
278 scrollToRead(os, readNumber);
279 const QRect readNameRect = getReadNameRect(os, readNumber);
280 GTMouseDriver::moveTo(readNameRect.center());
281 }
282 #undef GT_METHOD_NAME
283
284 #define GT_METHOD_NAME "clickReadName"
clickReadName(GUITestOpStatus & os,const QString & readName,Qt::MouseButton mouseButton)285 void GTUtilsMcaEditor::clickReadName(GUITestOpStatus &os, const QString &readName, Qt::MouseButton mouseButton) {
286 clickReadName(os, readName2readNumber(os, readName), mouseButton);
287 }
288 #undef GT_METHOD_NAME
289
290 #define GT_METHOD_NAME "clickReadName"
clickReadName(GUITestOpStatus & os,int readNumber,Qt::MouseButton mouseButton)291 void GTUtilsMcaEditor::clickReadName(GUITestOpStatus &os, int readNumber, Qt::MouseButton mouseButton) {
292 moveToReadName(os, readNumber);
293 GTMouseDriver::click(mouseButton);
294 }
295 #undef GT_METHOD_NAME
296
297 #define GT_METHOD_NAME "doubleClickReadName"
doubleClickReadName(GUITestOpStatus & os,int readIndex)298 void GTUtilsMcaEditor::doubleClickReadName(GUITestOpStatus &os, int readIndex) {
299 moveToReadName(os, readIndex);
300 GTMouseDriver::doubleClick();
301 }
302 #undef GT_METHOD_NAME
303
304 #define GT_METHOD_NAME "undo"
removeRead(GUITestOpStatus & os,const QString & readName)305 void GTUtilsMcaEditor::removeRead(GUITestOpStatus &os, const QString &readName) {
306 clickReadName(os, readName);
307 GTKeyboardDriver::keyClick(Qt::Key_Delete);
308 GTGlobals::sleep(500);
309 }
310 #undef GT_METHOD_NAME
311
312 #define GT_METHOD_NAME "undo"
undo(GUITestOpStatus & os)313 void GTUtilsMcaEditor::undo(GUITestOpStatus &os) {
314 GTWidget::click(os, GTToolbar::getWidgetForActionObjectName(os, GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI), "msa_action_undo"));
315 }
316 #undef GT_METHOD_NAME
317
318 #define GT_METHOD_NAME "redo"
redo(GUITestOpStatus & os)319 void GTUtilsMcaEditor::redo(GUITestOpStatus &os) {
320 GTWidget::click(os, GTToolbar::getWidgetForActionObjectName(os, GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI), "msa_action_redo"));
321 }
322 #undef GT_METHOD_NAME
323
324 #define GT_METHOD_NAME "zoomIn"
zoomIn(HI::GUITestOpStatus & os)325 void GTUtilsMcaEditor::zoomIn(HI::GUITestOpStatus &os) {
326 GTWidget::click(os, GTToolbar::getWidgetForActionObjectName(os, GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI), "Zoom In"));
327 }
328 #undef GT_METHOD_NAME
329
330 #define GT_METHOD_NAME "zoomOut"
zoomOut(HI::GUITestOpStatus & os)331 void GTUtilsMcaEditor::zoomOut(HI::GUITestOpStatus &os) {
332 GTWidget::click(os, GTToolbar::getWidgetForActionObjectName(os, GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI), "Zoom Out"));
333 }
334 #undef GT_METHOD_NAME
335
336 #define GT_METHOD_NAME "resetZoom"
resetZoom(HI::GUITestOpStatus & os)337 void GTUtilsMcaEditor::resetZoom(HI::GUITestOpStatus &os) {
338 GTWidget::click(os, GTToolbar::getWidgetForActionObjectName(os, GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI), "Reset Zoom"));
339 }
340 #undef GT_METHOD_NAME
341
342 #define GT_METHOD_NAME "isUndoEnabled"
isUndoEnabled(GUITestOpStatus & os)343 bool GTUtilsMcaEditor::isUndoEnabled(GUITestOpStatus &os) {
344 return GTToolbar::getWidgetForActionObjectName(os, GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI), "msa_action_undo")->isEnabled();
345 }
346 #undef GT_METHOD_NAME
347
348 #define GT_METHOD_NAME "isRedoEnabled"
isRedoEnabled(GUITestOpStatus & os)349 bool GTUtilsMcaEditor::isRedoEnabled(GUITestOpStatus &os) {
350 return GTToolbar::getWidgetForActionObjectName(os, GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI), "msa_action_redo")->isEnabled();
351 }
352 #undef GT_METHOD_NAME
353
354 #define GT_METHOD_NAME "toggleShowChromatogramsMode"
toggleShowChromatogramsMode(GUITestOpStatus & os)355 void GTUtilsMcaEditor::toggleShowChromatogramsMode(GUITestOpStatus &os) {
356 GTWidget::click(os, GTToolbar::getWidgetForActionTooltip(os, GTToolbar::getToolbar(os, MWTOOLBAR_ACTIVEMDI), "Show chromatograms"));
357 }
358 #undef GT_METHOD_NAME
359
360 #define GT_METHOD_NAME "readName2readNumber"
readName2readNumber(GUITestOpStatus & os,const QString & readName)361 int GTUtilsMcaEditor::readName2readNumber(GUITestOpStatus &os, const QString &readName) {
362 const QStringList names = GTUtilsMcaEditorSequenceArea::getVisibleNames(os);
363 const int rowNumber = names.indexOf(readName);
364 GT_CHECK_RESULT(0 <= rowNumber, QString("Read '%1' not found").arg(readName), -1);
365 return rowNumber;
366 }
367 #undef GT_METHOD_NAME
368
369 #undef GT_CLASS_NAME
370
371 } // namespace U2
372