maineditor.cpp
1 /*
2  name: tools/editor/maineditor.cpp
3 
4  This file is part of ARCS - Augmented Reality Component System
5  (version 2-current), written by Jean-Yves Didier
6  for IBISC Laboratory (http://www.ibisc.univ-evry.fr)
7 
8  Copyright (C) 2013 Université d'Evry-Val d'Essonne
9 
10  This program is free software: you can redistribute it and/or modify
11  it under the terms of the GNU General Public License as published by
12  the Free Software Foundation, either version 2 of the License, or
13  (at your option) any later version.
14 
15  This program is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  GNU General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with this program. If not, see <http://www.gnu.org/licenses/>.
22 
23 
24  Please send bugreports with examples or suggestions to
25  jean-yves.didier__at__ibisc.univ-evry.fr
26 */
27 
28 
29 #include "maineditor.h"
30 #include "applicationview.h"
31 #include "logview.h"
32 #include <QMenuBar>
33 #include <QApplication>
34 #include <QPushButton>
35 #include <QTabWidget>
36 #include <QTextEdit>
37 #include <QSettings>
38 #include <QFileDialog>
39 #include "arcs/arcsxmlhandler.h"
40 #include <QDebug>
41 #include "arcs/arcslog.h"
42 
43 MainEditor::MainEditor(QWidget *parent) :
44  QMainWindow(parent)
45 {
46 
47  defaultApplication = 0;
48  recentMenu = new QMenu("Recent");
49 
50  QSettings settings;
51  recentList = settings.value("recent files").toStringList();
52  buildRecentMenu();
53  connect(recentMenu,SIGNAL(triggered(QAction*)),this,SLOT(handleRecentAction(QAction*)));
54 
55 
56  QMenu* fileMenu = new QMenu("File",menuBar());
57  fileMenu->addAction("New...",this,SLOT(newApplication()),QKeySequence(Qt::CTRL + Qt::Key_N));
58  fileMenu->addAction("Open",this,SLOT(openApplication()),QKeySequence(Qt::CTRL + Qt::Key_O));
59  saveFileAction=fileMenu->addAction("Save",this, SLOT(saveApplication()),QKeySequence(Qt::CTRL + Qt::Key_S));
60  saveFileAction->setEnabled(false);
61  fileMenu->addAction("Save as...",this,SLOT(saveAsApplication()));
62  fileMenu->addMenu(recentMenu);
63  fileMenu->addSeparator();
64  fileMenu->addAction("Exit",QApplication::instance(),SLOT(quit()),QKeySequence(Qt::CTRL + Qt::Key_Q));
65 
66  //menuBar()->addAction("New...");
67  editMenu = new QMenu("Edition",menuBar());
68 
69 
70  menuBar()->addMenu(fileMenu);
71  menuBar()->addMenu(editMenu);
72 
73  tbElements = new QTabWidget(this);
74 
75  setCentralWidget(tbElements);
76 
77  welcomeWidget = new QTextEdit(this);
78 
79  welcomeWidget->setHtml("<img src=\":arcs_logo.png\"/><h1>Welcome to the ARCS Editor !</h1><p>You can start a new project by clicking <tt>File -> New...</tt>");
80  welcomeWidget->setReadOnly(true);
81 
82 
83  tbElements->addTab(welcomeWidget,"Welcome");
84  tbElements->setTabsClosable(true);
85  connect(tbElements,SIGNAL(tabCloseRequested(int)),this,SLOT(removeTab(int)));
86  connect(tbElements,SIGNAL(currentChanged(int)),this,SLOT(actualizeFromTab(int)));
87  setWindowIcon(QIcon(":arcs_logo.png"));
88 
89  logView = new LogView(this);
90  addDockWidget(Qt::BottomDockWidgetArea,logView);
91 
92 }
93 
94 MainEditor::~MainEditor()
95 {
96  QSettings settings;
97  settings.setValue("recent files",QStringList(recentList.mid(0,5)));
98 }
99 
100 
101 
102 void MainEditor::newApplication()
103 {
104  ApplicationView* app = new ApplicationView(0,this);
105  applications.append(app);
106  addDockWidget(Qt::LeftDockWidgetArea,app);
107  connect(app,SIGNAL(defaultOwnershipRequested(ApplicationView*)),this,SLOT(setDefaultApplication(ApplicationView*)));
108  connect(app,SIGNAL(requestAppIdDestroy(QVariant)),this,SLOT(destroyAppId(QVariant)));
109  connect(app,SIGNAL(requestWidgetDestroy(QVariant,QString)),this,SLOT(destroyWidget(QVariant,QString)));
110  setDefaultApplication(app);
111 }
112 
113 
114 void MainEditor::saveApplication()
115 {
116  if (!defaultApplication)
117  return;
118 
119  // put here something in order to quick save all of this.
120 
121 }
122 
123 void MainEditor::saveAsApplication()
124 {
125  QString fileName = QFileDialog::getSaveFileName(this,"Save your ARCS application");
126 
127  if (fileName.isEmpty())
128  return ;
129 
130  if (recentList.contains(fileName))
131  recentList.swap(0,recentList.indexOf(fileName));
132  else
133  recentList.push_front(fileName);
134  buildRecentMenu();
135 
136 
137  // look for dock widgets.
138  if (defaultApplication)
139  {
140  ARCSLog::getInstance()->startCapture();
141  // another idea is to delegate the fact we save the application to the application viewer.
142  ARCSApplicationComponent* aac = defaultApplication->getApplication();
143  //aac->saveFile(fileName);
144  ARCSXMLHandler handler;
145  //handler.pushFilePath(fileName);
146  handler.storeApplication(aac);
147  handler.saveFile(fileName);
148 
149  logView->addLog(ARCSLog::getInstance()->endCapture());
150  }
151 }
152 
153 void MainEditor::openApplication(QString s)
154 {
155  QString fileName ;
156  if (s.isEmpty())
157  {
158  fileName = QFileDialog::getOpenFileName(this,"Please select your ARCS application");
159  if (fileName.isEmpty())
160  return ;
161 
162  if (recentList.contains(fileName))
163  recentList.swap(0,recentList.indexOf(fileName));
164  else
165  recentList.push_front(fileName);
166  buildRecentMenu();
167 
168  }
169  else
170  fileName = s;
171 
172  ARCSLog::getInstance()->startCapture();
173 
174 
176  if (appComp->loadFile(fileName))
177  {
178  ApplicationView* app = new ApplicationView(appComp,this);
179  app->setAssociatedFile(fileName);
180  applications.append(app);
181  app->setWindowTitle("Application: " + QFileInfo(fileName).fileName());
182  addDockWidget(Qt::LeftDockWidgetArea,app);
183  connect(app,SIGNAL(defaultOwnershipRequested(ApplicationView*)),this,SLOT(setDefaultApplication(ApplicationView*)));
184  connect(app,SIGNAL(requestWidgetDestroy(QVariant,QString)),this,SLOT(destroyWidget(QVariant,QString)));
185  connect(app,SIGNAL(requestAppIdDestroy(QVariant)),this,SLOT(destroyAppId(QVariant)));
186  setDefaultApplication(app);
187  }
188 
189 
190  logView->addLog(ARCSLog::getInstance()->endCapture());
191 }
192 
193 
194 void MainEditor::addNewTabWidget(QWidget *wdg)
195 {
197  for (int i=0; i < tbElements->count(); i++)
198  {
199  if (tbElements->tabText(i) == wdg->windowTitle() && wdg->property("appId") == tbElements->widget(i)->property("appId"))
200  {
201  tbElements->setCurrentIndex(i);
202  delete wdg;
203  return;
204  }
205  }
206 
207  tbElements->addTab(wdg,wdg->windowTitle());
208  tbElements->setCurrentIndex(tbElements->count()-1);
209  connect(wdg,SIGNAL(sendLog(QString)),logView,SLOT(addLog(QString)));
210  connect(wdg,SIGNAL(addWidget(QWidget*)),this,SLOT(addNewTabWidget(QWidget*)));
211 
212 }
213 
214 void MainEditor::actualizeFromTab(int cur)
215 {
216  if (cur < 0)
217  return ;
218 
219  editMenu->clear();
220  editMenu->addActions(tbElements->currentWidget()->actions());
221 }
222 
223 void MainEditor::handleRecentAction(QAction * act)
224 {
225  openApplication(act->text());
226 }
227 
228 void MainEditor::buildRecentMenu()
229 {
230  for (int i=0; i < recentList.count(); i++)
231  recentMenu->addAction(recentList[i]);
232 }
233 
234 void MainEditor::setDefaultApplication(ApplicationView *app)
235 {
236  if (defaultApplication)
237  defaultApplication->setStyleSheet("QDockWidget { font-weight: normal; }");
238  defaultApplication = app;
239  saveFileAction->setEnabled(!app->getAssociatedFile().isEmpty());
240  app->setStyleSheet("QDockWidget { font-weight: bold; } ");
241 }
242 
243 void MainEditor::destroyAppId(QVariant appId)
244 {
245  int id = 0;
246  for (int i = 0; i < applications.count(); i++)
247  {
248  if (applications[i]->property("appId") != appId)
249  setDefaultApplication(applications[i]);
250  else
251  id = i;
252  }
253 
254  applications.removeAt(id);
255  if (applications.count() == 0)
256  {
257  saveFileAction->setEnabled(false);
258  defaultApplication = 0;
259  }
260 
261  for (int i=0; i < tbElements->count(); i++)
262  {
263  if( tbElements->widget(i)->property("appId") == appId)
264  tbElements->removeTab(i);
265  }
266 }
267 
268 void MainEditor::destroyWidget(QVariant appId, QString name)
269 {
270  for (int i=0; i < tbElements->count(); i++)
271  {
272  if( tbElements->widget(i)->property("appId") == appId && tbElements->widget(i)->windowTitle() == name)
273  tbElements->removeTab(i);
274  }
275 }
This class represents an application.
void addNewTabWidget(QWidget *wdg)
Definition: maineditor.cpp:194
static ARCSLog * getInstance()
returns the only instance of the logging system that is available
Definition: arcslog.cpp:188
bool saveFile(QString s)
Saves a file given its path. The file will describe either an application or a composite component...
virtual bool loadFile(QString fn)
Defines a way to load a component description from a file.
This is an XML Handler for all ARCS native XML formats.