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/GTMouseDriver.h>
23 #include <math.h>
24 #include <primitives/GTWidget.h>
25 #include <utils/GTThread.h>
26
27 #include <QGraphicsItem>
28
29 #include <U2Core/U2SafePoints.h>
30
31 #include <U2View/GraphicsButtonItem.h>
32 #include <U2View/GraphicsRectangularBranchItem.h>
33
34 #include "GTUtilsMdi.h"
35 #include "GTUtilsPhyTree.h"
36
37 namespace U2 {
38 using namespace HI;
39
40 #define GT_CLASS_NAME "GTUtilsPhyTree"
41
42 #define GT_METHOD_NAME "getNodes"
getNodes(HI::GUITestOpStatus & os)43 QList<GraphicsButtonItem *> GTUtilsPhyTree::getNodes(HI::GUITestOpStatus &os) {
44 QList<GraphicsButtonItem *> result;
45 QGraphicsView *treeView = qobject_cast<QGraphicsView *>(GTWidget::findWidget(os, "treeView"));
46 GT_CHECK_RESULT(treeView, "treeView not found", result);
47 const QList<QGraphicsItem *> itemList = treeView->scene()->items();
48 for (QGraphicsItem *item : qAsConst(itemList)) {
49 auto nodeItem = dynamic_cast<GraphicsButtonItem *>(item);
50 if (nodeItem != nullptr) {
51 result.append(nodeItem);
52 }
53 }
54 return result;
55 }
56 #undef GT_METHOD_NAME
57
58 #define GT_METHOD_NAME "getSelectedNodes"
getSelectedNodes(HI::GUITestOpStatus & os)59 QList<GraphicsButtonItem *> GTUtilsPhyTree::getSelectedNodes(HI::GUITestOpStatus &os) {
60 QList<GraphicsButtonItem *> nodes = getNodes(os);
61 QList<GraphicsButtonItem *> selectedNodes;
62 for (auto node : qAsConst(nodes)) {
63 if (node->isNodeSelected()) {
64 selectedNodes << node;
65 }
66 }
67 return selectedNodes;
68 }
69 #undef GT_METHOD_NAME
70
71 #define GT_METHOD_NAME "getUnselectedNodes"
getUnselectedNodes(HI::GUITestOpStatus & os)72 QList<GraphicsButtonItem *> GTUtilsPhyTree::getUnselectedNodes(HI::GUITestOpStatus &os) {
73 QList<GraphicsButtonItem *> nodes = getNodes(os);
74 QList<GraphicsButtonItem *> unselectedNodes;
75 for (auto node : qAsConst(nodes)) {
76 if (node->isNodeSelected()) {
77 unselectedNodes << node;
78 }
79 }
80 return unselectedNodes;
81 }
82 #undef GT_METHOD_NAME
83
84 #define GT_METHOD_NAME "getLabels"
getLabels(HI::GUITestOpStatus & os,QGraphicsView * treeView)85 QList<QGraphicsSimpleTextItem *> GTUtilsPhyTree::getLabels(HI::GUITestOpStatus &os, QGraphicsView *treeView) {
86 QList<QGraphicsSimpleTextItem *> result;
87 if (treeView == nullptr) {
88 treeView = qobject_cast<QGraphicsView *>(GTWidget::findWidget(os, "treeView"));
89 }
90 GT_CHECK_RESULT(treeView, "treeView not found", result);
91 QList<QGraphicsItem *> list = treeView->scene()->items();
92
93 foreach (QGraphicsItem *item, list) {
94 QGraphicsSimpleTextItem *textItem = qgraphicsitem_cast<QGraphicsSimpleTextItem *>(item);
95 if (textItem) {
96 bool ok;
97 QString s = textItem->text();
98 s.toDouble(&ok);
99 if (!ok) {
100 result << textItem;
101 }
102 }
103 }
104 return result;
105 }
106 #undef GT_METHOD_NAME
107
getVisibleLabels(HI::GUITestOpStatus & os,QGraphicsView * treeView)108 QList<QGraphicsSimpleTextItem *> GTUtilsPhyTree::getVisibleLabels(HI::GUITestOpStatus &os, QGraphicsView *treeView) {
109 QList<QGraphicsSimpleTextItem *> result;
110 foreach (QGraphicsSimpleTextItem *item, getLabels(os, treeView)) {
111 if (item->isVisible() && !item->text().isEmpty()) {
112 result << item;
113 }
114 }
115 return result;
116 }
117
118 #define GT_METHOD_NAME "getDistances"
getDistances(HI::GUITestOpStatus & os,QGraphicsView * treeView)119 QList<QGraphicsSimpleTextItem *> GTUtilsPhyTree::getDistances(HI::GUITestOpStatus &os, QGraphicsView *treeView) {
120 QList<QGraphicsSimpleTextItem *> result;
121 if (treeView == nullptr) {
122 treeView = qobject_cast<QGraphicsView *>(GTWidget::findWidget(os, "treeView"));
123 }
124 GT_CHECK_RESULT(treeView, "treeView not found", result);
125 QList<QGraphicsItem *> list = treeView->scene()->items();
126
127 foreach (QGraphicsItem *item, list) {
128 QGraphicsSimpleTextItem *textItem = qgraphicsitem_cast<QGraphicsSimpleTextItem *>(item);
129 if (textItem) {
130 bool ok;
131 textItem->text().toDouble(&ok);
132 if (ok) {
133 result << textItem;
134 }
135 }
136 }
137 return result;
138 }
139 #undef GT_METHOD_NAME
140
141 #define GT_METHOD_NAME "getVisibleDistances"
getVisibleDistances(HI::GUITestOpStatus & os,QGraphicsView * treeView)142 QList<QGraphicsSimpleTextItem *> GTUtilsPhyTree::getVisibleDistances(HI::GUITestOpStatus &os, QGraphicsView *treeView) {
143 QList<QGraphicsSimpleTextItem *> result;
144 const QList<QGraphicsSimpleTextItem *> textItemList = getDistances(os, treeView);
145 for (QGraphicsSimpleTextItem *item : qAsConst(textItemList)) {
146 if (item->isVisible()) {
147 result << item;
148 }
149 }
150 return result;
151 }
152 #undef GT_METHOD_NAME
153
154 #define GT_METHOD_NAME "getDistancesValues"
getDistancesValues(HI::GUITestOpStatus & os)155 QList<double> GTUtilsPhyTree::getDistancesValues(HI::GUITestOpStatus &os) {
156 QList<double> result;
157 QList<QGraphicsSimpleTextItem *> distList = getDistances(os);
158
159 foreach (QGraphicsSimpleTextItem *item, distList) {
160 bool ok;
161 QString s = item->text();
162 double d = s.toDouble(&ok);
163 if (ok) {
164 result << d;
165 }
166 }
167
168 return result;
169 }
170 #undef GT_METHOD_NAME
171
172 #define GT_METHOD_NAME "getLabelsText"
getLabelsText(HI::GUITestOpStatus & os)173 QStringList GTUtilsPhyTree::getLabelsText(HI::GUITestOpStatus &os) {
174 QStringList result;
175 QList<QGraphicsSimpleTextItem *> labelList = getLabels(os);
176
177 foreach (QGraphicsSimpleTextItem *item, labelList) {
178 result << item->text();
179 }
180
181 return result;
182 }
183 #undef GT_METHOD_NAME
184
185 #define GT_METHOD_NAME "getGlobalCenterCoord"
getGlobalCenterCoord(HI::GUITestOpStatus & os,QGraphicsItem * item)186 QPoint GTUtilsPhyTree::getGlobalCenterCoord(HI::GUITestOpStatus &os, QGraphicsItem *item) {
187 QGraphicsView *treeView = qobject_cast<QGraphicsView *>(GTWidget::findWidget(os, "treeView"));
188 GT_CHECK_RESULT(treeView, "treeView not found", QPoint());
189
190 QPointF sceneCoord = item->mapToScene(item->boundingRect().topLeft());
191 QPoint viewCord = treeView->mapFromScene(sceneCoord);
192 QPoint globalCoord = treeView->mapToGlobal(viewCord);
193 globalCoord += QPoint(item->boundingRect().width() / 2, item->boundingRect().height() / 2);
194
195 return globalCoord;
196 }
197 #undef GT_METHOD_NAME
198
199 #define GT_METHOD_NAME "clickNode"
clickNode(HI::GUITestOpStatus & os,GraphicsButtonItem * node)200 void GTUtilsPhyTree::clickNode(HI::GUITestOpStatus &os, GraphicsButtonItem *node) {
201 GT_CHECK(node != nullptr, "Node to click is NULL");
202 node->ensureVisible();
203 GTThread::waitForMainThread();
204 GTMouseDriver::moveTo(getGlobalCenterCoord(os, node));
205 GTMouseDriver::click();
206 }
207 #undef GT_METHOD_NAME
208
209 #define GT_METHOD_NAME "doubleClickNode"
doubleClickNode(HI::GUITestOpStatus & os,GraphicsButtonItem * node)210 void GTUtilsPhyTree::doubleClickNode(HI::GUITestOpStatus &os, GraphicsButtonItem *node) {
211 GT_CHECK(node != nullptr, "Node to doubleClickNode is NULL");
212 node->ensureVisible();
213 GTThread::waitForMainThread();
214 GTMouseDriver::moveTo(getGlobalCenterCoord(os, node));
215 GTMouseDriver::doubleClick();
216 GTThread::waitForMainThread();
217 }
218 #undef GT_METHOD_NAME
219
220 #define GT_METHOD_NAME "getNodeDistance"
getNodeDistance(HI::GUITestOpStatus & os,GraphicsButtonItem * node)221 qreal GTUtilsPhyTree::getNodeDistance(HI::GUITestOpStatus &os, GraphicsButtonItem *node) {
222 GT_CHECK_RESULT(nullptr != node, "Node is NULL", 0);
223 GraphicsRectangularBranchItem *branch = dynamic_cast<GraphicsRectangularBranchItem *>(node->parentItem());
224 GT_CHECK_RESULT(nullptr != branch, "Node's branch' is NULL", 0);
225 return branch->getDist();
226 }
227 #undef GT_METHOD_NAME
228
229 #define GT_METHOD_NAME "getTreeViewerUi"
getTreeViewerUi(HI::GUITestOpStatus & os)230 TreeViewerUI *GTUtilsPhyTree::getTreeViewerUi(HI::GUITestOpStatus &os) {
231 return GTWidget::findExactWidget<TreeViewerUI *>(os, "treeView", GTUtilsMdi::activeWindow(os));
232 }
233 #undef GT_METHOD_NAME
234
235 #define GT_METHOD_NAME "getOrderedRectangularNodes"
getOrderedRectangularNodes(HI::GUITestOpStatus & os)236 QList<GraphicsButtonItem *> GTUtilsPhyTree::getOrderedRectangularNodes(HI::GUITestOpStatus &os) {
237 QList<GraphicsButtonItem *> orderedRectangularNodes;
238 QList<GraphicsRectangularBranchItem *> graphicsRectangularBranchItems = getOrderedRectangularBranches(os);
239 foreach (GraphicsRectangularBranchItem *rectangularBranch, graphicsRectangularBranchItems) {
240 GT_CHECK_RESULT(nullptr != rectangularBranch, "Rectangular branch is NULL", QList<GraphicsButtonItem *>());
241 GraphicsButtonItem *rectangularNode = rectangularBranch->getButton();
242 if (nullptr != rectangularNode) {
243 orderedRectangularNodes << rectangularNode;
244 }
245 }
246 return orderedRectangularNodes;
247 }
248 #undef GT_METHOD_NAME
249
250 #define GT_METHOD_NAME "getOrderedRectangularBranches"
getOrderedRectangularBranches(HI::GUITestOpStatus & os)251 QList<GraphicsRectangularBranchItem *> GTUtilsPhyTree::getOrderedRectangularBranches(HI::GUITestOpStatus &os) {
252 return getSubtreeOrderedRectangularBranches(os, getRootRectangularBranch(os));
253 }
254 #undef GT_METHOD_NAME
255
256 #define GT_METHOD_NAME "getRootRectangularNode"
getOrderedRectangularBranchesDistances(HI::GUITestOpStatus & os)257 QList<qreal> GTUtilsPhyTree::getOrderedRectangularBranchesDistances(HI::GUITestOpStatus &os) {
258 QList<GraphicsRectangularBranchItem *> orderedBranches = getOrderedRectangularBranches(os);
259 QList<qreal> orderedDistances;
260 foreach (GraphicsRectangularBranchItem *branch, orderedBranches) {
261 GT_CHECK_RESULT(nullptr != branch, "Branch is NULL", QList<qreal>());
262 orderedDistances << branch->getDist();
263 }
264 return orderedDistances;
265 }
266 #undef GT_METHOD_NAME
267
268 #define GT_METHOD_NAME "getRootRectangularNode"
getRootRectangularNode(HI::GUITestOpStatus & os)269 GraphicsButtonItem *GTUtilsPhyTree::getRootRectangularNode(HI::GUITestOpStatus &os) {
270 GraphicsRectangularBranchItem *rootBranch = getRootRectangularBranch(os);
271 GT_CHECK_RESULT(nullptr != rootBranch, "Root branch is NULL", nullptr);
272 return rootBranch->getButton();
273 }
274 #undef GT_METHOD_NAME
275
276 #define GT_METHOD_NAME "getRootRectangularBranch"
getRootRectangularBranch(HI::GUITestOpStatus & os)277 GraphicsRectangularBranchItem *GTUtilsPhyTree::getRootRectangularBranch(HI::GUITestOpStatus &os) {
278 TreeViewerUI *treeViewerUi = getTreeViewerUi(os);
279 GT_CHECK_RESULT(nullptr != treeViewerUi, "TreeViewerUI is NULL", nullptr);
280
281 QList<QGraphicsItem *> items = treeViewerUi->scene()->items();
282 foreach (QGraphicsItem *item, items) {
283 GraphicsRectangularBranchItem *rectangularBranch = dynamic_cast<GraphicsRectangularBranchItem *>(item);
284 if (nullptr != rectangularBranch && nullptr == rectangularBranch->getParentItem()) {
285 return rectangularBranch;
286 }
287 }
288
289 return nullptr;
290 }
291 #undef GT_METHOD_NAME
292
293 #define GT_METHOD_NAME "getSubtreeOrderedRectangularBranches"
getSubtreeOrderedRectangularBranches(HI::GUITestOpStatus & os,GraphicsRectangularBranchItem * rootBranch)294 QList<GraphicsRectangularBranchItem *> GTUtilsPhyTree::getSubtreeOrderedRectangularBranches(HI::GUITestOpStatus &os, GraphicsRectangularBranchItem *rootBranch) {
295 GT_CHECK_RESULT(nullptr != rootBranch, "Subtree root branch is NULL", QList<GraphicsRectangularBranchItem *>());
296
297 const QList<QGraphicsItem *> childItems = rootBranch->getChildItems();
298 QList<GraphicsRectangularBranchItem *> childRectangularBranches;
299 foreach (QGraphicsItem *childItem, childItems) {
300 GraphicsRectangularBranchItem *childRectangularBranch = dynamic_cast<GraphicsRectangularBranchItem *>(childItem);
301 if (nullptr != childRectangularBranch && nullptr != childRectangularBranch->getDistanceText()) {
302 childRectangularBranches << childRectangularBranch;
303 }
304 }
305
306 std::sort(childRectangularBranches.begin(), childRectangularBranches.end(), rectangularBranchLessThan);
307
308 QList<GraphicsRectangularBranchItem *> subtreeOrderedRectangularBranches;
309 foreach (GraphicsRectangularBranchItem *childRectangularBranch, childRectangularBranches) {
310 subtreeOrderedRectangularBranches << getSubtreeOrderedRectangularBranches(os, childRectangularBranch);
311 }
312 subtreeOrderedRectangularBranches << rootBranch;
313
314 return subtreeOrderedRectangularBranches;
315 }
316 #undef GT_METHOD_NAME
317
318 #define GT_METHOD_NAME "rectangularBranchLessThan"
rectangularBranchLessThan(GraphicsRectangularBranchItem * first,GraphicsRectangularBranchItem * second)319 bool GTUtilsPhyTree::rectangularBranchLessThan(GraphicsRectangularBranchItem *first, GraphicsRectangularBranchItem *second) {
320 SAFE_POINT(nullptr != first, "First rectangular branch item is NULL", true);
321 SAFE_POINT(nullptr != second, "Second rectangular branch item is NULL", false);
322
323 if (first->getDirection() == second->getDirection()) {
324 if (first->getDirection() == GraphicsBranchItem::up) {
325 return first->getDist() < second->getDist();
326 } else {
327 return first->getDist() > second->getDist();
328 }
329 }
330
331 return first->getDirection() > second->getDirection();
332 }
333 #undef GT_METHOD_NAME
334
335 #undef GT_CLASS_NAME
336
337 } // namespace U2
338