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 <AppContextImpl.h>
23 
24 #include <QMainWindow>
25 #include <QMenu>
26 #include <QMessageBox>
27 #include <QToolBar>
28 
29 #include <U2Core/GUrlUtils.h>
30 #include <U2Core/L10n.h>
31 #include <U2Core/QObjectScopedPointer.h>
32 #include <U2Core/Settings.h>
33 #include <U2Core/U2OpStatusUtils.h>
34 
35 #include <U2Gui/DialogUtils.h>
36 #include <U2Gui/GUIUtils.h>
37 #include <U2Gui/MainWindow.h>
38 
39 #include "ExportProjectDialogController.h"
40 #include "ProjectImpl.h"
41 #include "ProjectLoaderImpl.h"
42 #include "ProjectServiceImpl.h"
43 #include "ProjectTasksGui.h"
44 
45 namespace U2 {
46 
47 #define SETTINGS_DIR QString("project_loader/")
48 
ProjectServiceImpl(Project * _pr)49 ProjectServiceImpl::ProjectServiceImpl(Project *_pr)
50     : ProjectService(tr("Project"), tr("Project service is available when opened a project file. Other services that depends on Project service will be automatically started after this service is enabled.")) {
51     saveAction = nullptr;
52     saveAsAction = nullptr;
53     closeProjectAction = nullptr;
54     projectActionsSeparator = nullptr;
55     exportProjectAction = nullptr;
56 
57     pr = _pr;
58     assert(pr != nullptr);
59 }
60 
~ProjectServiceImpl()61 ProjectServiceImpl::~ProjectServiceImpl() {
62     delete pr;
63 }
64 
saveProjectTask(SaveProjectTaskKind k)65 Task *ProjectServiceImpl::saveProjectTask(SaveProjectTaskKind k) {
66     return new SaveProjectTask(k);
67 }
68 
closeProjectTask()69 Task *ProjectServiceImpl::closeProjectTask() {
70     return new CloseProjectTask();
71 }
72 
enableSaveAction(bool e)73 void ProjectServiceImpl::enableSaveAction(bool e) {
74     if (saveAction) {
75         saveAction->setEnabled(e);
76     }
77 }
78 
createServiceEnablingTask()79 Task *ProjectServiceImpl::createServiceEnablingTask() {
80     return new ProjectServiceEnableTask(this);
81 }
82 
createServiceDisablingTask()83 Task *ProjectServiceImpl::createServiceDisablingTask() {
84     return new ProjectServiceDisableTask(this);
85 }
86 
sl_closeProject()87 void ProjectServiceImpl::sl_closeProject() {
88     AppContext::getTaskScheduler()->registerTopLevelTask(closeProjectTask());
89 }
90 
sl_save()91 void ProjectServiceImpl::sl_save() {
92     AppContext::getTaskScheduler()->registerTopLevelTask(saveProjectTask(SaveProjectTaskKind_SaveProjectAndDocuments));
93 }
94 
sl_saveAs()95 void ProjectServiceImpl::sl_saveAs() {
96     QWidget *p = qobject_cast<QWidget *>(AppContext::getMainWindow()->getQMainWindow());
97     QObjectScopedPointer<ProjectDialogController> d = new ProjectDialogController(ProjectDialogController::Save_Project, p);
98     const int rc = d->exec();
99     CHECK(!d.isNull(), );
100 
101     if (rc == QDialog::Rejected) {
102         return;
103     }
104 
105     U2OpStatus2Log os;
106 
107     AppContext::getProject()->setProjectName(d->projectNameEdit->text());
108 
109     QString fileName = d->projectFilePathEdit->text();
110     if (!fileName.endsWith(PROJECTFILE_EXT)) {
111         fileName.append(PROJECTFILE_EXT);
112     }
113     AppContext::getProject()->setProjectURL(fileName);
114 
115     AppContext::getTaskScheduler()->registerTopLevelTask(saveProjectTask(SaveProjectTaskKind_SaveProjectAndDocuments));
116 }
117 
sl_exportProject()118 void ProjectServiceImpl::sl_exportProject() {
119     Project *p = getProject();
120     QString pUrl = p->getProjectURL();
121     QString projectFilePath = pUrl.isEmpty() ? GUrlUtils::getDefaultDataPath() + "/project" + PROJECTFILE_EXT : pUrl;
122     QObjectScopedPointer<ExportProjectDialogController> dialog = new ExportProjectDialogController(AppContext::getMainWindow()->getQMainWindow(), projectFilePath);
123     dialog->exec();
124     CHECK(!dialog.isNull(), );
125 
126     if (dialog->result() == QDialog::Accepted) {
127         Task *t = new ExportProjectTask(dialog->getDirToSave(), dialog->getProjectFile(), dialog->useCompression());
128         AppContext::getTaskScheduler()->registerTopLevelTask(t);
129     }
130 }
131 
132 //////////////////////////////////////////////////////////////////////////
133 /// Service tasks
134 
ProjectServiceEnableTask(ProjectServiceImpl * _psi)135 ProjectServiceEnableTask::ProjectServiceEnableTask(ProjectServiceImpl *_psi)
136     : Task(tr("Enable Project"), TaskFlag_NoRun), psi(_psi) {
137 }
138 
report()139 Task::ReportResult ProjectServiceEnableTask::report() {
140     AppContextImpl::getApplicationContext()->setProjectService(psi);
141     AppContextImpl::getApplicationContext()->setProject(psi->getProject());
142 
143     assert(psi->saveAction == nullptr && psi->closeProjectAction == nullptr);
144 
145     psi->saveAction = new QAction(QIcon(":ugene/images/project_save.png"), tr("&Save all"), psi);
146     psi->saveAction->setObjectName(ACTION_PROJECTSUPPORT__SAVE_PROJECT);
147     psi->saveAction->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_S));
148     psi->saveAction->setShortcutContext(Qt::WindowShortcut);
149     connect(psi->saveAction, SIGNAL(triggered()), psi, SLOT(sl_save()));
150 
151     psi->saveAsAction = new QAction(tr("Save project &as..."), psi);
152     psi->saveAsAction->setObjectName(ACTION_PROJECTSUPPORT__SAVE_AS_PROJECT);
153     connect(psi->saveAsAction, SIGNAL(triggered()), psi, SLOT(sl_saveAs()));
154 
155     psi->closeProjectAction = new QAction(tr("&Close project"), psi);
156     psi->closeProjectAction->setObjectName(ACTION_PROJECTSUPPORT__CLOSE_PROJECT);
157     psi->closeProjectAction->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_Q));
158     psi->closeProjectAction->setShortcutContext(Qt::WindowShortcut);
159     connect(psi->closeProjectAction, SIGNAL(triggered()), psi, SLOT(sl_closeProject()));
160 
161     psi->exportProjectAction = new QAction(tr("Export project..."), psi);
162     psi->exportProjectAction->setObjectName(ACTION_PROJECTSUPPORT__EXPORT_PROJECT);
163     connect(psi->exportProjectAction, SIGNAL(triggered()), psi, SLOT(sl_exportProject()));
164 
165     psi->projectActionsSeparator = new QAction("", psi);
166     psi->projectActionsSeparator->setSeparator(true);
167 
168     MainWindow *mw = AppContext::getMainWindow();
169     QMenu *fileMenu = mw->getTopLevelMenu(MWMENU_FILE);
170     QAction *beforeAction = GUIUtils::findActionAfter(fileMenu->actions(), ACTION_PROJECTSUPPORT__RECENT_PROJECTS_MENU);
171     fileMenu->insertAction(beforeAction, psi->projectActionsSeparator);
172     fileMenu->insertAction(beforeAction, psi->saveAction);
173     fileMenu->insertAction(beforeAction, psi->saveAsAction);
174     fileMenu->insertAction(beforeAction, psi->exportProjectAction);
175     fileMenu->insertAction(beforeAction, psi->closeProjectAction);
176 
177     QToolBar *tb = mw->getToolbar(MWTOOLBAR_MAIN);
178     beforeAction = GUIUtils::findActionAfter(tb->actions(), ACTION_PROJECTSUPPORT__OPEN_PROJECT);
179     tb->insertAction(beforeAction, psi->saveAction);
180 
181     return ReportResult_Finished;
182 }
183 
ProjectServiceDisableTask(ProjectServiceImpl * _psi)184 ProjectServiceDisableTask::ProjectServiceDisableTask(ProjectServiceImpl *_psi)
185     : Task(tr("Disable Project"), TaskFlag_NoRun), psi(_psi) {
186 }
187 
report()188 Task::ReportResult ProjectServiceDisableTask::report() {
189     AppContextImpl::getApplicationContext()->setProject(nullptr);
190     AppContextImpl::getApplicationContext()->setProjectService(nullptr);
191 
192     delete psi->saveAction;
193     psi->saveAction = nullptr;
194 
195     delete psi->closeProjectAction;
196     psi->closeProjectAction = nullptr;
197 
198     delete psi->projectActionsSeparator;
199     psi->projectActionsSeparator = nullptr;
200 
201     return ReportResult_Finished;
202 }
203 
204 }  // namespace U2
205