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 "ShowHideSubgroupWidget.h"
23 
24 #include <QHBoxLayout>
25 #include <QLabel>
26 #include <QMovie>
27 #include <QTimer>
28 #include <QVBoxLayout>
29 
30 #include <U2Core/U2SafePoints.h>
31 
32 namespace U2 {
33 
ShowHideSubgroupWidget(QWidget * parent)34 ShowHideSubgroupWidget::ShowHideSubgroupWidget(QWidget *parent)
35     : QWidget(parent), arrowHeaderWidget(nullptr), innerWidget(nullptr) {
36 }
37 
ShowHideSubgroupWidget(const QString & _id,const QString & caption,QWidget * _innerWidget,bool isOpened)38 ShowHideSubgroupWidget::ShowHideSubgroupWidget(const QString &_id, const QString &caption, QWidget *_innerWidget, bool isOpened)
39     : subgroupId(_id), innerWidget(_innerWidget) {
40     init(subgroupId, caption, innerWidget, isOpened);
41 }
42 
init(const QString & subgroupId,const QString & caption,QWidget * innerWidget,bool isOpened)43 void ShowHideSubgroupWidget::init(const QString &subgroupId, const QString &caption, QWidget *innerWidget, bool isOpened) {
44     this->subgroupId = subgroupId;
45     this->innerWidget = innerWidget;
46 
47     QVBoxLayout *mainLayout = new QVBoxLayout();
48     mainLayout->setContentsMargins(0, 0, 0, 10);
49     mainLayout->setSpacing(0);
50     mainLayout->setSizeConstraint(QLayout::SetMinAndMaxSize);
51     setLayout(mainLayout);
52 
53     innerWidget->setContentsMargins(17, 5, 5, 5);
54 
55     arrowHeaderWidget = new ArrowHeaderWidget(caption, isOpened);
56     connect(arrowHeaderWidget, SIGNAL(si_arrowHeaderPressed(bool)), SLOT(updateSubgroupState(bool)));
57     updateSubgroupState(isOpened);
58 
59     mainLayout->addWidget(arrowHeaderWidget);
60     mainLayout->addWidget(innerWidget);
61 
62     setObjectName(subgroupId);
63 }
64 
updateSubgroupState(bool isSubgroupOpened)65 void ShowHideSubgroupWidget::updateSubgroupState(bool isSubgroupOpened) {
66     innerWidget->setVisible(isSubgroupOpened);
67     emit si_subgroupStateChanged(subgroupId);
68 }
69 
isSubgroupOpened() const70 bool ShowHideSubgroupWidget::isSubgroupOpened() const {
71     SAFE_POINT(0 != arrowHeaderWidget, "The arrow header widget hasn't been created, but it is used.", false);
72     return arrowHeaderWidget->isArrowOpened();
73 }
74 
setSubgroupOpened(bool open)75 void ShowHideSubgroupWidget::setSubgroupOpened(bool open) {
76     arrowHeaderWidget->setOpened(open);
77 }
78 
showProgress()79 void ShowHideSubgroupWidget::showProgress() {
80     arrowHeaderWidget->showProgressWithTimeout();
81 }
82 
hideProgress()83 void ShowHideSubgroupWidget::hideProgress() {
84     arrowHeaderWidget->hideProgress();
85 }
86 
setPermanentlyOpen(bool isOpened)87 void ShowHideSubgroupWidget::setPermanentlyOpen(bool isOpened) {
88     arrowHeaderWidget->setOpened(isOpened);
89     if (isOpened) {
90         disconnect(arrowHeaderWidget, SIGNAL(si_arrowHeaderPressed(bool)), this, SLOT(updateSubgroupState(bool)));
91         arrowHeaderWidget->setAttribute(Qt::WA_TransparentForMouseEvents);
92     } else {
93         connect(arrowHeaderWidget, SIGNAL(si_arrowHeaderPressed(bool)), SLOT(updateSubgroupState(bool)));
94         arrowHeaderWidget->setAttribute(Qt::WA_TransparentForMouseEvents, false);
95     }
96 }
97 
ArrowHeaderWidget(const QString & caption,bool _isOpened)98 ArrowHeaderWidget::ArrowHeaderWidget(const QString &caption, bool _isOpened)
99     : isOpened(_isOpened) {
100     QHBoxLayout *arrowHeaderLayout = new QHBoxLayout();
101     arrowHeaderLayout->setContentsMargins(0, 0, 0, 0);
102     arrowHeaderLayout->setSizeConstraint(QLayout::SetMinAndMaxSize);
103 
104     arrow = new QLabel();
105     arrow->setObjectName("ArrowHeader_" + caption);
106     if (isOpened) {
107         arrow->setPixmap(QPixmap(":core/images/arrow_down.png"));
108     } else {
109         arrow->setPixmap(QPixmap(":core/images/arrow_right.png"));
110     }
111 
112     arrow->setMaximumSize(10, 10);
113 
114     QLabel *captionLabel = new QLabel(caption);
115     captionLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
116 
117     progressMovieLabel = new QLabel();
118     progressMovie = new QMovie(":/core/images/progress.gif", QByteArray(), progressMovieLabel);
119     progressMovieLabel->setMovie(progressMovie);
120 
121     if (progressMovie->isValid()) {
122         progressMovie->start();
123         progressMovie->setPaused(true);
124     }
125 
126     arrowHeaderLayout->addWidget(arrow);
127     arrowHeaderLayout->addWidget(captionLabel);
128     arrowHeaderLayout->addWidget(progressMovieLabel);
129 
130     progressMovieLabel->hide();
131     canStartProgress = false;
132 
133     setLayout(arrowHeaderLayout);
134 }
135 
~ArrowHeaderWidget()136 ArrowHeaderWidget::~ArrowHeaderWidget() {
137     delete progressMovie;
138 }
139 
showProgressWithTimeout()140 void ArrowHeaderWidget::showProgressWithTimeout() {
141     QTimer *timeoutToStartProgress = new QTimer(this);
142     connect(timeoutToStartProgress, SIGNAL(timeout()), SLOT(sl_showProgress()));
143     timeoutToStartProgress->start(TIMEOUT);
144     canStartProgress = true;
145 }
146 
sl_showProgress()147 void ArrowHeaderWidget::sl_showProgress() {
148     if (canStartProgress) {
149         progressMovie->setPaused(false);
150         progressMovieLabel->show();
151     }
152 }
153 
hideProgress()154 void ArrowHeaderWidget::hideProgress() {
155     canStartProgress = false;
156     progressMovieLabel->hide();
157     progressMovie->setPaused(true);
158 }
159 
setOpened(bool _isOpened)160 void ArrowHeaderWidget::setOpened(bool _isOpened) {
161     if (_isOpened != isOpened) {
162         if (isOpened) {
163             arrow->setPixmap(QPixmap(":core/images/arrow_right.png"));
164             isOpened = false;
165         } else {
166             arrow->setPixmap(QPixmap(":core/images/arrow_down.png"));
167             isOpened = true;
168         }
169         emit si_arrowHeaderPressed(isOpened);
170     }
171 }
172 
mousePressEvent(QMouseEvent *)173 void ArrowHeaderWidget::mousePressEvent(QMouseEvent * /* event */) {
174     setOpened(!isOpened);
175 }
176 
177 }  // namespace U2
178