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 "AnnotHighlightWidget.h"
23 #include <limits.h>
24
25 #include <QPushButton>
26
27 #include <U2Core/AnnotationSelection.h>
28 #include <U2Core/AnnotationSettings.h>
29 #include <U2Core/AnnotationTableObject.h>
30 #include <U2Core/AppContext.h>
31 #include <U2Core/Counter.h>
32 #include <U2Core/DNAAlphabet.h>
33 #include <U2Core/U1AnnotationUtils.h>
34 #include <U2Core/U2SafePoints.h>
35
36 #include <U2View/ADVSequenceObjectContext.h>
37 #include <U2View/ADVSingleSequenceWidget.h>
38 #include <U2View/AnnotatedDNAView.h>
39 #include <U2View/PanView.h>
40
41 namespace U2 {
42
ShowAllAnnotTypesLabel()43 ShowAllAnnotTypesLabel::ShowAllAnnotTypesLabel() {
44 // By default, show only types for the sequence
45 showAllIsSelected = false;
46 setText(QObject::tr("Show all annotation names"));
47
48 setStyleSheet(
49 "text-decoration: underline;"
50 "color: gray;"
51 "margin-left: 2px;"
52 "margin-top: 1px;");
53 }
54
mousePressEvent(QMouseEvent * event)55 void ShowAllAnnotTypesLabel::mousePressEvent(QMouseEvent *event) {
56 Q_UNUSED(event);
57 if (showAllIsSelected) {
58 showAllIsSelected = false;
59 setText(QObject::tr("Show all annotation names"));
60 } else {
61 showAllIsSelected = true;
62 setText(QObject::tr("Show names for the sequence only"));
63 }
64
65 emit si_showAllStateChanged();
66 }
67
AnnotHighlightWidget(AnnotatedDNAView * _annotatedDnaView)68 AnnotHighlightWidget::AnnotHighlightWidget(AnnotatedDNAView *_annotatedDnaView)
69 : annotatedDnaView(_annotatedDnaView) {
70 SAFE_POINT(0 != annotatedDnaView, "AnnotatedDNAView is NULL!", );
71 initLayout();
72 connectSlots();
73 loadAnnotTypes();
74 }
75
initLayout()76 void AnnotHighlightWidget::initLayout() {
77 QVBoxLayout *mainLayout = new QVBoxLayout();
78 mainLayout->setContentsMargins(0, 0, 0, 0);
79 mainLayout->setSpacing(10);
80 mainLayout->setSizeConstraint(QLayout::SetMinAndMaxSize);
81
82 noAnnotTypesLabel = new QLabel("");
83 noAnnotTypesLabel->setWordWrap(true);
84 setNoAnnotTypesLabelValue();
85 noAnnotTypesLabel->setStyleSheet("margin-left: 2px;");
86 noAnnotTypesLabel->setObjectName("noAnnotTypesLabel");
87
88 annotTreeTitle = new QLabel(tr("Select an annotation name:"));
89
90 // Tree
91 QVBoxLayout *treeLayout = new QVBoxLayout();
92 treeLayout->setContentsMargins(0, 0, 0, 10);
93 treeLayout->setSpacing(0);
94
95 annotTree = new AnnotHighlightTree();
96
97 showAllLabel = new ShowAllAnnotTypesLabel();
98 showAllLabel->setObjectName("show_all_annotation_types");
99
100 treeLayout->addWidget(annotTree);
101 treeLayout->addWidget(showAllLabel);
102
103 // Configure settings
104 QVBoxLayout *settingsLayout = new QVBoxLayout();
105 settingsLayout->setContentsMargins(0, 0, 0, 0);
106 settingsLayout->setSpacing(0);
107 settingsLayout->setSizeConstraint(QLayout::SetMinAndMaxSize);
108
109 settingsTitle = new QLabel(tr("Configure the annotations:"));
110 annotSettingsWidget = new AnnotHighlightSettingsWidget();
111
112 settingsLayout->addWidget(settingsTitle);
113 settingsLayout->addWidget(annotSettingsWidget);
114
115 QHBoxLayout *buttonsLayout = new QHBoxLayout();
116 buttonsLayout->setContentsMargins(0, 0, 0, 0);
117 buttonsLayout->setSpacing(0);
118
119 prevAnnotationButton = new QPushButton(QIcon(":core/images/backward.png"), "");
120 prevAnnotationButton->setFixedSize(32, 32);
121 prevAnnotationButton->setToolTip(AnnotHighlightWidget::tr("Previous annotation"));
122 prevAnnotationButton->setDisabled(true);
123 prevAnnotationButton->setObjectName("prevAnnotationButton");
124 buttonsLayout->addWidget(prevAnnotationButton);
125 buttonsLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
126
127 nextAnnotationButton = new QPushButton(QIcon(":core/images/forward.png"), "");
128 nextAnnotationButton->setFixedSize(32, 32);
129 nextAnnotationButton->setToolTip(AnnotHighlightWidget::tr("Next annotation"));
130 nextAnnotationButton->setObjectName("nextAnnotationButton");
131 buttonsLayout->addWidget(nextAnnotationButton);
132 if (noAnnotatedRegions()) {
133 nextAnnotationButton->setDisabled(true);
134 } else {
135 sl_onAnnotationSelectionChanged();
136 }
137
138 // Init main layout
139 mainLayout->addWidget(noAnnotTypesLabel);
140 mainLayout->addWidget(annotTreeTitle);
141 mainLayout->addLayout(treeLayout);
142 mainLayout->addLayout(settingsLayout);
143 mainLayout->addLayout(buttonsLayout);
144
145 setLayout(mainLayout);
146 }
147
isFirstAnnotatedRegion(Annotation * annotation,const U2Region & region,bool fromTheBeginning) const148 bool AnnotHighlightWidget::isFirstAnnotatedRegion(Annotation *annotation, const U2Region ®ion, bool fromTheBeginning) const {
149 AnnotatedRegion annRegion;
150 if (findFirstAnnotatedRegion(annRegion, fromTheBeginning)) {
151 if (annRegion.annotation == annotation) {
152 SAFE_POINT(annRegion.annotation->getRegions().size() > annRegion.regionIdx, "Invalid annotation region", false);
153 if (annRegion.annotation->getRegions()[annRegion.regionIdx] == region) {
154 return true;
155 }
156 }
157 }
158 return false;
159 }
160
noAnnotatedRegions() const161 bool AnnotHighlightWidget::noAnnotatedRegions() const {
162 const QList<AnnotationTableObject *> items = annotatedDnaView->getAnnotationObjects(true);
163 foreach (AnnotationTableObject *object, items) {
164 SAFE_POINT(object != nullptr, "Annotation table object is NULL", true);
165 if (object->hasAnnotations()) {
166 return false;
167 }
168 }
169 return true;
170 }
171
selectNextAnnotation(bool isForward) const172 void AnnotHighlightWidget::selectNextAnnotation(bool isForward) const {
173 AnnotationSelection *as = annotatedDnaView->getAnnotationsSelection();
174 CHECK(as != nullptr, );
175
176 bool isAnnRegionValid = false;
177 AnnotatedRegion annRegion;
178
179 if (as->isEmpty() && isForward) {
180 // no selected annotation regions - choose first one
181 isAnnRegionValid = findFirstAnnotatedRegion(annRegion);
182 } else {
183 // choose next acoording to selection
184 isAnnRegionValid = findNextUnselectedAnnotatedRegion(annRegion, isForward);
185 }
186
187 if (isAnnRegionValid) {
188 as->clear();
189 as->add(annRegion.annotation);
190 }
191 return;
192 }
193
findFirstAnnotatedRegion(AnnotatedRegion & annRegion,bool fromTheBeginging) const194 bool AnnotHighlightWidget::findFirstAnnotatedRegion(AnnotatedRegion &annRegion, bool fromTheBeginging) const {
195 return findFirstAnnotatedRegionAfterPos(annRegion,
196 fromTheBeginging ? -1 : LLONG_MAX,
197 fromTheBeginging);
198 }
199
findFirstAnnotatedRegionAfterPos(AnnotatedRegion & annRegion,qint64 startPos,bool isForward) const200 bool AnnotHighlightWidget::findFirstAnnotatedRegionAfterPos(AnnotatedRegion &annRegion, qint64 startPos, bool isForward) const {
201 qint64 boundary = isForward ? LLONG_MAX : -1;
202 qint64 sign = isForward ? 1 : -1;
203 qint64 pos = boundary;
204
205 const QList<AnnotationTableObject *> annObjects = annotatedDnaView->getAnnotationObjects(true);
206 foreach (AnnotationTableObject *annObject, annObjects) {
207 SAFE_POINT(annotatedDnaView->getSequenceContext(annObject) != nullptr, tr("Sequence context is NULL"), false);
208 qint64 seqLen = annotatedDnaView->getSequenceContext(annObject)->getSequenceLength();
209 QList<Annotation *> annots = annObject->getAnnotationsByRegion(U2Region(isForward ? startPos : 0, isForward ? seqLen - startPos : startPos));
210 foreach (Annotation *a, annots) {
211 QVector<U2Region> regions = a->getRegions();
212 for (int i = 0; i < regions.size(); i++) {
213 if (sign * regions[i].startPos > sign * startPos && sign * regions[i].startPos < sign * pos) {
214 pos = regions[i].startPos;
215 annRegion.annotation = a;
216 annRegion.regionIdx = i;
217 }
218 }
219 }
220 }
221
222 if (pos == boundary) {
223 return false;
224 }
225
226 QList<AnnotatedRegion> regionsAtTheSamePosition = getAllAnnotatedRegionsByStartPos(pos);
227 if (!regionsAtTheSamePosition.isEmpty()) {
228 annRegion = regionsAtTheSamePosition[isForward ? 0 : (regionsAtTheSamePosition.size() - 1)];
229 return true;
230 }
231
232 return false;
233 }
234
findNextUnselectedAnnotatedRegion(AnnotatedRegion & annRegion,bool fromTheBeginning) const235 bool AnnotHighlightWidget::findNextUnselectedAnnotatedRegion(AnnotatedRegion &annRegion, bool fromTheBeginning) const {
236 AnnotationSelection *as = annotatedDnaView->getAnnotationsSelection();
237 CHECK(as != nullptr, false);
238 CHECK(!as->isEmpty(), false);
239
240 // detect the most right/left start position in selection
241 const QList<Annotation *> selectionData = as->getAnnotations();
242 int start = -1;
243 foreach (Annotation *selectionItem, selectionData) {
244 foreach (U2Region region, selectionItem->getRegions()) {
245 if (start == -1) {
246 start = region.startPos;
247 } else {
248 if ((region.startPos - start) * (fromTheBeginning ? 1 : -1) > 0) {
249 start = region.startPos;
250 }
251 }
252 }
253 }
254
255 QList<AnnotatedRegion> regionsAtTheSamePosition = getAllAnnotatedRegionsByStartPos(start);
256 // find the next unselected
257 for (int i = 0; i < regionsAtTheSamePosition.size(); i++) {
258 int idx = fromTheBeginning ? regionsAtTheSamePosition.size() - 1 - i : i;
259 if (as->contains(regionsAtTheSamePosition[idx].annotation)) {
260 idx += (fromTheBeginning ? 1 : -1);
261 if (idx < 0 || idx == regionsAtTheSamePosition.size()) {
262 break;
263 }
264 annRegion = regionsAtTheSamePosition[idx];
265 return true;
266 }
267 }
268
269 return findFirstAnnotatedRegionAfterPos(annRegion, start, fromTheBeginning);
270 }
271
getAllAnnotatedRegionsByStartPos(qint64 startPos) const272 QList<AnnotatedRegion> AnnotHighlightWidget::getAllAnnotatedRegionsByStartPos(qint64 startPos) const {
273 const QList<AnnotationTableObject *> annObjects = annotatedDnaView->getAnnotationObjects(true);
274 return U1AnnotationUtils::getAnnotatedRegionsByStartPos(annObjects, startPos);
275 }
276
sl_onNextAnnotationClick()277 void AnnotHighlightWidget::sl_onNextAnnotationClick() {
278 GCOUNTER(cvar, "Annotations navigation: next annotation");
279 selectNextAnnotation(true);
280 }
281
sl_onPrevAnnotationClick()282 void AnnotHighlightWidget::sl_onPrevAnnotationClick() {
283 GCOUNTER(cvar, "Annotations navigation: previous annotation");
284 selectNextAnnotation(false);
285 }
286
sl_onAnnotationSelectionChanged()287 void AnnotHighlightWidget::sl_onAnnotationSelectionChanged() {
288 AnnotationSelection *as = annotatedDnaView->getAnnotationsSelection();
289 CHECK(as != nullptr, );
290
291 if (as->isEmpty()) {
292 nextAnnotationButton->setDisabled(noAnnotatedRegions());
293 prevAnnotationButton->setDisabled(true);
294 } else {
295 nextAnnotationButton->setDisabled(false);
296 prevAnnotationButton->setDisabled(false);
297
298 // find first or last annotation region
299 foreach (Annotation *a, as->getAnnotations()) {
300 foreach (U2Region region, a->getRegions()) {
301 if (isFirstAnnotatedRegion(a, region, false)) {
302 nextAnnotationButton->setDisabled(true);
303 }
304 if (isFirstAnnotatedRegion(a, region)) {
305 prevAnnotationButton->setDisabled(true);
306 }
307 }
308 }
309 }
310 }
311
setNoAnnotTypesLabelValue()312 void AnnotHighlightWidget::setNoAnnotTypesLabelValue() {
313 QList<ADVSequenceObjectContext *> seqContexts = annotatedDnaView->getSequenceContexts();
314
315 if (1 == seqContexts.count()) {
316 noAnnotTypesLabel->setText(tr("The sequence doesn't have any annotations."));
317 } else {
318 noAnnotTypesLabel->setText(tr("The sequences do not have any annotations."));
319 }
320 }
321
setNoAnnotsLayout()322 void AnnotHighlightWidget::setNoAnnotsLayout() {
323 noAnnotTypesLabel->show();
324 annotTreeTitle->hide();
325 annotTree->hide();
326 settingsTitle->hide();
327 annotSettingsWidget->hide();
328 }
329
setLayoutWithAnnotsSelection()330 void AnnotHighlightWidget::setLayoutWithAnnotsSelection() {
331 noAnnotTypesLabel->hide();
332 annotTreeTitle->show();
333 annotTree->show();
334 settingsTitle->show();
335 annotSettingsWidget->show();
336 }
337
connectSlots()338 void AnnotHighlightWidget::connectSlots() {
339 // Show annotation types for the sequence or all annotation types
340 connect(showAllLabel, SIGNAL(si_showAllStateChanged()), this, SLOT(sl_onShowAllStateChanged()));
341
342 // Selected annotation type has changed
343 connect(annotTree, SIGNAL(si_selectedItemChanged(QString)), SLOT(sl_onSelectedItemChanged(QString)));
344
345 // Another color or a setting has been selected for an annotation type
346 connect(annotTree, SIGNAL(si_colorChanged(QString, QColor)), SLOT(sl_storeNewColor(QString, QColor)));
347 connect(annotSettingsWidget, SIGNAL(si_annotSettingsChanged(AnnotationSettings *)), SLOT(sl_storeNewSettings(AnnotationSettings *)));
348
349 // A sequence has been modified (a subsequence added, removed, etc.)
350 connect(annotatedDnaView, SIGNAL(si_sequenceModified(ADVSequenceObjectContext *)), this, SLOT(sl_onSequenceModified(ADVSequenceObjectContext *)));
351
352 // An annotation object has been added/removed - connect/disconnect slots
353 connect(annotatedDnaView, SIGNAL(si_annotationObjectAdded(AnnotationTableObject *)), SLOT(sl_onAnnotationObjectAdded(AnnotationTableObject *)));
354 connect(annotatedDnaView, SIGNAL(si_annotationObjectRemoved(AnnotationTableObject *)), SLOT(sl_onAnnotationObjectRemoved(AnnotationTableObject *)));
355
356 // An annotation has been added/removed/modified
357 QList<AnnotationTableObject *> seqAnnotTableObjs = annotatedDnaView->getAnnotationObjects(true); // "true" to include auto-annotations
358 foreach (const AnnotationTableObject *annotTableObj, seqAnnotTableObjs) {
359 connectSlotsForAnnotTableObj(annotTableObj);
360 }
361
362 connect(prevAnnotationButton, SIGNAL(clicked()), this, SLOT(sl_onPrevAnnotationClick()));
363
364 connect(nextAnnotationButton, SIGNAL(clicked()), this, SLOT(sl_onNextAnnotationClick()));
365
366 AnnotationSelection *as = annotatedDnaView->getAnnotationsSelection();
367 CHECK(as != nullptr, );
368 connect(as, SIGNAL(si_selectionChanged(AnnotationSelection *, const QList<Annotation *> &, const QList<Annotation *> &)), SLOT(sl_onAnnotationSelectionChanged()));
369 }
370
connectSlotsForAnnotTableObj(const AnnotationTableObject * annotTableObj)371 void AnnotHighlightWidget::connectSlotsForAnnotTableObj(const AnnotationTableObject *annotTableObj) {
372 connect(annotTableObj, SIGNAL(si_onAnnotationsAdded(const QList<Annotation *> &)), SLOT(sl_onAnnotationsAdded(const QList<Annotation *> &)));
373 connect(annotTableObj, SIGNAL(si_onAnnotationsRemoved(const QList<Annotation *> &)), SLOT(sl_onAnnotationsRemoved(const QList<Annotation *> &)));
374 connect(annotTableObj, SIGNAL(si_onAnnotationsModified(const QList<AnnotationModification> &)), SLOT(sl_onAnnotationsModified()));
375 }
376
disconnectSlotsForAnnotTableObj(const AnnotationTableObject * annotTableObj)377 void AnnotHighlightWidget::disconnectSlotsForAnnotTableObj(const AnnotationTableObject *annotTableObj) {
378 disconnect(annotTableObj, SIGNAL(si_onAnnotationsAdded(const QList<Annotation *> &)), this, SLOT(sl_onAnnotationsAdded(const QList<Annotation *> &)));
379 disconnect(annotTableObj, SIGNAL(si_onAnnotationsRemoved(const QList<Annotation *> &)), this, SLOT(sl_onAnnotationsRemoved(const QList<Annotation *> &)));
380 disconnect(annotTableObj, SIGNAL(si_onAnnotationsModified(const QList<AnnotationModification> &)), this, SLOT(sl_onAnnotationsModified()));
381 }
382
sl_onShowAllStateChanged()383 void AnnotHighlightWidget::sl_onShowAllStateChanged() {
384 loadAnnotTypes();
385 }
386
sl_onSelectedItemChanged(const QString & annotName)387 void AnnotHighlightWidget::sl_onSelectedItemChanged(const QString &annotName) {
388 AnnotationSettingsRegistry *annotRegistry = AppContext::getAnnotationsSettingsRegistry();
389
390 AnnotationSettings *selectedAnnotSettings = annotRegistry->getAnnotationSettings(annotName);
391 annotSettingsWidget->setSettings(selectedAnnotSettings, annotNamesWithAminoInfo.value(annotName));
392 }
393
findAllAnnotationsNamesForSequence()394 void AnnotHighlightWidget::findAllAnnotationsNamesForSequence() {
395 annotNamesWithAminoInfo.clear();
396
397 QList<ADVSequenceObjectContext *> seqObjContexts = annotatedDnaView->getSequenceContexts();
398
399 foreach (ADVSequenceObjectContext *seqContext, seqObjContexts) {
400 const DNAAlphabet *seqAlphabet = seqContext->getAlphabet();
401 bool isAminoSeq = seqAlphabet->isAmino();
402
403 QSet<AnnotationTableObject *> seqAnnotTableObjects = seqContext->getAnnotationObjects(true);
404
405 foreach (AnnotationTableObject *annotTableObj, seqAnnotTableObjects) {
406 const QList<Annotation *> annotations = annotTableObj->getAnnotations();
407
408 foreach (Annotation *annot, annotations) {
409 const QString annotName = annot->getName();
410
411 // If the annotation was found on a nucleotide sequence
412 if (!isAminoSeq) {
413 // The "Show on translation" option should be enabled for this annotation type
414 annotNamesWithAminoInfo.insert(annotName, false);
415 }
416 // The annotation was found on an amino acid sequence
417 else {
418 if (annotNamesWithAminoInfo.contains(annotName)) {
419 // Do nothing:
420 // if the value is "true", then it doesn't make sense to rewrite the same value
421 // if the value is "false", then the annotation was previously found on a nucleotide
422 // sequence and therefore the "Show on translation" option should be enabled
423 } else {
424 // Disable the option
425 annotNamesWithAminoInfo.insert(annotName, true);
426 }
427 }
428 }
429 }
430 }
431 }
432
findAllAnnotationsNamesInSettings()433 void AnnotHighlightWidget::findAllAnnotationsNamesInSettings() {
434 annotNamesWithAminoInfo.clear();
435
436 AnnotationSettingsRegistry *registry = AppContext::getAnnotationsSettingsRegistry();
437 SAFE_POINT(0 != registry, "AnnotationSettingsRegistry is NULL!", );
438
439 QStringList annotSettings = registry->getAllSettings();
440 foreach (QString setting, annotSettings) {
441 annotNamesWithAminoInfo.insert(setting, false);
442 }
443 }
444
updateAnnotationNames()445 void AnnotHighlightWidget::updateAnnotationNames() {
446 if (showAllLabel->isShowAllSelected()) {
447 findAllAnnotationsNamesInSettings();
448 } else {
449 findAllAnnotationsNamesForSequence();
450 }
451 }
452
loadAnnotTypes()453 void AnnotHighlightWidget::loadAnnotTypes() {
454 // Get the annotation names
455 updateAnnotationNames();
456
457 QList<QString> annotNames = annotNamesWithAminoInfo.keys();
458 std::sort(annotNames.begin(), annotNames.end());
459
460 // Get the currently selected annotation name
461 QString currentAnnotName = annotTree->getCurrentItemAnnotName();
462
463 // Clear the old items and restore the initial height
464 annotTree->clear();
465
466 // If there types to show
467 if (!annotNames.isEmpty()) {
468 setLayoutWithAnnotsSelection();
469
470 // Add the tree items
471 AnnotationSettingsRegistry *annotRegistry = AppContext::getAnnotationsSettingsRegistry();
472 foreach (const QString &name, annotNames) {
473 AnnotationSettings *annotSettings = annotRegistry->getAnnotationSettings(name);
474 annotTree->addItem(name, annotSettings->color);
475 }
476
477 // By default, select either previously selected item (if it is present) or the first item
478 if (annotNames.contains(currentAnnotName)) {
479 annotTree->setItemSelectedWithAnnotName(currentAnnotName);
480 } else {
481 annotTree->setFirstItemSelected();
482 currentAnnotName = annotTree->getFirstItemAnnotName();
483 SAFE_POINT(currentAnnotName != QString(), "Failed to get first annotation name!", );
484 }
485
486 // Set the configuration settings for the item
487 AnnotationSettings *currentAnnotSettings = annotRegistry->getAnnotationSettings(currentAnnotName);
488 annotSettingsWidget->setSettings(currentAnnotSettings, annotNamesWithAminoInfo.value(currentAnnotName));
489 } else {
490 setNoAnnotsLayout();
491 }
492
493 if (noAnnotatedRegions()) {
494 nextAnnotationButton->setDisabled(true);
495 }
496 }
497
sl_storeNewColor(const QString & annotName,const QColor & newColor)498 void AnnotHighlightWidget::sl_storeNewColor(const QString &annotName, const QColor &newColor) {
499 QList<AnnotationSettings *> annotToWrite;
500 AnnotationSettingsRegistry *annotRegistry = AppContext::getAnnotationsSettingsRegistry();
501 AnnotationSettings *annotSettings = annotRegistry->getAnnotationSettings(annotName);
502 if (annotSettings->color != newColor) {
503 annotSettings->color = newColor;
504 annotToWrite.append(annotSettings);
505 annotRegistry->changeSettings(annotToWrite, true);
506 }
507 }
508
sl_storeNewSettings(AnnotationSettings * annotSettings)509 void AnnotHighlightWidget::sl_storeNewSettings(AnnotationSettings *annotSettings) {
510 QList<AnnotationSettings *> annotToWrite;
511 AnnotationSettingsRegistry *annotRegistry = AppContext::getAnnotationsSettingsRegistry();
512 annotToWrite.append(annotSettings);
513 annotRegistry->changeSettings(annotToWrite, true);
514 }
515
sl_onSequenceModified(ADVSequenceObjectContext *)516 void AnnotHighlightWidget::sl_onSequenceModified(ADVSequenceObjectContext * /* seqContext */) {
517 loadAnnotTypes();
518 }
519
sl_onAnnotationsAdded(const QList<Annotation * > &)520 void AnnotHighlightWidget::sl_onAnnotationsAdded(const QList<Annotation *> & /* annotations */) {
521 loadAnnotTypes();
522 }
523
sl_onAnnotationsRemoved(const QList<Annotation * > & annotations)524 void AnnotHighlightWidget::sl_onAnnotationsRemoved(const QList<Annotation *> &annotations) {
525 CHECK(!showAllLabel->isShowAllSelected(), );
526
527 const QString selectedAnnotName = annotTree->getCurrentItemAnnotName();
528
529 QMap<QString, int> observedAnnNames;
530 foreach (Annotation *a, annotations) {
531 const QString annotName = a->getName();
532 if (observedAnnNames.contains(annotName)) {
533 observedAnnNames[annotName]++;
534 continue;
535 }
536 observedAnnNames.insert(annotName, 1);
537 }
538
539 bool isSelectedItemRemoved = false;
540 QList<AnnotationTableObject *> annTables = annotatedDnaView->getAnnotationObjects(true);
541 foreach (const QString &annotName, observedAnnNames.keys()) {
542 int count = 0;
543 foreach (AnnotationTableObject *t, annTables) {
544 count += t->getAnnotationsByName(annotName).size();
545 }
546 if (count == observedAnnNames[annotName]) {
547 QList<QTreeWidgetItem *> itemList = annotTree->findItems(annotName, Qt::MatchExactly);
548 SAFE_POINT(itemList.size() == 1, "Annotation Highlight tree should contain only one item per annotation type", );
549 QTreeWidgetItem *item = itemList.first();
550 delete annotTree->takeTopLevelItem(annotTree->indexOfTopLevelItem(item));
551 annotNamesWithAminoInfo.remove(annotName);
552 if (selectedAnnotName == annotName) {
553 isSelectedItemRemoved = true;
554 }
555 }
556 }
557
558 if (annotNamesWithAminoInfo.count() == 0) {
559 annotTree->clear();
560 setNoAnnotsLayout();
561 nextAnnotationButton->setDisabled(true);
562 } else {
563 setLayoutWithAnnotsSelection();
564 if (isSelectedItemRemoved || selectedAnnotName.isEmpty()) {
565 annotTree->setFirstItemSelected();
566 } else {
567 annotTree->setItemSelectedWithAnnotName(selectedAnnotName);
568 }
569 }
570 }
571
sl_onAnnotationsModified()572 void AnnotHighlightWidget::sl_onAnnotationsModified() {
573 loadAnnotTypes();
574 }
575
sl_onAnnotationObjectAdded(AnnotationTableObject * annotTableObj)576 void AnnotHighlightWidget::sl_onAnnotationObjectAdded(AnnotationTableObject *annotTableObj) {
577 connectSlotsForAnnotTableObj(annotTableObj);
578 loadAnnotTypes();
579 }
580
sl_onAnnotationObjectRemoved(AnnotationTableObject * annotTableObj)581 void AnnotHighlightWidget::sl_onAnnotationObjectRemoved(AnnotationTableObject *annotTableObj) {
582 disconnectSlotsForAnnotTableObj(annotTableObj);
583 loadAnnotTypes();
584 }
585
586 } // namespace U2
587