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 "Primer3Plugin.h"
23 
24 #include <QAction>
25 #include <QMap>
26 #include <QMenu>
27 #include <QMessageBox>
28 
29 #include <U2Core/AppContext.h>
30 #include <U2Core/GAutoDeleteList.h>
31 #include <U2Core/L10n.h>
32 #include <U2Core/QObjectScopedPointer.h>
33 #include <U2Core/U2OpStatusUtils.h>
34 #include <U2Core/U2SafePoints.h>
35 
36 #include <U2Gui/GUIUtils.h>
37 
38 #include <U2Test/GTest.h>
39 #include <U2Test/GTestFrameworkComponents.h>
40 #include <U2Test/XMLTestFormat.h>
41 
42 #include <U2View/ADVConstants.h>
43 #include <U2View/ADVSequenceObjectContext.h>
44 #include <U2View/ADVUtils.h>
45 #include <U2View/AnnotatedDNAView.h>
46 
47 #include "Primer3Dialog.h"
48 #include "Primer3Query.h"
49 
50 namespace U2 {
51 
U2_PLUGIN_INIT_FUNC()52 extern "C" Q_DECL_EXPORT Plugin *U2_PLUGIN_INIT_FUNC() {
53     Primer3Plugin *plug = new Primer3Plugin();
54     return plug;
55 }
56 
Primer3Plugin()57 Primer3Plugin::Primer3Plugin()
58     : Plugin(tr("Primer3"), tr("Integrated tool for PCR primers design.")), viewCtx(nullptr) {
59     if (AppContext::getMainWindow()) {
60         viewCtx = new Primer3ADVContext(this);
61         viewCtx->init();
62     }
63 
64     QDActorPrototypeRegistry *qdpr = AppContext::getQDActorProtoRegistry();
65     qdpr->registerProto(new QDPrimerActorPrototype());
66 
67     //////////////////////////////////////////////////////////////////////////
68     // tests
69     GTestFormatRegistry *tfr = AppContext::getTestFramework()->getTestFormatRegistry();
70     XMLTestFormat *xmlTestFormat = qobject_cast<XMLTestFormat *>(tfr->findFormat("XML"));
71     assert(xmlTestFormat != nullptr);
72 
73     GAutoDeleteList<XMLTestFactory> *l = new GAutoDeleteList<XMLTestFactory>(this);
74     l->qlist = Primer3Tests::createTestFactories();
75 
76     foreach (XMLTestFactory *f, l->qlist) {
77         bool res = xmlTestFormat->registerTestFactory(f);
78         Q_UNUSED(res);
79         assert(res);
80     }
81 }
82 
~Primer3Plugin()83 Primer3Plugin::~Primer3Plugin() {
84 }
85 
Primer3ADVContext(QObject * p)86 Primer3ADVContext::Primer3ADVContext(QObject *p)
87     : GObjectViewWindowContext(p, ANNOTATED_DNA_VIEW_FACTORY_ID) {
88 }
89 
initViewContext(GObjectView * v)90 void Primer3ADVContext::initViewContext(GObjectView *v) {
91     AnnotatedDNAView *av = qobject_cast<AnnotatedDNAView *>(v);
92     ADVGlobalAction *a = new ADVGlobalAction(av, QIcon(":/primer3/images/primer3.png"), tr("Primer3..."), 95);
93     a->setObjectName("primer3_action");
94     a->addAlphabetFilter(DNAAlphabet_NUCL);
95     connect(a, SIGNAL(triggered()), SLOT(sl_showDialog()));
96 }
97 
sl_showDialog()98 void Primer3ADVContext::sl_showDialog() {
99     QAction *a = (QAction *)sender();
100     GObjectViewAction *viewAction = qobject_cast<GObjectViewAction *>(a);
101     AnnotatedDNAView *av = qobject_cast<AnnotatedDNAView *>(viewAction->getObjectView());
102     assert(av);
103 
104     ADVSequenceObjectContext *seqCtx = av->getActiveSequenceContext();
105     assert(seqCtx->getAlphabet()->isNucleic());
106     {
107         Primer3TaskSettings defaultSettings;
108         {
109             QList<U2Region> sizeRange;
110             sizeRange.append(U2Region(150, 101));  // 150-250
111             sizeRange.append(U2Region(100, 201));  // 100-300
112             sizeRange.append(U2Region(301, 100));  // 301-400
113             sizeRange.append(U2Region(401, 100));  // 401-500
114             sizeRange.append(U2Region(501, 100));  // 501-600
115             sizeRange.append(U2Region(601, 100));  // 601-700
116             sizeRange.append(U2Region(701, 150));  // 701-850
117             sizeRange.append(U2Region(851, 150));  // 851-1000
118             defaultSettings.setProductSizeRange(sizeRange);
119         }
120         defaultSettings.setDoubleProperty("PRIMER_MAX_END_STABILITY", 9.0);
121         defaultSettings.setAlignProperty("PRIMER_MAX_TEMPLATE_MISPRIMING", 1200);
122         defaultSettings.setAlignProperty("PRIMER_PAIR_MAX_TEMPLATE_MISPRIMING", 2400);
123         defaultSettings.setIntProperty("PRIMER_LIBERAL_BASE", 1);
124         defaultSettings.setDoubleProperty("PRIMER_WT_POS_PENALTY", 0.0);
125         defaultSettings.setIntProperty("PRIMER_FIRST_BASE_INDEX", 1);
126 
127         QObjectScopedPointer<Primer3Dialog> dialog = new Primer3Dialog(defaultSettings, seqCtx);
128         dialog->exec();
129         CHECK(!dialog.isNull(), );
130 
131         if (QDialog::Accepted == dialog->result()) {
132             Primer3TaskSettings settings = dialog->getSettings();
133             U2OpStatusImpl os;
134             QByteArray seqData = seqCtx->getSequenceObject()->getWholeSequenceData(os);
135             CHECK_OP_EXT(os, QMessageBox::critical(QApplication::activeWindow(), L10N::errorTitle(), os.getError()), );
136             settings.setSequence(seqData,
137                                  seqCtx->getSequenceObject()->isCircular());
138             QString err = dialog->checkModel();
139             if (!err.isEmpty()) {
140                 QMessageBox::warning(QApplication::activeWindow(), dialog->windowTitle(), err);
141                 return;
142             }
143             bool objectPrepared = dialog->prepareAnnotationObject();
144             if (!objectPrepared) {
145                 QMessageBox::warning(QApplication::activeWindow(), tr("Error"), tr("Cannot create an annotation object. Please check settings"));
146                 return;
147             }
148             const CreateAnnotationModel &model = dialog->getCreateAnnotationModel();
149             AppContext::getTaskScheduler()->registerTopLevelTask(new Primer3ToAnnotationsTask(settings, seqCtx->getSequenceObject(), model.getAnnotationObject(), model.groupName, model.data->name, model.description));
150         }
151     }
152 }
153 
createTestFactories()154 QList<XMLTestFactory *> Primer3Tests::createTestFactories() {
155     QList<XMLTestFactory *> res;
156     res.append(GTest_Primer3::createFactory());
157     return res;
158 }
159 
160 }  // namespace U2
161