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 #ifndef _U2_QD_SCHEME_H_
23 #define _U2_QD_SCHEME_H_
24 
25 #include <QPair>
26 #include <QSharedData>
27 
28 #include <U2Core/AnnotationData.h>
29 #include <U2Core/DNASequence.h>
30 
31 #include <U2Lang/Configuration.h>
32 
33 namespace U2 {
34 
35 enum QDStrandOption { QDStrand_DirectOnly,
36                       QDStrand_ComplementOnly,
37                       QDStrand_Both };
38 
39 class U2LANG_EXPORT QDParameters : public QObject, public Configuration {
40     Q_OBJECT
41 public:
42     virtual void setParameter(const QString &name, const QVariant &val);
remap(const QMap<ActorId,ActorId> &)43     virtual void remap(const QMap<ActorId, ActorId> &) {
44     }
45 signals:
46     void si_modified();
47 };
48 
49 class U2LANG_EXPORT QDActorParameters : public QDParameters {
50     Q_OBJECT
51 public:
QDActorParameters()52     QDActorParameters()
53         : annKey("misc_feature") {
54     }
setLabel(const QString & l)55     void setLabel(const QString &l) {
56         label = l;
57         emit si_modified();
58     }
getLabel()59     const QString &getLabel() const {
60         return label;
61     }
setAnnotationKey(const QString & key)62     void setAnnotationKey(const QString &key) {
63         annKey = key;
64         emit si_modified();
65     }
getAnnotationKey()66     const QString &getAnnotationKey() const {
67         return annKey;
68     }
69 
70 private:
71     QString label;
72     QString annKey;
73 };
74 
75 class QDSchemeUnit;
76 class U2LANG_EXPORT QDResultUnitData : public QSharedData {
77 public:
QDResultUnitData()78     QDResultUnitData()
79         : owner(nullptr) {
80     }
81 
82     QDSchemeUnit *owner;
83     U2Strand strand;
84     U2Region region;
85     QVector<U2Qualifier> quals;
86 };
87 
88 typedef QSharedDataPointer<QDResultUnitData> QDResultUnit;
89 
90 class U2LANG_EXPORT QDResultGroup {
91 public:
92     QDResultGroup(QDStrandOption _strand = QDStrand_DirectOnly)
strand(_strand)93         : strand(_strand), startPos(0), endPos(0) {
94     }
95     U2Region location() const;
96     void add(const QDResultUnit &res);
97     void add(const QList<QDResultUnit> &res);
98     const QList<QDResultUnit> &getResultsList() const;
99 
100 public:
101     static void buildGroupFromSingleResult(const QDResultUnit &ru, QList<QDResultGroup *> &results);
102 
103 public:
104     QDStrandOption strand;
105 
106 private:
107     int startPos;
108     int endPos;
109     QList<QDResultUnit> results;
110 };
111 
location()112 inline U2Region QDResultGroup::location() const {
113     return U2Region(startPos, endPos - startPos);
114 }
getResultsList()115 inline const QList<QDResultUnit> &QDResultGroup::getResultsList() const {
116     return results;
117 }
118 
119 typedef QPair<QString, QString> StringAttribute;
120 
121 class QDScheme;
122 class QDConstraint;
123 class QDActor;
124 
125 class U2LANG_EXPORT QDActorPrototype {
126 public:
QDActorPrototype()127     QDActorPrototype()
128         : editor(nullptr) {
129     }
130     virtual ~QDActorPrototype();
getParameters()131     const QList<Attribute *> &getParameters() const {
132         return attributes;
133     }
getEditor()134     ConfigurationEditor *getEditor() const {
135         return editor;
136     }
137 
getDescriptor()138     const Descriptor &getDescriptor() const {
139         return descriptor;
140     }
getId()141     QString getId() const {
142         return descriptor.getId();
143     }
getDisplayName()144     QString getDisplayName() const {
145         return descriptor.getDisplayName();
146     }
getIcon()147     virtual QIcon getIcon() const {
148         return QIcon();
149     }
150 
151     virtual QDActor *createInstance() const = 0;
152 
153 protected:
154     QList<Attribute *> attributes;
155     ConfigurationEditor *editor;
156     Descriptor descriptor;
157 };
158 
159 class U2LANG_EXPORT QDActor : public QObject {
160     friend class QDScheme;
161     Q_OBJECT
162 public:
163     QDActor(QDActorPrototype const *proto);
164     virtual ~QDActor();
165 
getScheme()166     QDScheme *getScheme() const {
167         return scheme;
168     }
getProto()169     QDActorPrototype const *getProto() const {
170         return proto;
171     }
getParameters()172     QDActorParameters *getParameters() const {
173         return cfg;
174     }
getUnitId(QDSchemeUnit * su)175     QString getUnitId(QDSchemeUnit *su) const {
176         return units.key(su);
177     }
getSchemeUnit(const QString & id)178     QDSchemeUnit *getSchemeUnit(const QString &id) const {
179         return units.value(id);
180     }
getSchemeUnits()181     QList<QDSchemeUnit *> getSchemeUnits() const {
182         return units.values();
183     }
getParamConstraints()184     const QList<QDConstraint *> &getParamConstraints() const {
185         return paramConstraints;
186     }
187 
188     QDStrandOption getStrand() const;
189     void setStrand(QDStrandOption stOp);
190 
updateEditor()191     virtual void updateEditor() {
192     }
193 
hasAnyDirection()194     bool hasAnyDirection() const {
195         return getStrand() == QDStrand_Both;
196     }
hasForwardDirection()197     bool hasForwardDirection() const {
198         return getStrand() == QDStrand_DirectOnly;
199     }
hasBackwardDirection()200     bool hasBackwardDirection() const {
201         return getStrand() == QDStrand_ComplementOnly;
202     }
203 
isSimmetric()204     bool isSimmetric() const {
205         return simmetric;
206     }
207 
208     QList<QDConstraint *> getConstraints() const;
209 
getActorType()210     QString getActorType() const {
211         return proto->getId();
212     }
annotateAs()213     const QString &annotateAs() const {
214         return cfg->getAnnotationKey();
215     }
216 
217     void filterResults(const QVector<U2Region> &location);
218 
219     QList<QDResultGroup *> popResults();
220     void reset();
221 
222     virtual int getMinResultLen() const = 0;
223     virtual int getMaxResultLen() const = 0;
224     virtual QString getText() const = 0;
225     virtual Task *getAlgorithmTask(const QVector<U2Region> &location) = 0;
hasStrand()226     virtual bool hasStrand() const {
227         return true;
228     }
229     // implement in subclass to provide configuration representation in serialized scheme
230     virtual QList<QPair<QString, QString>> saveConfiguration() const;
231     virtual void loadConfiguration(const QList<QPair<QString, QString>> &strMap);
232     // implement in subclass to customize the color of the visual actor representation
defaultColor()233     virtual QColor defaultColor() const {
234         return QColor(0x98, 0xff, 0xc5);
235     }
236 signals:
237     void si_strandChanged(QDStrandOption);
238 
239 public:
240     static const int DEFAULT_MAX_RESULT_LENGTH;
241 
242 protected:
243     QDStrandOption getStrandToRun() const;
244 
245 protected:
246     QDScheme *scheme;
247     QDActorPrototype const *proto;
248     QDActorParameters *cfg;
249     QMap<QString, QDSchemeUnit *> units;
250     QList<QDConstraint *> paramConstraints;
251     QList<QDResultGroup *> results;
252     QMap<QString, QVariant> defaultCfg;
253     QDStrandOption strand;
254     bool simmetric;
255 };
256 
257 class QDDistanceConstraint;
258 class U2LANG_EXPORT QDSchemeUnit {
259     friend class QDScheme;
260 
261 public:
QDSchemeUnit(QDActor * parent)262     QDSchemeUnit(QDActor *parent)
263         : actor(parent) {
264     }
getConstraints()265     const QList<QDConstraint *> &getConstraints() const {
266         return schemeConstraints;
267     }
268     QList<QDDistanceConstraint *> getDistanceConstraints() const;
getActor()269     QDActor *getActor() const {
270         return actor;
271     }
getId()272     QString getId() const {
273         QDSchemeUnit *thisPtr = const_cast<QDSchemeUnit *>(this);
274         return actor->getUnitId(thisPtr);
275     }
276 
277 private:
278     QDActor *actor;
279     QList<QDConstraint *> schemeConstraints;
280 };
281 
282 class U2LANG_EXPORT QDPath {
283 public:
QDPath()284     QDPath()
285         : pathSrc(nullptr), pathDst(nullptr), overallConstraint(nullptr) {
286     }
287     ~QDPath();
288     QDPath *clone() const;
289     bool addConstraint(QDDistanceConstraint *dc);
getSrc()290     QDSchemeUnit const *getSrc() const {
291         return pathSrc;
292     }
getDst()293     QDSchemeUnit const *getDst() const {
294         return pathDst;
295     }
getConstraints()296     const QList<QDDistanceConstraint *> &getConstraints() const {
297         return constraints;
298     }
299     // returns unsorted list of involved scheme units
getSchemeUnits()300     const QList<QDSchemeUnit *> &getSchemeUnits() const {
301         return schemeUnits;
302     }
303     QDDistanceConstraint *toConstraint();
304 
305 private:
306     QDSchemeUnit *pathSrc;
307     QDSchemeUnit *pathDst;
308     QDDistanceConstraint *overallConstraint;
309     QList<QDDistanceConstraint *> constraints;
310     QList<QDSchemeUnit *> schemeUnits;
311 };
312 
313 class U2SequenceObject;
314 class U2LANG_EXPORT QDScheme : public QObject {
315     Q_OBJECT
316 public:
QDScheme()317     QDScheme()
318         : strand(QDStrand_Both) {
319     }
320     ~QDScheme();
321     void clear();
322     void addActor(QDActor *a);
323     void addConstraint(QDConstraint *constraint);
324     bool removeActor(QDActor *a);
325     void removeConstraint(QDConstraint *constraint);
getSequence()326     const DNASequence &getSequence() const {
327         return dna;
328     }
getEntityRef()329     U2EntityRef getEntityRef() const {
330         return entityRef;
331     }
setSequence(const DNASequence & sequence)332     void setSequence(const DNASequence &sequence) {
333         dna = sequence;
334     }
setEntityRef(const U2EntityRef & _entityRef)335     void setEntityRef(const U2EntityRef &_entityRef) {
336         entityRef = _entityRef;
337     }
getActors()338     const QList<QDActor *> &getActors() const {
339         return actors;
340     }
341     QList<QDConstraint *> getConstraints() const;
342     QList<QDConstraint *> getConstraints(QDSchemeUnit const *su1, QDSchemeUnit const *su2) const;
343     QList<QDPath *> findPaths(QDSchemeUnit *src, QDSchemeUnit *dst);
344     void setOrder(QDActor *a, int serialNum);
isEmpty()345     bool isEmpty() const {
346         return actors.isEmpty();
347     }
348     bool isValid() const;
349     QDActor *getActorByLabel(const QString &label) const;
350 
getStrand()351     QDStrandOption getStrand() const {
352         return strand;
353     }
setStrand(QDStrandOption opt)354     void setStrand(QDStrandOption opt) {
355         strand = opt;
356     }
357 
358     // actor group methods
359     void adaptActorsOrder();
360     QString getActorGroup(QDActor *a) const;
getActorGroups()361     QList<QString> getActorGroups() const {
362         return actorGroups.keys();
363     }
getActors(const QString & group)364     QList<QDActor *> getActors(const QString &group) const {
365         return actorGroups.value(group);
366     }
367     void addActorToGroup(QDActor *a, const QString &group);
368     bool removeActorFromGroup(QDActor *a);
369     void createActorGroup(const QString &name);
370     bool removeActorGroup(const QString &name);
371     bool validateGroupName(const QString &name) const;
getRequiredNumber(const QString & group)372     int getRequiredNumber(const QString &group) const {
373         return actorGroupReqNum.value(group);
374     }
375     void setRequiredNum(const QString &group, int num);
376 signals:
377     void si_schemeChanged();
378 
379 private:
380     void findRoute(QDSchemeUnit *curSu, QDSchemeUnit *routeDst, QList<QDSchemeUnit *>& currentRoute, QList<QList<QDSchemeUnit *>> routes);
381 
382 private:
383     QList<QDActor *> actors;
384     QMap<QString, QList<QDActor *>> actorGroups;
385     QMap<QString, int> actorGroupReqNum;
386     U2EntityRef entityRef;
387     DNASequence dna;
388     QDStrandOption strand;
389 };
390 
391 class U2LANG_EXPORT QDAttributeNameConverter {
392 public:
convertAttrName(const QString & str)393     static QString convertAttrName(const QString &str) {
394         return str.toLower().replace(' ', '_');
395     }
396 };
397 
398 class U2LANG_EXPORT QDAttributeValueMapper {
399 public:
400     enum ValueType { BOOLEAN_TYPE,
401                      UNKNOWN_TYPE };
402 
403     static QVariant stringToAttributeValue(const QString &str);
404     static ValueType getType(const QString &val);
405 
406 public:
407     static const QMap<QString, bool> BOOLEAN_MAP;
408 
409 private:
410     static QMap<QString, bool> initBooleanMap();
411 };
412 
413 }  // namespace U2
414 
415 Q_DECLARE_METATYPE(U2::QDActorPrototype *)
416 
417 #endif
418