ProjectManager::ProjectManager(IApplication *app, QWidget *parent) :
    liteApp(app), QWidget(parent), project(NULL)
{
    tree = new QTreeView;
    model = new QStandardItemModel;
    tree->setModel(model);
    tree->setEditTriggers(QAbstractItemView::NoEditTriggers);
    tree->setHeaderHidden(true);
    tree->setContextMenuPolicy(Qt::CustomContextMenu);
    connect(tree,SIGNAL(doubleClicked(QModelIndex)),this,SLOT(doubleClickedTree(QModelIndex)));
    connect(tree,SIGNAL(customContextMenuRequested(QPoint)),this,SLOT(showProjectMenu(QPoint)));

    QVBoxLayout *layout = new QVBoxLayout;
    layout->addWidget(tree);
    layout->setMargin(0);

    setLayout(layout);

    liteApp->addProjectFactory(this);
    parentDock = liteApp->mainWindow()->addWorkspacePane(this,"Projects");
}
MainWindow::MainWindow(QWidget *parent)
	: QMainWindow(parent)
	, ui(new Ui::MainWindow)
	, userSettings(QSettings::UserScope, "Jason Gedge", "StereoReconstruction")
	, trayIcon(nullptr)
    , recentFiles(userSettings.value("recentFileList").toStringList())
{
    ui->setupUi(this);

	//
	// Recent Files
	//
	QSignalMapper *recentFilesMapper = new QSignalMapper(this);
	connect(recentFilesMapper, SIGNAL(mapped(int)), SLOT(openRecentFile(int)));

	for(int index = 0; index < NUM_RECENT_FILES; ++index) {
		recentFileActions[index] = ui->menuOpen_Recent->addAction(
				QString("%1: <No File>").arg(index + 1),
				recentFilesMapper,
				SLOT(map()) );

		recentFileActions[index]->setVisible(false);
		recentFilesMapper->setMapping(recentFileActions[index], index);
	}
	{
		// Move separator + "clear recent files" to end
		QAction *act = ui->menuOpen_Recent->actions().first();
		ui->menuOpen_Recent->removeAction(act);
		ui->menuOpen_Recent->addAction(act);

		act = ui->menuOpen_Recent->actions().first();
		ui->menuOpen_Recent->removeAction(act);
		ui->menuOpen_Recent->addAction(act);
	}

	//
	//
	//
	trayIcon = new QSystemTrayIcon(this);

#ifndef HAS_IMAGE_CAPTURE
	ui->menuBar->removeAction(ui->menuCapture->menuAction());
#endif
#ifndef HAS_HDR
	ui->menuBar->removeAction(ui->menuHDR->menuAction());
#endif

	//
	//
	//
	projectExplorerDock = new QDockWidget(tr("Project Explorer"), this);
	projectExplorerDock->setObjectName(QString::fromUtf8("projectExplorerDock"));
	projectExplorerDock->setMinimumWidth(200);
	projectExplorerDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
	addDockWidget(Qt::LeftDockWidgetArea, projectExplorerDock);
	projectExplorerDock->hide();

	projectExplorer = new ProjectExplorer(this);
	projectExplorerDock->setWidget(projectExplorer);
	connect(projectExplorer, SIGNAL(customContextMenuRequested(QPoint)), SLOT(showProjectMenu(QPoint)));

	//
	//
	//
	imageSetTable = new ImageSetTable(this);
	imageSetTable->setEnabled(false);

	cameraInfoWidget = new CameraInfoWidget(this);
	cameraInfoWidget->setEnabled(false);

	inspectorDock = new QDockWidget(tr("Inspector"), this);
	inspectorDock->setObjectName(QString::fromUtf8("inspectorDock"));
	inspectorDock->setMinimumWidth(350);
	inspectorDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
	addDockWidget(Qt::RightDockWidgetArea, inspectorDock);
	inspectorDock->hide();

	inspector = new QStackedWidget(inspectorDock);
	inspector->addWidget(new QWidget(this));
	inspector->addWidget(cameraInfoWidget);
	inspector->addWidget(imageSetTable);
	inspectorDock->setWidget(inspector);

	//
	//
	//
	taskList = new QWidget(this);
	taskList->setAutoFillBackground(true);
	taskList->setBackgroundRole(QPalette::Light);
	taskList->setObjectName(QString::fromUtf8("taskList"));
	taskList->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
	taskList->setMinimumHeight(50); // XXX necessary?

	taskListLayout = new QVBoxLayout(taskList);
	taskListLayout->setMargin(0);
	taskListLayout->addStretch(1);

	taskListDock = new QDockWidget(tr("Task List"), this);
	taskListDock->setObjectName(QString::fromUtf8("taskListDock"));
	taskListDock->setWidget(taskList);
	taskListDock->setAllowedAreas(Qt::AllDockWidgetAreas);
	addDockWidget(Qt::BottomDockWidgetArea, taskListDock);
	taskListDock->hide();

	//
	// TODO move these to the ui files
	//
	connect(projectExplorer,
			SIGNAL(cameraSelected(CameraPtr)),
			SLOT(cameraSelected(CameraPtr)) );

	connect(projectExplorer,
			SIGNAL(imageSetSelected(ImageSetPtr)),
			SLOT(imageSetSelected(ImageSetPtr)) );

	connect(projectExplorerDock,
			SIGNAL(visibilityChanged(bool)),
			SLOT(on_actionShowHide_Project_Explorer_triggered(bool)) );

	connect(inspectorDock,
			SIGNAL(visibilityChanged(bool)),
			SLOT(on_actionShowHide_Inspector_triggered(bool)) );

	projectExplorer->connect(this,
			SIGNAL(projectLoaded(ProjectPtr)),
			SLOT(setProject(ProjectPtr)) );

	cameraInfoWidget->connect(this,
							  SIGNAL(projectLoaded(ProjectPtr)),
							  SLOT(setProject(ProjectPtr)) );

	cameraInfoWidget->connect(projectExplorer,
							  SIGNAL(cameraSelected(CameraPtr)),
							  SLOT(setCamera(CameraPtr)) );

	imageSetTable->connect(this,
						   SIGNAL(projectLoaded(ProjectPtr)),
						   SLOT(setProject(ProjectPtr)) );

	imageSetTable->connect(projectExplorer,
						   SIGNAL(imageSetSelected(ImageSetPtr)),
						   SLOT(setImageSet(ImageSetPtr)) );

	ui->stereoWidget->connect(this,
							  SIGNAL(projectLoaded(ProjectPtr)),
							  SLOT(setProject(ProjectPtr)) );

	//
	// Set up initial window state
	//
	restoreGeometry(userSettings.value("mainWindowGeometry").toByteArray());
	restoreState(userSettings.value("mainWindowState").toByteArray());
	updateRecentFiles();
	ui->actionView_Nothing->trigger();
	ui->actionNew->trigger();
}