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 "AssemblySettingsWidget.h"
23
24 #include <QAction>
25 #include <QCheckBox>
26 #include <QComboBox>
27 #include <QVBoxLayout>
28
29 #include <U2Core/U2SafePoints.h>
30
31 #include <U2Gui/ShowHideSubgroupWidget.h>
32 #include <U2Gui/U2WidgetStateStorage.h>
33
34 #include "AssemblyBrowser.h"
35 #include "AssemblyConsensusArea.h"
36 #include "AssemblyReadsArea.h"
37
38 namespace U2 {
39
40 static const int ITEMS_SPACING = 10;
41 static const int TITLE_SPACING = 5;
42
initLayout(QWidget * w)43 static inline QVBoxLayout *initLayout(QWidget *w) {
44 QVBoxLayout *layout = new QVBoxLayout;
45 layout->setContentsMargins(0, 0, 0, 0);
46 layout->setSpacing(5);
47
48 w->setLayout(layout);
49 return layout;
50 }
51
AssemblySettingsWidget(AssemblyBrowserUi * ui_)52 AssemblySettingsWidget::AssemblySettingsWidget(AssemblyBrowserUi *ui_)
53 : QWidget(ui_), ui(ui_), savableTab(this, GObjectViewUtils::findViewByName(ui_->getWindow()->getName())) {
54 QVBoxLayout *mainLayout = initLayout(this);
55 mainLayout->setSpacing(0);
56
57 QWidget *readsGroup = new ShowHideSubgroupWidget("READS", tr("Reads Area"), createReadsSettings(), true);
58 mainLayout->addWidget(readsGroup);
59
60 QWidget *consensusGroup = new ShowHideSubgroupWidget("CONSENSUS", tr("Consensus Area"), createConsensusSettings(), true);
61 mainLayout->addWidget(consensusGroup);
62
63 QWidget *rulerGroup = new ShowHideSubgroupWidget("RULER", tr("Ruler"), createRulerSettings(), true);
64 mainLayout->addWidget(rulerGroup);
65
66 U2WidgetStateStorage::restoreWidgetState(savableTab);
67 }
68
createTwoWayBinding(QCheckBox * checkBox,QAction * action)69 static inline void createTwoWayBinding(QCheckBox *checkBox, QAction *action) {
70 QObject::connect(action, SIGNAL(toggled(bool)), checkBox, SLOT(setChecked(bool)));
71 QObject::connect(checkBox, SIGNAL(toggled(bool)), action, SLOT(setChecked(bool)));
72 checkBox->setChecked(action->isChecked());
73 }
74
75 // ------- Reads ----------
76
createReadsSettings()77 QWidget *AssemblySettingsWidget::createReadsSettings() {
78 QWidget *group = new QWidget(this);
79 QVBoxLayout *layout = initLayout(group);
80 AssemblyReadsArea *readsArea = ui->getReadsArea();
81 hint = new QLabel("", group);
82 hint->setObjectName("HINT_HIGHLIGHTNING");
83 hint->setWordWrap(true);
84 hint->setStyleSheet(
85 "color: green;"
86 "font: bold;");
87
88 layout->addSpacing(TITLE_SPACING);
89
90 layout->addWidget(new QLabel(tr("Reads highlighting:"), group));
91
92 readsHighlightCombo = new QComboBox(group);
93 readsHighlightCombo->setObjectName("READS_HIGHLIGHTNING_COMBO");
94 foreach (QAction *a, readsArea->getCellRendererActions()) {
95 readsHighlightCombo->addItem(a->text());
96 connect(a, SIGNAL(triggered()), SLOT(sl_cellRendererChanged()));
97 if (a->isChecked()) {
98 readsHighlightCombo->setCurrentIndex(readsHighlightCombo->count() - 1);
99 AssemblyCellRendererFactory *factory = ui->getWindow()->getCellRendererRegistry()->getFactoryById(AssemblyCellRendererFactory::DIFF_NUCLEOTIDES);
100 if (a->text() == factory->getName()) {
101 hint->setText(tr("You should add reference first for correct displaying of this highlighting"));
102 hint->show();
103 } else {
104 hint->setText("");
105 hint->hide();
106 }
107 }
108 }
109 connect(readsHighlightCombo, SIGNAL(currentIndexChanged(int)), SLOT(sl_changeCellRenderer(int)));
110 layout->addWidget(readsHighlightCombo);
111 layout->addWidget(hint);
112
113 QLabel *aboutScrolling = new QLabel(tr("Scrolling can be optimized by drawing only reads' positions without content while scrolling:"));
114 aboutScrolling->setWordWrap(true);
115 aboutScrolling->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
116 layout->addWidget(aboutScrolling);
117
118 QCheckBox *optimizeScroll = new QCheckBox(tr("Optimize scrolling"), group);
119 QAction *optimizeAction = readsArea->getOptimizeRenderAction();
120 createTwoWayBinding(optimizeScroll, optimizeAction);
121 layout->addWidget(optimizeScroll);
122
123 layout->addSpacing(ITEMS_SPACING);
124
125 QCheckBox *showHint = new QCheckBox(tr("Show pop-up hint"), group);
126 QAction *hintAct = ui->getWindow()->getReadHintEnabledAction();
127 createTwoWayBinding(showHint, hintAct);
128 layout->addWidget(showHint);
129
130 return group;
131 }
132
sl_cellRendererChanged()133 void AssemblySettingsWidget::sl_cellRendererChanged() {
134 QAction *action = qobject_cast<QAction *>(sender());
135 int index = ui->getReadsArea()->getCellRendererActions().indexOf(action);
136 SAFE_POINT(index >= 0, "cell renderer action not found", );
137 readsHighlightCombo->setCurrentIndex(index);
138 }
139
sl_changeCellRenderer(int index)140 void AssemblySettingsWidget::sl_changeCellRenderer(int index) {
141 QList<QAction *> actions = ui->getReadsArea()->getCellRendererActions();
142 CHECK(index >= 0, );
143 SAFE_POINT(index <= actions.count(), "too big cell renderer action index", );
144 QAction *selected = actions.at(index);
145 selected->trigger();
146 AssemblyCellRendererFactory *factory = ui->getWindow()->getCellRendererRegistry()->getFactoryById(AssemblyCellRendererFactory::DIFF_NUCLEOTIDES);
147 if (selected->text() == factory->getName()) {
148 hint->setText(tr("You should add a reference first for correct displaying of selected highlighting"));
149 hint->show();
150 } else {
151 hint->setText("");
152 hint->hide();
153 }
154 }
155
156 // ------- Consensus ----------
157
createConsensusSettings()158 QWidget *AssemblySettingsWidget::createConsensusSettings() {
159 QWidget *group = new QWidget(this);
160 QVBoxLayout *layout = initLayout(group);
161 AssemblyConsensusArea *consensusArea = ui->getConsensusArea();
162
163 layout->addSpacing(TITLE_SPACING);
164
165 layout->addWidget(new QLabel(tr("Consensus algorithm:")));
166
167 algorithmCombo = new QComboBox(group);
168 algorithmCombo->setObjectName("consensusAlgorithmCombo");
169 foreach (QAction *a, consensusArea->getAlgorithmActions()) {
170 algorithmCombo->addItem(a->text());
171 connect(a, SIGNAL(triggered()), SLOT(sl_consensusAlgorithmChanged()));
172 if (a->isChecked()) {
173 algorithmCombo->setCurrentIndex(algorithmCombo->count() - 1);
174 }
175 }
176 connect(algorithmCombo, SIGNAL(currentIndexChanged(int)), SLOT(sl_changeConsensusAlgorithm(int)));
177 layout->addWidget(algorithmCombo);
178
179 layout->addSpacing(ITEMS_SPACING);
180
181 QCheckBox *showDiff = new QCheckBox(tr("Difference from reference"), group);
182 QAction *diffAct = consensusArea->getDiffAction();
183 createTwoWayBinding(showDiff, diffAct);
184 layout->addWidget(showDiff);
185
186 return group;
187 }
188
sl_consensusAlgorithmChanged()189 void AssemblySettingsWidget::sl_consensusAlgorithmChanged() {
190 QAction *action = qobject_cast<QAction *>(sender());
191 int index = ui->getConsensusArea()->getAlgorithmActions().indexOf(action);
192 SAFE_POINT(index >= 0, "consensus algorithm action not found", );
193 algorithmCombo->setCurrentIndex(index);
194 }
195
sl_changeConsensusAlgorithm(int index)196 void AssemblySettingsWidget::sl_changeConsensusAlgorithm(int index) {
197 QList<QAction *> actions = ui->getConsensusArea()->getAlgorithmActions();
198 CHECK(index >= 0, );
199 SAFE_POINT(index <= actions.count(), "too big consensus algorithm action index", );
200 actions.at(index)->trigger();
201 }
202
203 // ------- Ruler ----------
204
createRulerSettings()205 QWidget *AssemblySettingsWidget::createRulerSettings() {
206 QWidget *group = new QWidget(this);
207 QVBoxLayout *layout = initLayout(group);
208 AssemblyBrowser *browser = ui->getWindow();
209
210 layout->addSpacing(TITLE_SPACING);
211
212 QCheckBox *showCoords = new QCheckBox(tr("Show coordinates"), group);
213 QAction *coordAct = browser->getCoordsOnRulerAction();
214 createTwoWayBinding(showCoords, coordAct);
215 layout->addWidget(showCoords);
216
217 layout->addSpacing(ITEMS_SPACING);
218
219 QCheckBox *showCoverage = new QCheckBox(tr("Show coverage under cursor"), group);
220 QAction *coverageAct = browser->getCoverageOnRulerAction();
221 createTwoWayBinding(showCoverage, coverageAct);
222 layout->addWidget(showCoverage);
223
224 return group;
225 }
226
227 //
228 // AssemblySettingsWidgetFactory
229 ////////////////////////////////////
230 const QString AssemblySettingsWidgetFactory::GROUP_ID = "OP_ASS_SETTINGS";
231 const QString AssemblySettingsWidgetFactory::GROUP_ICON_STR = ":core/images/settings2.png";
232 const QString AssemblySettingsWidgetFactory::GROUP_DOC_PAGE = "65929863";
233
AssemblySettingsWidgetFactory()234 AssemblySettingsWidgetFactory::AssemblySettingsWidgetFactory() {
235 objectViewOfWidget = ObjViewType_AssemblyBrowser;
236 }
237
createWidget(GObjectView * objView,const QVariantMap &)238 QWidget *AssemblySettingsWidgetFactory::createWidget(GObjectView *objView, const QVariantMap & /*options*/) {
239 SAFE_POINT(objView != nullptr,
240 QString("Internal error: unable to create widget for group '%1', object view is NULL.").arg(GROUP_ID),
241 nullptr);
242
243 AssemblyBrowser *assemblyBrowser = qobject_cast<AssemblyBrowser *>(objView);
244 SAFE_POINT(assemblyBrowser != nullptr,
245 QString("Internal error: unable to cast object view to Assembly Browser for group '%1'.").arg(GROUP_ID),
246 nullptr);
247
248 return new AssemblySettingsWidget(assemblyBrowser->getMainWidget());
249 }
250
getOPGroupParameters()251 OPGroupParameters AssemblySettingsWidgetFactory::getOPGroupParameters() {
252 return OPGroupParameters(GROUP_ID, QPixmap(GROUP_ICON_STR), QObject::tr("Assembly Browser Settings"), GROUP_DOC_PAGE);
253 }
254
255 } // namespace U2
256