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 "GraphSettingsDialog.h"
23 
24 #include <QColorDialog>
25 #include <QHBoxLayout>
26 #include <QMessageBox>
27 #include <QProxyStyle>
28 #include <QPushButton>
29 #include <QStyleFactory>
30 
31 #include <U2Core/QObjectScopedPointer.h>
32 #include <U2Core/U2SafePoints.h>
33 
34 #include <U2Gui/HelpButton.h>
35 
36 #include "ADVGraphModel.h"
37 #include "WindowStepSelectorWidget.h"
38 
39 namespace U2 {
40 
41 namespace {
42 
setButtonColor(QPushButton * button,const QColor & color)43 void setButtonColor(QPushButton *button, const QColor &color) {
44     QPalette palette = button->palette();
45     palette.setColor(button->backgroundRole(), color);
46     button->setPalette(palette);
47 }
48 
49 }  // namespace
50 
GraphSettingsDialog(GSequenceGraphDrawer * d,const U2Region & range,QWidget * parent)51 GraphSettingsDialog::GraphSettingsDialog(GSequenceGraphDrawer *d, const U2Region &range, QWidget *parent)
52     : QDialog(parent), colorMap(d->getColors()) {
53     const GSequenceGraphMinMaxCutOffState &cutOffData = d->getCutOffState();
54     wss = new WindowStepSelectorWidget(this, range, d->getWindow(), d->getStep());
55     mms = new MinMaxSelectorWidget(this, cutOffData.min, cutOffData.max, cutOffData.isEnabled);
56 
57     QFormLayout *form = wss->getFormLayout();
58     foreach (const QString &key, colorMap.keys()) {
59         QPushButton *colorChangeButton = new QPushButton();
60         colorChangeButton->setObjectName(key);
61         connect(colorChangeButton, SIGNAL(clicked()), SLOT(sl_onPickColorButtonClicked()));
62         QColor color = colorMap.value(key);
63 
64         QStyle *buttonStyle = new QProxyStyle(QStyleFactory::create("fusion"));
65         buttonStyle->setParent(this);
66         colorChangeButton->setStyle(buttonStyle);
67 
68         setButtonColor(colorChangeButton, color);
69 
70         form->addRow(QString("%1:").arg(key), colorChangeButton);
71     }
72 
73     QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this);
74     buttonBox->setObjectName("buttonBox");
75 
76     QHBoxLayout *buttonsLayout = new QHBoxLayout();
77     buttonsLayout->addStretch(10);
78     buttonsLayout->addWidget(buttonBox);
79 
80     QVBoxLayout *l = new QVBoxLayout();
81     l->setSizeConstraint(QLayout::SetFixedSize);
82     l->addWidget(wss);
83     l->addWidget(mms);
84     l->addLayout(buttonsLayout);
85 
86     setLayout(l);
87     setWindowTitle(tr("Graph Settings"));
88     setWindowIcon(QIcon(":core/images/graphs.png"));
89 
90     QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok);
91     QPushButton *cancelButton = buttonBox->button(QDialogButtonBox::Cancel);
92     new HelpButton(this, buttonBox, "65929576");
93 
94     connect(cancelButton, SIGNAL(clicked()), SLOT(sl_onCancelClicked()));
95     connect(okButton, SIGNAL(clicked()), SLOT(sl_onOkClicked()));
96 
97     okButton->setDefault(true);
98     setObjectName("GraphSettingsDialog");
99 }
100 
sl_onPickColorButtonClicked()101 void GraphSettingsDialog::sl_onPickColorButtonClicked() {
102     QPushButton *colorButton = qobject_cast<QPushButton *>(sender());
103     SAFE_POINT(colorButton, "Button for color is NULL", );
104 
105     QString colorName = colorButton->objectName();
106     QColor initial = colorMap.value(colorName);
107 
108     QObjectScopedPointer<QColorDialog> colorDialog = new QColorDialog(initial, this);
109 
110     // Disable use of native dialog here.
111     // Reason: the native dialog will not be shown (tested on Ubuntu 20.04) if we have at least 1 graph-label visible (QT bug?).
112     // The problem is caused by GSequenceGraphDrawer::draw() method that calls graphLabel->setVisible().
113     // One possible solution here could be an optimization of GSequenceGraphViewRA::drawAll method: avoid full redraw when it is not needed.
114     // Another solution is to make 'TextLabel' not a QLabel (which causes the problem), but a QWidget that draws the label text manually.
115     colorDialog->setOption(QColorDialog::DontUseNativeDialog, true);
116     colorDialog->exec();
117     CHECK(!colorDialog.isNull(), );
118 
119     if (colorDialog->result() == QDialog::Accepted) {
120         QColor newColor = colorDialog->selectedColor();
121         colorMap[colorName] = newColor;
122         setButtonColor(colorButton, newColor);
123     }
124 }
125 
sl_onCancelClicked()126 void GraphSettingsDialog::sl_onCancelClicked() {
127     reject();
128 }
129 
sl_onOkClicked()130 void GraphSettingsDialog::sl_onOkClicked() {
131     QString err = wss->validate();
132     QString mmerr = mms->validate();
133     if (err.isEmpty() && mmerr.isEmpty()) {
134         accept();
135         return;
136     }
137     QMessageBox::critical(this, windowTitle(), err.append(' ').append(mmerr));
138 }
139 
140 }  // namespace U2
141