1 /**
2  * UGENE - Integrated Bioinformatics Tools.
3  * Copyright (C) 2008-2017 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/GTWidget.h>
25 
26 #include <QHeaderView>
27 
28 #include "primitives/GTTreeWidget.h"
29 
30 namespace HI {
31 
32 #define GT_CLASS_NAME "GTUtilsTreeView"
33 
34 #define GT_METHOD_NAME "expand"
expand(GUITestOpStatus & os,QTreeWidgetItem * item)35 void GTTreeWidget::expand(GUITestOpStatus &os, QTreeWidgetItem *item) {
36     if (item == NULL) {
37         return;
38     }
39     expand(os, item->parent());
40     GT_CHECK(item->isHidden() == false, "parent item is hidden");
41 
42     QTreeWidget *treeWidget = item->treeWidget();
43     GT_CHECK(item->isHidden() == false, "parent item is hidden");
44 
45     treeWidget->scrollToItem(item);
46 
47     QRect itemRect = treeWidget->visualItemRect(item);
48     if (!item->isExpanded()) {
49         QPoint p = QPoint(itemRect.left() - 8, itemRect.center().y());
50 
51         GTMouseDriver::moveTo(treeWidget->viewport()->mapToGlobal(p));
52         GTMouseDriver::click();
53     }
54 }
55 #undef GT_METHOD_NAME
56 
57 #define GT_METHOD_NAME "checkItem"
checkItem(GUITestOpStatus & os,QTreeWidgetItem * item,int column,GTGlobals::UseMethod method)58 void GTTreeWidget::checkItem(GUITestOpStatus &os, QTreeWidgetItem *item, int column, GTGlobals::UseMethod method) {
59     Q_UNUSED(os);
60     GT_CHECK(NULL != item, "treeWidgetItem is NULL");
61     GT_CHECK(0 <= column, "The column number is invalid");
62 
63     QTreeWidget *tree = item->treeWidget();
64     GT_CHECK(NULL != tree, "The tree widget is NULL");
65 
66     const QRect itemRect = getItemRect(os, item);
67     const QPoint indentationOffset(tree->indentation(), 0);
68     const QPoint itemStartPos = QPoint(itemRect.left(), itemRect.center().y()) - indentationOffset;
69     const QPoint columnOffset(tree->columnViewportPosition(column), 0);
70     const QPoint itemLevelOffset(getItemLevel(os, item) * tree->indentation(), 0);
71 
72     switch (method) {
73         case GTGlobals::UseKeyBoard: {
74             const QPoint cellCenterOffset(tree->columnWidth(column) / 2, itemRect.height() / 2);
75             GTMouseDriver::moveTo(itemStartPos + itemLevelOffset + columnOffset + cellCenterOffset);
76             GTMouseDriver::click();
77             GTKeyboardDriver::keyClick(Qt::Key_Space);
78             break;
79         }
80         case GTGlobals::UseMouse: {
81             const QPoint magicCheckBoxOffset = QPoint(15, 0);
82             GTMouseDriver::moveTo(tree->viewport()->mapToGlobal(itemStartPos + itemLevelOffset + columnOffset + magicCheckBoxOffset));
83             GTMouseDriver::click();
84             break;
85         }
86         default:
87             GT_CHECK(false, "Method is not implemented");
88     }
89 }
90 #undef GT_METHOD_NAME
91 
92 #define GT_METHOD_NAME "getItemRect"
getItemRect(GUITestOpStatus & os,QTreeWidgetItem * item)93 QRect GTTreeWidget::getItemRect(GUITestOpStatus &os, QTreeWidgetItem *item) {
94     GT_CHECK_RESULT(item != NULL, "treeWidgetItem is NULL", QRect());
95 
96     QTreeWidget *treeWidget = item->treeWidget();
97     GT_CHECK_RESULT(treeWidget != NULL, "treeWidget is NULL", QRect());
98 
99     expand(os, item);
100     GT_CHECK_RESULT(item->isHidden() == false, "item is hidden", QRect());
101 
102     QRect rect = treeWidget->visualItemRect(item);
103 
104     return rect;
105 }
106 #undef GT_METHOD_NAME
107 
108 #define GT_METHOD_NAME "getItemCenter"
getItemCenter(GUITestOpStatus & os,QTreeWidgetItem * item)109 QPoint GTTreeWidget::getItemCenter(GUITestOpStatus &os, QTreeWidgetItem *item) {
110     GT_CHECK_RESULT(item != NULL, "item is NULL", QPoint());
111 
112     QTreeWidget *treeWidget = item->treeWidget();
113     GT_CHECK_RESULT(treeWidget != NULL, "treeWidget is NULL", QPoint());
114 
115     QPoint p = getItemRect(os, item).center();
116 
117     return treeWidget->viewport()->mapToGlobal(p);
118 }
119 #undef GT_METHOD_NAME
120 
121 #define GT_METHOD_NAME "getItems"
getItems(QTreeWidgetItem * root)122 QList<QTreeWidgetItem *> GTTreeWidget::getItems(QTreeWidgetItem *root) {
123     QList<QTreeWidgetItem *> treeItems;
124     for (int i = 0; i < root->childCount(); i++) {
125         QTreeWidgetItem *childItem = root->child(i);
126         treeItems.append(childItem);
127         treeItems.append(getItems(childItem));
128     }
129     return treeItems;
130 }
131 #undef GT_METHOD_NAME
132 
133 #define GT_METHOD_NAME "getItems"
getItems(GUITestOpStatus & os,QTreeWidget * treeWidget)134 QList<QTreeWidgetItem *> GTTreeWidget::getItems(GUITestOpStatus &os, QTreeWidget *treeWidget) {
135     GT_CHECK_RESULT(treeWidget != nullptr, "Tree widget is NULL", QList<QTreeWidgetItem *>());
136     return getItems(treeWidget->invisibleRootItem());
137 }
138 #undef GT_METHOD_NAME
139 
140 #define GT_METHOD_NAME "getItemNames"
getItemNames(GUITestOpStatus & os,QTreeWidget * treeWidget)141 QStringList GTTreeWidget::getItemNames(GUITestOpStatus &os, QTreeWidget *treeWidget) {
142     QStringList itemNames;
143     QList<QTreeWidgetItem *> items = getItems(os, treeWidget);
144     foreach (QTreeWidgetItem *item, items) {
145         itemNames << item->text(0);
146     }
147     return itemNames;
148 }
149 #undef GT_METHOD_NAME
150 
151 #define GT_METHOD_NAME "findItemPrivate"
findItemPrivate(GUITestOpStatus & os,QTreeWidget * tree,const QString & text,QTreeWidgetItem * parent,int column,const GTGlobals::FindOptions & options)152 QTreeWidgetItem *GTTreeWidget::findItemPrivate(GUITestOpStatus &os, QTreeWidget *tree, const QString &text, QTreeWidgetItem *parent, int column, const GTGlobals::FindOptions &options) {
153     Q_UNUSED(os);
154     GT_CHECK_RESULT(tree != NULL, "tree widget is NULL", NULL);
155 
156     if (parent == NULL) {
157         parent = tree->invisibleRootItem();
158     }
159 
160     GTGlobals::FindOptions innerOptions(options);
161     if (options.depth != GTGlobals::FindOptions::INFINITE_DEPTH) {
162         innerOptions.depth--;
163     }
164 
165     const QList<QTreeWidgetItem *> list = getItems(parent);
166     foreach (QTreeWidgetItem *item, list) {
167         const QString itemText = item->text(column);
168         if (options.matchPolicy.testFlag(Qt::MatchExactly) && itemText == text) {
169             return item;
170         } else if (options.matchPolicy.testFlag(Qt::MatchContains) && itemText.contains(text)) {
171             return item;
172         }
173 
174         if (options.depth == GTGlobals::FindOptions::INFINITE_DEPTH ||
175             innerOptions.depth > 0) {
176             QTreeWidgetItem *childItem = findItemPrivate(os, tree, text, item, column, innerOptions);
177             if (NULL != childItem) {
178                 return childItem;
179             }
180         }
181     }
182     return NULL;
183 }
184 #undef GT_METHOD_NAME
185 
186 #define GT_METHOD_NAME "findItem"
findItem(GUITestOpStatus & os,QTreeWidget * tree,const QString & text,QTreeWidgetItem * parent,int column,const GTGlobals::FindOptions & options)187 QTreeWidgetItem *GTTreeWidget::findItem(GUITestOpStatus &os, QTreeWidget *tree, const QString &text, QTreeWidgetItem *parent, int column, const GTGlobals::FindOptions &options) {
188     QTreeWidgetItem *result = findItemPrivate(os, tree, text, parent, column, options);
189     if (options.failIfNotFound) {
190         CHECK_SET_ERR_RESULT(result != NULL, QString("Item '%1' not found").arg(text), NULL);
191     }
192     return result;
193 }
194 #undef GT_METHOD_NAME
195 
196 #define GT_METHOD_NAME "findItems"
findItems(GUITestOpStatus & os,QTreeWidget * tree,const QString & text,QTreeWidgetItem * parent,int column,const GTGlobals::FindOptions & options)197 QList<QTreeWidgetItem *> GTTreeWidget::findItems(GUITestOpStatus &os, QTreeWidget *tree, const QString &text, QTreeWidgetItem *parent, int column, const GTGlobals::FindOptions &options) {
198     QList<QTreeWidgetItem *> items;
199 
200     GT_CHECK_RESULT(tree != NULL, "tree widget is NULL", items);
201 
202     if (parent == NULL) {
203         parent = tree->invisibleRootItem();
204     }
205 
206     GTGlobals::FindOptions innerOptions(options);
207     if (options.depth != GTGlobals::FindOptions::INFINITE_DEPTH) {
208         innerOptions.depth--;
209     }
210 
211     const QList<QTreeWidgetItem *> list = getItems(parent);
212     foreach (QTreeWidgetItem *item, list) {
213         const QString itemText = item->text(column);
214         if (options.matchPolicy.testFlag(Qt::MatchExactly) && itemText == text) {
215             items << item;
216         } else if (options.matchPolicy.testFlag(Qt::MatchContains) && itemText.contains(text)) {
217             items << item;
218         }
219 
220         if (options.depth == GTGlobals::FindOptions::INFINITE_DEPTH ||
221             innerOptions.depth > 0) {
222             items << findItems(os, tree, text, item, column, innerOptions);
223         }
224     }
225 
226     return items;
227 }
228 #undef GT_METHOD_NAME
229 
230 #define GT_METHOD_NAME "click"
click(GUITestOpStatus & os,QTreeWidgetItem * item,int column)231 void GTTreeWidget::click(GUITestOpStatus &os, QTreeWidgetItem *item, int column) {
232     GT_CHECK(item != NULL, "item is NULL");
233     QTreeWidget *tree = item->treeWidget();
234     tree->scrollToItem(item);
235 
236     QPoint point;
237     if (-1 == column) {
238         point = getItemCenter(os, item);
239     } else {
240         const QRect itemRect = getItemRect(os, item);
241         point = tree->viewport()->mapToGlobal(itemRect.topLeft());
242         point += QPoint(tree->columnViewportPosition(column) + tree->columnWidth(column) / 2, itemRect.height() / 2);
243     }
244 
245     GTMouseDriver::moveTo(point);
246     GTMouseDriver::click();
247 }
248 #undef GT_METHOD_NAME
249 
250 #define GT_METHOD_NAME "getItemLevel"
getItemLevel(GUITestOpStatus & os,QTreeWidgetItem * item)251 int GTTreeWidget::getItemLevel(GUITestOpStatus &os, QTreeWidgetItem *item) {
252     Q_UNUSED(os);
253     GT_CHECK_RESULT(item != NULL, "item is NULL", -1);
254 
255     int level = 0;
256     while (NULL != item->parent()) {
257         level++;
258         item = item->parent();
259     }
260 
261     return level;
262 }
263 #undef GT_METHOD_NAME
264 
265 #undef GT_CLASS_NAME
266 
267 }  // namespace HI
268