28 #include <QApplication>
29 #include <QDockWidget>
30 #include <QGridLayout>
35 #include <QStringList>
36 #include <QXmlStreamWriter>
39 #include "CnetEditorWidget.h"
42 #include "ControlList.h"
44 #include "ExportControlNetWorkOrder.h"
45 #include "ExportImagesWorkOrder.h"
48 #include "HistoryTreeWidget.h"
54 #include "ImageFileListWidget.h"
55 #include "MosaicSceneWidget.h"
58 #include "ProjectTreeWidget.h"
62 #include "WarningTreeWidget.h"
65 #include "XmlStackedHandler.h"
66 #include "XmlStackedHandlerReader.h"
73 m_project =
new Project(*
this);
75 catch (IException &e) {
77 "Could not create directory because Project could not be created.",
81 connect(m_project, SIGNAL(imagesAdded(ImageList *)),
82 this, SLOT(imagesAddedToProject(ImageList *)));
84 m_projectTreeWidget =
new ProjectTreeWidget(
this);
87 createWorkOrder<CnetEditorViewWorkOrder>();
88 createWorkOrder<CubeViewportViewWorkOrder>();
89 createWorkOrder<Footprint2DViewWorkOrder>();
90 createWorkOrder<ImageFileListViewWorkOrder>();
92 m_exportControlNetWorkOrder = createWorkOrder<ExportControlNetWorkOrder>();
93 m_exportImagesWorkOrder = createWorkOrder<ExportImagesWorkOrder>();
94 m_importControlNetWorkOrder = createWorkOrder<ImportControlNetWorkOrder>();
95 m_importImagesWorkOrder = createWorkOrder<ImportImagesWorkOrder>();
96 m_openProjectWorkOrder = createWorkOrder<OpenProjectWorkOrder>();
97 m_saveProjectWorkOrder = createWorkOrder<SaveProjectWorkOrder>();
98 m_saveProjectAsWorkOrder = createWorkOrder<SaveProjectAsWorkOrder>();
100 m_renameProjectWorkOrder = createWorkOrder<RenameProjectWorkOrder>();
102 catch (IException &e) {
104 "Could not create directory because work orders are corrupt.",
110 Directory::~Directory() {
111 delete m_projectTreeWidget;
114 foreach (WorkOrder *workOrder, m_workOrders) {
118 m_workOrders.clear();
122 void Directory::populateMainMenu(QMenuBar *menuBar) {
123 QMenu *fileMenu = menuBar->findChild<QMenu *>(
"fileMenu");
125 fileMenu->addAction(m_importControlNetWorkOrder->clone());
126 fileMenu->addAction(m_importImagesWorkOrder->clone());
127 fileMenu->addSeparator();
128 fileMenu->addAction(m_openProjectWorkOrder->clone());
129 fileMenu->addSeparator();
131 QAction *saveAction = m_saveProjectWorkOrder->clone();
132 saveAction->setShortcut(Qt::Key_S | Qt::CTRL);
134 connect(project()->undoStack(), SIGNAL(cleanChanged(
bool)),
135 saveAction, SLOT(setDisabled(
bool)));
137 fileMenu->addAction(saveAction);
139 fileMenu->addAction(m_saveProjectAsWorkOrder->clone());
141 fileMenu->addSeparator();
142 fileMenu->addAction(m_exportControlNetWorkOrder->clone());
143 fileMenu->addAction(m_exportImagesWorkOrder->clone());
144 fileMenu->addSeparator();
147 QMenu *projectMenu = menuBar->findChild<QMenu *>(
"projectMenu");
149 projectMenu->addAction(m_renameProjectWorkOrder->clone());
154 void Directory::setHistoryContainer(QDockWidget *historyContainer) {
155 if (!m_historyTreeWidget) {
156 m_historyTreeWidget =
new HistoryTreeWidget(project());
158 historyContainer->setWidget(m_historyTreeWidget);
162 void Directory::setWarningContainer(QDockWidget *warningContainer) {
163 if (!m_warningTreeWidget) {
164 m_warningTreeWidget =
new WarningTreeWidget;
166 warningContainer->setWidget(m_warningTreeWidget);
170 CnetEditorWidget *Directory::addCnetEditorView(Control *network) {
171 QString title = tr(
"Cnet Editor View %1").arg(network->displayProperties()->displayName());
173 FileName configFile(
"$HOME/.Isis/" + QApplication::applicationName() +
"/" + title +
".config");
178 QGridLayout *resultLayout =
new QGridLayout;
179 result->setLayout(resultLayout);
183 QMenuBar *menuBar =
new QMenuBar;
184 resultLayout->addWidget(menuBar, row, 0, 1, 2);
187 CnetEditorWidget *mainWidget =
188 new CnetEditorWidget(network->controlNet(), configFile.expanded());
189 resultLayout->addWidget(mainWidget, row, 0, 1, 2);
194 QMapIterator< QAction *, QList< QString > > actionMapIterator(actionMap);
198 while (actionMapIterator.hasNext()) {
199 actionMapIterator.next();
200 QAction *actionToAdd = actionMapIterator.key();
203 QMenu *menuToPutActionInto = NULL;
205 if (location.count()) {
206 QString topLevelMenuTitle = location.takeFirst();
207 if (!topLevelMenus[topLevelMenuTitle]) {
208 topLevelMenus[topLevelMenuTitle] = menuBar->addMenu(topLevelMenuTitle);
211 menuToPutActionInto = topLevelMenus[topLevelMenuTitle];
214 foreach (QString menuName, location) {
215 bool foundSubMenu =
false;
216 foreach (
QAction *possibleSubMenu, menuToPutActionInto->actions()) {
218 possibleSubMenu->menu() && possibleSubMenu->menu()->title() == menuName) {
220 menuToPutActionInto = possibleSubMenu->menu();
225 menuToPutActionInto = menuToPutActionInto->addMenu(menuName);
229 menuToPutActionInto->addAction(actionToAdd);
232 QTabWidget *treeViews =
new QTabWidget;
233 treeViews->addTab(mainWidget->pointTreeView(), tr(
"Point View"));
234 treeViews->addTab(mainWidget->serialTreeView(), tr(
"Serial View"));
235 treeViews->addTab(mainWidget->connectionTreeView(), tr(
"Connection View"));
236 resultLayout->addWidget(treeViews, row, 0, 1, 1);
238 QTabWidget *filterViews =
new QTabWidget;
239 filterViews->addTab(mainWidget->pointFilterWidget(), tr(
"Filter Points and Measures"));
240 filterViews->addTab(mainWidget->serialFilterWidget(), tr(
"Filter Images and Points"));
241 filterViews->addTab(mainWidget->connectionFilterWidget(), tr(
"Filter Connections"));
242 resultLayout->addWidget(filterViews, row, 1, 1, 1);
245 connect(result, SIGNAL(destroyed(
QObject *)),
246 this, SLOT(cleanupCnetEditorViewWidgets()));
248 m_cnetEditorViewWidgets.append(mainWidget);
250 result->setWindowTitle(title);
251 result->setObjectName(title);
253 emit newWidgetAvailable(result, Qt::RightDockWidgetArea, Qt::Horizontal);
259 Workspace *Directory::addCubeDnView() {
260 Workspace *result =
new Workspace(
true);
262 connect(result, SIGNAL(destroyed(
QObject *)),
263 this, SLOT(cleanupCubeDnViewWidgets()));
265 m_cubeDnViewWidgets.append(result);
267 result->setWindowTitle(tr(
"Cube DN View %1").arg(m_cubeDnViewWidgets.count()));
268 result->setObjectName(result->windowTitle());
270 emit newWidgetAvailable(result, Qt::RightDockWidgetArea, Qt::Horizontal);
276 MosaicSceneWidget *Directory::addFootprint2DView() {
277 MosaicSceneWidget *result =
new MosaicSceneWidget(NULL,
true,
true,
this);
279 connect(result, SIGNAL(destroyed(
QObject *)),
280 this, SLOT(cleanupFootprint2DViewWidgets()));
282 m_footprint2DViewWidgets.append(result);
284 result->setWindowTitle(tr(
"Footprint View %1").arg(m_footprint2DViewWidgets.count()));
285 result->setObjectName(result->windowTitle());
287 emit newWidgetAvailable(result, Qt::RightDockWidgetArea, Qt::Horizontal);
293 ImageFileListWidget *Directory::addImageFileListView() {
294 ImageFileListWidget *result =
new ImageFileListWidget(
this);
296 connect(result, SIGNAL(destroyed(
QObject *)),
297 this, SLOT(cleanupFileListWidgets()));
299 m_fileListWidgets.append(result);
301 result->setWindowTitle(tr(
"File List %1").arg(m_fileListWidgets.count()));
302 result->setObjectName(result->windowTitle());
304 emit newWidgetAvailable(result, Qt::LeftDockWidgetArea, Qt::Horizontal);
310 QWidget *Directory::warningWidget() {
311 return m_warningTreeWidget;
315 QWidget *Directory::projectTreeWidget() {
316 return m_projectTreeWidget;
320 void Directory::cleanupCnetEditorViewWidgets() {
321 m_cnetEditorViewWidgets.removeAll(NULL);
325 void Directory::cleanupCubeDnViewWidgets() {
326 m_cubeDnViewWidgets.removeAll(NULL);
330 void Directory::cleanupFileListWidgets() {
331 m_fileListWidgets.removeAll(NULL);
335 void Directory::cleanupFootprint2DViewWidgets() {
336 m_footprint2DViewWidgets.removeAll(NULL);
340 void Directory::imagesAddedToProject(ImageList *imageList) {
341 m_projectTreeWidget->addImageGroup(imageList);
345 Project *Directory::project()
const {
353 foreach (CnetEditorWidget *widget, m_cnetEditorViewWidgets) {
354 results.append(widget);
364 foreach (Workspace *widget, m_cubeDnViewWidgets) {
365 results.append(widget);
375 foreach (MosaicSceneWidget *widget, m_footprint2DViewWidgets) {
376 results.append(widget);
386 foreach (ImageFileListWidget *widget, m_fileListWidgets) {
387 results.append(widget);
400 void Directory::showWarning(QString text) {
401 m_warningTreeWidget->showWarning(text);
405 QAction *Directory::redoAction() {
406 return project()->undoStack()->createRedoAction(
this);
410 QAction *Directory::undoAction() {
411 return project()->undoStack()->createUndoAction(
this);
415 void Directory::load(XmlStackedHandlerReader *xmlReader) {
416 xmlReader->pushContentHandler(
new XmlHandler(
this));
420 void Directory::save(QXmlStreamWriter &stream, FileName newProjectRoot)
const {
421 stream.writeStartElement(
"directory");
423 if (!m_fileListWidgets.isEmpty()) {
424 stream.writeStartElement(
"fileListWidgets");
426 foreach (ImageFileListWidget *fileListWidget, m_fileListWidgets) {
427 fileListWidget->save(stream, project(), newProjectRoot);
430 stream.writeEndElement();
434 if (!m_footprint2DViewWidgets.isEmpty()) {
435 stream.writeStartElement(
"footprintViews");
437 foreach (MosaicSceneWidget *footprint2DViewWidget, m_footprint2DViewWidgets) {
438 footprint2DViewWidget->save(stream, project(), newProjectRoot);
441 stream.writeEndElement();
444 stream.writeEndElement();
448 Directory::XmlHandler::XmlHandler(Directory *directory) {
449 m_directory = directory;
453 Directory::XmlHandler::~XmlHandler() {
457 bool Directory::XmlHandler::startElement(
const QString &namespaceURI,
const QString &localName,
458 const QString &qName,
const QXmlAttributes &atts) {
459 bool result = XmlStackedHandler::startElement(namespaceURI, localName, qName, atts);
462 if (localName ==
"footprint2DView") {
463 m_directory->addFootprint2DView()->load(reader());
465 else if (localName ==
"imageFileList") {
466 m_directory->addImageFileListView()->load(reader());
541 foreach (singleWidgetPairing, actionPairings) {
542 QString widgetTitle = singleWidgetPairing.first;
545 foreach (
QAction *widgetAction, widgetActions) {
547 QString actionText = widgetAction->text();
549 restructuredData[actionText].append(qMakePair(widgetTitle, widgetAction));
551 if (!sortedActionTexts.contains(actionText)) {
552 sortedActionTexts.append(actionText);
557 if (!sortedActionTexts.isEmpty() && !sortedActionTexts.last().isEmpty()) {
558 sortedActionTexts.append(
"");
564 if (sortedActionTexts.count() && sortedActionTexts.last().isEmpty()) {
565 sortedActionTexts.removeLast();
568 foreach (QString actionText, sortedActionTexts) {
569 if (actionText.isEmpty()) {
570 results.append(NULL);
577 if (actions.count() == 1) {
578 QAction *finalAct = actions.first().second;
579 QString widgetTitle = actions.first().first;
581 finalAct->setText(tr(
"%1 on %2").arg(actionText).arg(widgetTitle));
582 results.append(finalAct);
587 QMenu *menu =
new QMenu;
588 menuAct->setMenu(menu);
593 foreach (widgetTitleAndAction, actions) {
594 QString widgetTitle = widgetTitleAndAction.first;
595 QAction *action = widgetTitleAndAction.second;
597 action->setText(widgetTitle);
598 actionsInsideMenu.append(action);
601 qSort(actionsInsideMenu.begin(), actionsInsideMenu.end(), &actionTextLessThan);
605 foreach (
QAction *actionInMenu, actionsInsideMenu) {
606 connect(allAct, SIGNAL(triggered()), actionInMenu, SIGNAL(triggered()));
607 menu->addAction(actionInMenu);
610 menu->addSeparator();
611 menu->addAction(allAct);
613 results.append(menuAct);
623 return lhs->text().localeAwareCompare(rhs->text()) < 0;