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 "AssemblyBrowserTasks.h"
23 
24 #include <U2Core/AppContext.h>
25 #include <U2Core/AssemblyObject.h>
26 #include <U2Core/DocumentModel.h>
27 #include <U2Core/L10n.h>
28 #include <U2Core/ProjectModel.h>
29 #include <U2Core/U2OpStatusUtils.h>
30 #include <U2Core/U2SafePoints.h>
31 
32 #include <U2Gui/Notification.h>
33 
34 #include "AssemblyBrowser.h"
35 #include "AssemblyBrowserFactory.h"
36 #include "AssemblyBrowserState.h"
37 
38 namespace U2 {
39 
40 //==============================================================================
41 // OpenAssemblyBrowserTask - open new view
42 //==============================================================================
43 
OpenAssemblyBrowserTask(AssemblyObject * obj)44 OpenAssemblyBrowserTask::OpenAssemblyBrowserTask(AssemblyObject *obj)
45     : ObjectViewTask(AssemblyBrowserFactory::ID) {
46     selectedObjects.append(obj);
47 }
48 
OpenAssemblyBrowserTask(UnloadedObject * unloadedObj)49 OpenAssemblyBrowserTask::OpenAssemblyBrowserTask(UnloadedObject *unloadedObj)
50     : ObjectViewTask(AssemblyBrowserFactory::ID),
51       unloadedObjRef(unloadedObj) {
52     documentsToLoad.append(unloadedObj->getDocument());
53 }
54 
OpenAssemblyBrowserTask(Document * doc)55 OpenAssemblyBrowserTask::OpenAssemblyBrowserTask(Document *doc)
56     : ObjectViewTask(AssemblyBrowserFactory::ID) {
57     assert(!doc->isLoaded());
58     documentsToLoad.append(doc);
59 }
60 
open()61 void OpenAssemblyBrowserTask::open() {
62     if (stateInfo.hasError() || (documentsToLoad.isEmpty() && selectedObjects.isEmpty())) {
63         return;
64     }
65 
66     if (selectedObjects.isEmpty()) {
67         assert(documentsToLoad.size() == 1);
68         Document *doc = documentsToLoad.first();
69         QList<GObject *> objects;
70         if (unloadedObjRef.isValid()) {
71             // To do: replace the object finding to "GObject* obj = doc->findGObjectByName(unloadedObjRef.objName);" after fixing of UGENE-4904
72             QList<GObject *> objs = doc->findGObjectByType(unloadedObjRef.objType);
73             GObject *obj = nullptr;
74             foreach (GObject *curObj, objs) {
75                 if (curObj->getGObjectName() == unloadedObjRef.objName) {
76                     obj = curObj;
77                     break;
78                 }
79             }
80             if (obj != nullptr && obj->getGObjectType() == GObjectTypes::ASSEMBLY) {
81                 selectedObjects.append(qobject_cast<AssemblyObject *>(obj));
82             }
83         } else {
84             QList<GObject *> assemblyObjects = doc->findGObjectByType(GObjectTypes::ASSEMBLY, UOF_LoadedAndUnloaded);
85             if (!assemblyObjects.isEmpty()) {
86                 selectedObjects.append(qobject_cast<AssemblyObject *>(assemblyObjects.first()));
87             }
88         }
89         if (selectedObjects.isEmpty()) {
90             stateInfo.setError(tr("Assembly object not found"));
91             return;
92         }
93     }
94 
95     foreach (QPointer<GObject> po, selectedObjects) {
96         AssemblyObject *o = qobject_cast<AssemblyObject *>(po);
97 
98         SAFE_POINT(o, "Invalid assembly object!", );
99 
100         viewName = GObjectViewUtils::genUniqueViewName(o->getDocument(), o);
101         openBrowserForObject(o, viewName, false);
102     }
103 }
104 
updateTitle(AssemblyBrowser * ab)105 void OpenAssemblyBrowserTask::updateTitle(AssemblyBrowser *ab) {
106     const QString &oldViewName = ab->getName();
107     GObjectViewWindow *w = GObjectViewUtils::findViewByName(oldViewName);
108     if (w != nullptr) {
109         AssemblyObject *aObj = ab->getAssemblyObject();
110         QString newViewName = GObjectViewUtils::genUniqueViewName(aObj->getDocument(), aObj);
111         ab->setName(newViewName);
112         w->setWindowTitle(newViewName);
113     }
114 }
115 
openBrowserForObject(AssemblyObject * obj,QString viewName,bool persistent)116 AssemblyBrowser *OpenAssemblyBrowserTask::openBrowserForObject(AssemblyObject *obj, QString viewName, bool persistent) {
117     AssemblyBrowser *v = new AssemblyBrowser(viewName, obj);
118     U2OpStatus2Notification os;
119     if (!v->checkValid(os)) {
120         delete v;
121         return nullptr;
122     }
123     GObjectViewWindow *w = new GObjectViewWindow(v, viewName, persistent);
124     AppContext::getMainWindow()->getMDIManager()->addMDIWindow(w);
125     return v;
126 }
127 
128 //==============================================================================
129 // OpenSavedAssemblyBrowserTask - restore a new view from saved state
130 //==============================================================================
131 
OpenSavedAssemblyBrowserTask(const QString & viewName,const QVariantMap & stateData)132 OpenSavedAssemblyBrowserTask::OpenSavedAssemblyBrowserTask(const QString &viewName, const QVariantMap &stateData)
133     : ObjectViewTask(AssemblyBrowserFactory::ID, viewName, stateData) {
134     AssemblyBrowserState state(stateData);
135     GObjectReference ref = state.getGObjectRef();
136     Document *doc = AppContext::getProject()->findDocumentByURL(ref.docUrl);
137     if (doc == nullptr) {
138         doc = createDocumentAndAddToProject(ref.docUrl, AppContext::getProject(), stateInfo);
139         CHECK_OP_EXT(stateInfo, stateIsIllegal = true, );
140     }
141     if (!doc->isLoaded()) {
142         documentsToLoad.append(doc);
143     }
144 }
145 
open()146 void OpenSavedAssemblyBrowserTask::open() {
147     CHECK_OP(stateInfo, );
148 
149     AssemblyBrowserState state(stateData);
150     GObjectReference ref = state.getGObjectRef();
151     Document *doc = AppContext::getProject()->findDocumentByURL(ref.docUrl);
152     if (doc == nullptr) {
153         stateIsIllegal = true;
154         stateInfo.setError(L10N::errorDocumentNotFound(ref.docUrl));
155         return;
156     }
157     GObject *obj = nullptr;
158     if (doc->isDatabaseConnection() && ref.entityRef.isValid()) {
159         obj = doc->getObjectById(ref.entityRef.entityId);
160     } else {
161         // To do: replace the object finding to "GObject* obj = doc->findGObjectByName(unloadedObjRef.objName);" after fixing of UGENE-4904
162         QList<GObject *> objs = doc->findGObjectByType(ref.objType);
163         foreach (GObject *curObj, objs) {
164             if (curObj->getGObjectName() == ref.objName) {
165                 obj = curObj;
166                 break;
167             }
168         }
169     }
170     if (obj == nullptr || obj->getGObjectType() != GObjectTypes::ASSEMBLY) {
171         stateIsIllegal = true;
172         stateInfo.setError(tr("Assembly object not found: %1").arg(ref.objName));
173         return;
174     }
175     AssemblyObject *asmObj = qobject_cast<AssemblyObject *>(obj);
176     SAFE_POINT(asmObj != nullptr, "Object has type ASSEMBLY, but cannot cast to AssemblyObject", );
177 
178     AssemblyBrowser *ab = OpenAssemblyBrowserTask::openBrowserForObject(asmObj, viewName, true);
179     CHECK(ab != nullptr, );
180     state.restoreState(ab);
181 }
182 
183 //==============================================================================
184 // UpdateAssemblyBrowserTask - restore saved state on current view
185 //==============================================================================
186 
update()187 void UpdateAssemblyBrowserTask::update() {
188     if (view.isNull() || view->getFactoryId() != AssemblyBrowserFactory::ID) {
189         return;  // view was closed;
190     }
191 
192     AssemblyBrowser *ab = qobject_cast<AssemblyBrowser *>(view.data());
193     SAFE_POINT(ab != nullptr, "UpdateAssemblyBrowserTask::update: view is not AssemblyBrowser", );
194 
195     AssemblyBrowserState(stateData).restoreState(ab);
196 }
197 
198 }  // namespace U2
199