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 "BuildIndexDialog.h"
23
24 #include <QMessageBox>
25 #include <QPushButton>
26
27 #include <U2Algorithm/DnaAssemblyAlgRegistry.h>
28
29 #include <U2Core/AppContext.h>
30 #include <U2Core/DocumentUtils.h>
31 #include <U2Core/ExternalToolRegistry.h>
32 #include <U2Core/GUrlUtils.h>
33 #include <U2Core/QObjectScopedPointer.h>
34 #include <U2Core/U2SafePoints.h>
35
36 #include <U2Gui/AppSettingsGUI.h>
37 #include <U2Gui/HelpButton.h>
38 #include <U2Gui/LastUsedDirHelper.h>
39 #include <U2Gui/U2FileDialog.h>
40
41 #include "DnaAssemblyGUIExtension.h"
42
43 namespace U2 {
44
45 QString BuildIndexDialog::genomePath;
46
BuildIndexDialog(const DnaAssemblyAlgRegistry * registry,QWidget * p)47 BuildIndexDialog::BuildIndexDialog(const DnaAssemblyAlgRegistry *registry, QWidget *p)
48 : QDialog(p), assemblyRegistry(registry), customGUI(nullptr) {
49 setupUi(this);
50 QMap<QString, QString> helpPagesMap;
51 helpPagesMap.insert("BWA", "65930872");
52 helpPagesMap.insert("BWA-MEM", "65930886");
53 helpPagesMap.insert("BWA-SW", "65930879");
54 helpPagesMap.insert("Bowtie", "65930855");
55 helpPagesMap.insert("Bowtie2", "65930864");
56 helpPagesMap.insert("UGENE Genome Aligner", "65930893");
57 new ComboboxDependentHelpButton(this, buttonBox, methodNamesBox, helpPagesMap);
58 buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Start"));
59 buttonBox->button(QDialogButtonBox::Cancel)->setText(tr("Cancel"));
60
61 QStringList names = registry->getRegisteredAlgorithmsWithIndexFileSupport();
62 methodNamesBox->addItems(names);
63 // TODO: change the way default method is set
64 if (names.size() > 0) {
65 methodNamesBox->setCurrentIndex(names.size() - 1);
66 }
67 sl_onAlgorithmChanged(methodNamesBox->currentText());
68 connect(setIndexFileNameButton, SIGNAL(clicked()), SLOT(sl_onSetIndexFileNameButtonClicked()));
69 connect(addRefButton, SIGNAL(clicked()), SLOT(sl_onAddRefButtonClicked()));
70 connect(methodNamesBox, SIGNAL(currentIndexChanged(const QString &)), SLOT(sl_onAlgorithmChanged(const QString &)));
71
72 if (!genomePath.isEmpty()) {
73 refSeqEdit->setText(genomePath);
74 buildIndexUrl(genomePath);
75 SAFE_POINT(nullptr != customGUI, "Build Index dialog referenced null pointer", );
76 customGUI->validateReferenceSequence(genomePath);
77 }
78 }
79
sl_onAddRefButtonClicked()80 void BuildIndexDialog::sl_onAddRefButtonClicked() {
81 LastUsedDirHelper lod;
82 QString filter;
83
84 if (qgetenv(ENV_GUI_TEST).toInt() == 1 && qgetenv(ENV_USE_NATIVE_DIALOGS).toInt() == 0) {
85 lod.url = U2FileDialog::getOpenFileName(this, tr("Open reference sequence"), lod.dir, filter, 0, QFileDialog::DontUseNativeDialog);
86 } else {
87 lod.url = U2FileDialog::getOpenFileName(this, tr("Open reference sequence"), lod.dir, filter);
88 }
89 if (lod.url.isEmpty()) {
90 return;
91 }
92
93 if (nullptr != customGUI) {
94 customGUI->validateReferenceSequence(GUrl(lod.url));
95 }
96 refSeqEdit->setText(lod.url);
97 buildIndexUrl(lod.url);
98 }
99
sl_onSetIndexFileNameButtonClicked()100 void BuildIndexDialog::sl_onSetIndexFileNameButtonClicked() {
101 LastUsedDirHelper lod;
102 lod.url = U2FileDialog::getSaveFileName(this, tr("Set index file name"), lod.dir);
103 if (!lod.url.isEmpty()) {
104 GUrl index = lod.url;
105 if (index.lastFileSuffix().isEmpty() && customGUI != nullptr) {
106 QString extension = customGUI->getIndexFileExtension();
107 if (extension.isEmpty()) {
108 index = QString("%1").arg(index.getURLString());
109 } else {
110 index = QString("%1.%2").arg(index.getURLString()).arg(extension);
111 }
112 }
113 indexFileNameEdit->setText(index.getURLString());
114 }
115 }
116
sl_onAlgorithmChanged(const QString &)117 void BuildIndexDialog::sl_onAlgorithmChanged(const QString &) {
118 updateState();
119 }
120
updateState()121 void BuildIndexDialog::updateState() {
122 addGuiExtension();
123 }
124
addGuiExtension()125 void BuildIndexDialog::addGuiExtension() {
126 // cleanup previous extension
127 if (customGUI != nullptr) {
128 layout()->removeWidget(customGUI);
129 setMinimumHeight(minimumHeight() - customGUI->minimumHeight());
130 delete customGUI;
131 customGUI = nullptr;
132 }
133
134 // insert new extension widget
135 DnaAssemblyAlgorithmEnv *env = assemblyRegistry->getAlgorithm(methodNamesBox->currentText());
136 if (nullptr == env) {
137 adjustSize();
138 return;
139 }
140 DnaAssemblyGUIExtensionsFactory *gui = env->getGUIExtFactory();
141 if (gui != nullptr && gui->hasBuildIndexWidget()) {
142 customGUI = gui->createBuildIndexWidget(this);
143 int insertPos = verticalLayout->count() - 1;
144 verticalLayout->insertWidget(insertPos, customGUI);
145 if (!refSeqEdit->text().isEmpty()) {
146 buildIndexUrl(refSeqEdit->text());
147 customGUI->validateReferenceSequence(GUrl(refSeqEdit->text()));
148 }
149 customGUI->show();
150 }
151 adjustSize();
152 }
153
buildIndexUrl(const GUrl & refUrl)154 void BuildIndexDialog::buildIndexUrl(const GUrl &refUrl) {
155 QString extension("");
156 GUrl url;
157 if (nullptr != customGUI) {
158 extension = customGUI->getIndexFileExtension();
159 url = customGUI->buildIndexUrl(refUrl);
160 }
161 if (url.isEmpty()) {
162 if (extension.isEmpty()) {
163 url = GUrlUtils::rollFileName(refUrl.dirPath() + "/" + refUrl.baseFileName(), DocumentUtils::getNewDocFileNameExcludesHint());
164 } else {
165 url = GUrlUtils::rollFileName(refUrl.dirPath() + "/" + refUrl.baseFileName() + "." + extension, DocumentUtils::getNewDocFileNameExcludesHint());
166 }
167 }
168
169 indexFileNameEdit->setText(url.getURLString());
170 }
171
accept()172 void BuildIndexDialog::accept() {
173 if ((getAlgorithmName() == "Bowtie") || (getAlgorithmName() == "Bowtie2") || (getAlgorithmName() == "BWA") || (getAlgorithmName() == "BWA-MEM") || (getAlgorithmName() == "BWA-SW")) {
174 QString externalToolId;
175
176 if (getAlgorithmName() == "Bowtie2") {
177 externalToolId = "USUPP_BOWTIE2_BUILD";
178 }
179 if (getAlgorithmName() == "Bowtie") {
180 externalToolId = "USUPP_BOWTIE_BUILD";
181 }
182 if ((getAlgorithmName() == "BWA") || (getAlgorithmName() == "BWA-MEM") || (getAlgorithmName() == "BWA-SW")) {
183 externalToolId = "USUPP_BWA";
184 }
185 if (AppContext::getExternalToolRegistry()->getById(externalToolId)->getPath().isEmpty()) {
186 QObjectScopedPointer<QMessageBox> msgBox = new QMessageBox(this);
187 msgBox->setWindowTitle(tr("DNA Assembly"));
188 msgBox->setInformativeText(tr("Do you want to select it now?"));
189 msgBox->setStandardButtons(QMessageBox::Yes | QMessageBox::No);
190 msgBox->setDefaultButton(QMessageBox::Yes);
191 msgBox->setText(tr(QString("Path for <i>" + AppContext::getExternalToolRegistry()->getToolNameById(externalToolId) + "</i> tool is not selected.").toLatin1().data()));
192 const int ret = msgBox->exec();
193 CHECK(!msgBox.isNull(), );
194
195 switch (ret) {
196 case QMessageBox::Yes:
197 AppContext::getAppSettingsGUI()->showSettingsDialog(APP_SETTINGS_EXTERNAL_TOOLS);
198 break;
199 case QMessageBox::No:
200 return;
201 break;
202 default:
203 assert(false);
204 break;
205 }
206 if (AppContext::getExternalToolRegistry()->getById(externalToolId)->getPath().isEmpty()) {
207 return;
208 }
209 }
210 }
211 if (refSeqEdit->text().isEmpty()) {
212 QMessageBox::information(this, tr("Build Index"), tr("Reference sequence url is not set!"));
213 } else if (indexFileNameEdit->text().isEmpty()) {
214 QMessageBox::information(this, tr("Build Index"), tr("Index file name is not set!"));
215 } else {
216 genomePath.clear();
217 genomePath = refSeqEdit->text();
218
219 QDialog::accept();
220 }
221 }
222
getRefSeqUrl()223 const GUrl BuildIndexDialog::getRefSeqUrl() {
224 return refSeqEdit->text();
225 }
226
getAlgorithmName()227 const QString BuildIndexDialog::getAlgorithmName() {
228 return methodNamesBox->currentText();
229 }
230
getIndexFileName()231 const QString BuildIndexDialog::getIndexFileName() {
232 return indexFileNameEdit->text();
233 }
234
getCustomSettings()235 QMap<QString, QVariant> BuildIndexDialog::getCustomSettings() {
236 if (customGUI != nullptr) {
237 return customGUI->getBuildIndexCustomSettings();
238 } else {
239 return QMap<QString, QVariant>();
240 }
241 }
242
243 } // namespace U2
244