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 "GTUtilsTaskTreeView.h"
23 #include <drivers/GTKeyboardDriver.h>
24 #include <drivers/GTMouseDriver.h>
25 #include <primitives/GTWidget.h>
26 
27 #include <QTimer>
28 #include <QTreeWidget>
29 
30 #include <U2Core/AppContext.h>
31 #include <U2Core/Task.h>
32 
33 #include <U2Gui/MainWindow.h>
34 
35 #include "primitives/PopupChooser.h"
36 #include "utils/GTThread.h"
37 
38 namespace U2 {
39 using namespace HI;
40 
41 #define GT_CLASS_NAME "GTUtilsTaskTreeView"
42 
43 const QString GTUtilsTaskTreeView::widgetName = DOCK_TASK_TREE_VIEW;
44 
waitTaskFinished(HI::GUITestOpStatus & os,long timeoutMillis)45 void GTUtilsTaskTreeView::waitTaskFinished(HI::GUITestOpStatus &os, long timeoutMillis) {
46     TaskScheduler *scheduler = AppContext::getTaskScheduler();
47     for (int time = 0; time < timeoutMillis && !scheduler->getTopLevelTasks().isEmpty(); time += GT_OP_CHECK_MILLIS) {
48         GTGlobals::sleep(GT_OP_CHECK_MILLIS);
49     }
50     if (!scheduler->getTopLevelTasks().isEmpty()) {
51         os.setError(os.getError() + getTasksInfo(scheduler->getTopLevelTasks(), 0));
52     }
53 }
54 
getTasksInfo(QList<Task * > tasks,int level)55 QString GTUtilsTaskTreeView::getTasksInfo(QList<Task *> tasks, int level) {
56     QString result;
57     QMap<Task::State, QString> stateMap;
58     stateMap.insert(Task::State_New, "State_New");
59     stateMap.insert(Task::State_Prepared, "State_Prepared");
60     stateMap.insert(Task::State_Running, "State_Running");
61     stateMap.insert(Task::State_Finished, "State_Finished");
62     foreach (Task *t, tasks) {
63         for (int i = 0; i < level; i++) {
64             result.append("  ");
65         }
66         result.append(QString("%1:  %2\n").arg(t->getTaskName()).arg(stateMap.value(t->getState())));
67         result.append(getTasksInfo(t->getPureSubtasks(), level + 1));
68     }
69     return result;
70 }
openView(HI::GUITestOpStatus & os)71 void GTUtilsTaskTreeView::openView(HI::GUITestOpStatus &os) {
72     GTGlobals::FindOptions options;
73     options.failIfNotFound = false;
74 
75     QWidget *documentTreeWidget = GTWidget::findWidget(os, widgetName, nullptr, options);
76     if (!documentTreeWidget) {
77         toggleView(os);
78         GTGlobals::sleep(500);
79         GTThread::waitForMainThread();
80     }
81 }
82 
toggleView(HI::GUITestOpStatus &)83 void GTUtilsTaskTreeView::toggleView(HI::GUITestOpStatus & /*os*/) {
84     GTKeyboardDriver::keyClick('2', Qt::AltModifier);
85 }
86 
87 #define GT_METHOD_NAME "getTreeWidgetItem"
getTreeWidgetItem(HI::GUITestOpStatus & os,const QString & itemName,bool failOnNull)88 QTreeWidgetItem *GTUtilsTaskTreeView::getTreeWidgetItem(HI::GUITestOpStatus &os, const QString &itemName, bool failOnNull) {
89     QTreeWidget *treeWidget = getTreeWidget(os);
90     GT_CHECK_RESULT(treeWidget != nullptr, "Tree widget not found", nullptr);
91 
92     QTreeWidgetItem *item = getTreeWidgetItem(treeWidget, itemName);
93     if (failOnNull) {
94         GT_CHECK_RESULT(item != nullptr, "Item " + itemName + " not found in tree widget", nullptr);
95     }
96 
97     return item;
98 }
99 #undef GT_METHOD_NAME
100 
getTreeWidgetItem(QTreeWidget * tree,const QString & itemName)101 QTreeWidgetItem *GTUtilsTaskTreeView::getTreeWidgetItem(QTreeWidget *tree, const QString &itemName) {
102     if (itemName.isEmpty()) {
103         return nullptr;
104     }
105 
106     QList<QTreeWidgetItem *> treeItems = getTaskTreeViewItems(tree->invisibleRootItem());
107     foreach (QTreeWidgetItem *item, treeItems) {
108         QString treeItemName = item->text(0);
109         if (treeItemName == itemName) {
110             return item;
111         }
112     }
113 
114     return nullptr;
115 }
116 
getTreeWidget(HI::GUITestOpStatus & os)117 QTreeWidget *GTUtilsTaskTreeView::getTreeWidget(HI::GUITestOpStatus &os) {
118     GTGlobals::FindOptions options;
119     options.failIfNotFound = false;
120 
121     QTreeWidget *treeWidget = static_cast<QTreeWidget *>(GTWidget::findWidget(os, widgetName, nullptr, options));
122     return treeWidget;
123 }
124 
getTaskTreeViewItems(QTreeWidgetItem * root,bool recursively)125 QList<QTreeWidgetItem *> GTUtilsTaskTreeView::getTaskTreeViewItems(QTreeWidgetItem *root, bool recursively) {
126     QList<QTreeWidgetItem *> treeItems;
127 
128     for (int i = 0; i < root->childCount(); i++) {
129         treeItems.append(root->child(i));
130         if (recursively) {
131             treeItems.append(getTaskTreeViewItems(root->child(i)));
132         }
133     }
134 
135     return treeItems;
136 }
137 
cancelTask(HI::GUITestOpStatus & os,const QString & itemName)138 void GTUtilsTaskTreeView::cancelTask(HI::GUITestOpStatus &os, const QString &itemName) {
139     Runnable *popupChooser = new PopupChooser(os, QStringList() << "Cancel task", GTGlobals::UseMouse);
140     GTUtilsDialog::waitForDialog(os, popupChooser);
141     click(os, itemName, Qt::RightButton);
142     GTGlobals::sleep(3000);
143 }
144 
click(HI::GUITestOpStatus & os,const QString & itemName,Qt::MouseButton b)145 void GTUtilsTaskTreeView::click(HI::GUITestOpStatus &os, const QString &itemName, Qt::MouseButton b) {
146     moveTo(os, itemName);
147     GTMouseDriver::click(b);
148 }
149 
moveTo(HI::GUITestOpStatus & os,const QString & itemName)150 void GTUtilsTaskTreeView::moveTo(HI::GUITestOpStatus &os, const QString &itemName) {
151     openView(os);
152     moveToOpenedView(os, itemName);
153 }
154 
155 #define GT_METHOD_NAME "getTopLevelTasksCount"
getTopLevelTasksCount(HI::GUITestOpStatus & os)156 int GTUtilsTaskTreeView::getTopLevelTasksCount(HI::GUITestOpStatus &os) {
157     openView(os);
158 
159     QTreeWidget *treeWidget = getTreeWidget(os);
160     GT_CHECK_RESULT(treeWidget != nullptr, "Tree widget not found", -1);
161 
162     return getTaskTreeViewItems(treeWidget->invisibleRootItem(), false).size();
163 }
164 #undef GT_METHOD_NAME
165 
moveToOpenedView(HI::GUITestOpStatus & os,const QString & itemName)166 void GTUtilsTaskTreeView::moveToOpenedView(HI::GUITestOpStatus &os, const QString &itemName) {
167     QPoint p = getTreeViewItemPosition(os, itemName);
168     GTMouseDriver::moveTo(p);
169 }
170 
171 #define GT_METHOD_NAME "getTreeViewItemPosition"
getTreeViewItemPosition(HI::GUITestOpStatus & os,const QString & itemName)172 QPoint GTUtilsTaskTreeView::getTreeViewItemPosition(HI::GUITestOpStatus &os, const QString &itemName) {
173     QTreeWidget *treeWidget = getTreeWidget(os);
174     GT_CHECK_RESULT(treeWidget != nullptr, "treeWidget is NULL", QPoint());
175     for (int time = 0; time < GT_OP_WAIT_MILLIS; time += GT_OP_CHECK_MILLIS) {
176         GTGlobals::sleep(time > 0 ? GT_OP_CHECK_MILLIS : 0);
177         QTreeWidgetItem *item = getTreeWidgetItem(os, itemName);
178         if (item) {
179             QPoint itemCenter = treeWidget->visualItemRect(item).center();
180             itemCenter.setY(itemCenter.y() + treeWidget->visualItemRect(item).height() + 5);  //+ height because of header item; +5 because height is not enough
181             return treeWidget->mapToGlobal(itemCenter);
182         }
183     }
184     // TODO: report error?
185     return treeWidget->mapToGlobal(treeWidget->rect().center());
186 }
187 #undef GT_METHOD_NAME
188 
189 #define GT_METHOD_NAME "checkTask"
checkTask(HI::GUITestOpStatus & os,const QString & itemName)190 bool GTUtilsTaskTreeView::checkTask(HI::GUITestOpStatus &os, const QString &itemName) {
191     openView(os);
192     QTreeWidgetItem *item = getTreeWidgetItem(os, itemName, false);
193     return item != nullptr;
194 }
195 #undef GT_METHOD_NAME
196 
197 #define GT_METHOD_NAME "countTasks"
countTasks(HI::GUITestOpStatus & os,const QString & itemName)198 int GTUtilsTaskTreeView::countTasks(HI::GUITestOpStatus &os, const QString &itemName) {
199     openView(os);
200     int result = 0;
201     QList<QTreeWidgetItem *> treeItems = getTaskTreeViewItems(getTreeWidget(os)->invisibleRootItem());
202     foreach (QTreeWidgetItem *item, treeItems) {
203         QString treeItemName = item->text(0);
204         if (treeItemName == itemName) {
205             result++;
206         }
207     }
208     return result;
209 }
210 #undef GT_METHOD_NAME
211 
getTaskStatus(GUITestOpStatus & os,const QString & itemName)212 QString GTUtilsTaskTreeView::getTaskStatus(GUITestOpStatus &os, const QString &itemName) {
213     openView(os);
214     GTGlobals::sleep(500);
215     return getTreeWidgetItem(os, itemName)->text(1);
216 }
217 
SchedulerListener()218 SchedulerListener::SchedulerListener()
219     : QObject(nullptr),
220       registeredTaskCount(0) {
221     connect(AppContext::getTaskScheduler(), SIGNAL(si_topLevelTaskRegistered(Task *)), SLOT(sl_taskRegistered()));
222 }
223 
getRegisteredTaskCount() const224 int SchedulerListener::getRegisteredTaskCount() const {
225     return registeredTaskCount;
226 }
227 
reset()228 void SchedulerListener::reset() {
229     registeredTaskCount = 0;
230 }
231 
sl_taskRegistered()232 void SchedulerListener::sl_taskRegistered() {
233     registeredTaskCount++;
234 }
235 
236 #undef GT_CLASS_NAME
237 
238 }  // namespace U2
239