1
0
mirror of https://github.com/opencv/opencv_contrib.git synced 2025-10-23 00:49:38 +08:00
Files
opencv_contrib/modules/cvv/src/controller/view_controller.cpp
2018-03-29 13:26:11 +03:00

385 lines
8.1 KiB
C++

#include "view_controller.hpp"
#include <stdexcept>
#include <iostream>
#include <QApplication>
#include <QDesktopServices>
#include <QUrl>
#include "../gui/call_tab.hpp"
#include "../gui/call_window.hpp"
#include "../gui/overview_panel.hpp"
#include "../gui/main_call_window.hpp"
#include "../gui/filter_call_tab.hpp"
#include "../gui/match_call_tab.hpp"
#include "../gui/image_call_tab.hpp"
#include "../impl/init.hpp"
#include "../impl/filter_call.hpp"
#include "../impl/match_call.hpp"
#include "../impl/single_image_call.hpp"
#include "../impl/data_controller.hpp"
#include "../qtutil/util.hpp"
namespace cvv
{
namespace controller
{
// It's only used for instatiating a QApplication.
// static char *emptyArray[] = {""};
static char *parameterSystemV[] = { new char[1]{ 0 }, nullptr };
static int parameterSystemC = 1;
ViewController::ViewController()
{
impl::initializeFilterAndViews();
if (!QApplication::instance())
{
auto tmp =
new QApplication{ parameterSystemC, parameterSystemV };
ownsQApplication = true;
(void)tmp;
}
ovPanel = new gui::OverviewPanel{ util::makeRef(*this) };
mainWindow = new gui::MainCallWindow(util::makeRef(*this), 0, ovPanel);
windowMap[0] = std::unique_ptr<gui::CallWindow>(mainWindow);
max_window_id = 0;
mainWindow->show();
}
ViewController::~ViewController()
{
callTabMap.clear();
windowMap.clear();
windowMap.clear();
if (ownsQApplication)
{
delete QApplication::instance();
}
}
void ViewController::addCallType(const QString typeName, TabFactory constr)
{
ViewController::callTabType[typeName] = constr;
}
static std::unique_ptr<cvv::gui::FilterCallTab>
makeFilterCallTab(cvv::util::Reference<cvv::impl::Call> call)
{
return cvv::util::make_unique<cvv::gui::FilterCallTab>(
*call.castTo<cvv::impl::FilterCall>());
}
static std::unique_ptr<cvv::gui::MatchCallTab>
makeMatchCallTab(cvv::util::Reference<cvv::impl::Call> call)
{
return cvv::util::make_unique<cvv::gui::MatchCallTab>(
*call.castTo<cvv::impl::MatchCall>());
}
static std::unique_ptr<cvv::gui::ImageCallTab>
makeImageCallTab(cvv::util::Reference<cvv::impl::Call> call)
{
return cvv::util::make_unique<cvv::gui::ImageCallTab>(
*call.castTo<cvv::impl::SingleImageCall>());
}
std::map<QString, TabFactory> ViewController::callTabType{
{ "filter", makeFilterCallTab }, { "match", makeMatchCallTab },
{ "singleImage", makeImageCallTab }
};
void ViewController::addCall(util::Reference<impl::Call> data)
{
updateMode();
if (mode == Mode::NORMAL)
{
ovPanel->addElement(*data);
mainWindow->showOverviewTab();
}
else if (mode == Mode::FAST_FORWARD)
{
ovPanel->addElementBuffered(*data);
}
}
void ViewController::exec()
{
updateMode();
if (mode == Mode::NORMAL)
{
QApplication::instance()->exec();
}
}
impl::Call &ViewController::getCall(size_t id)
{
return impl::dataController().getCall(id);
}
QString ViewController::getSetting(const QString &scope, const QString &key)
{
return qtutil::getSetting(scope, key);
}
std::vector<util::Reference<gui::CallWindow>> ViewController::getTabWindows()
{
std::vector<util::Reference<gui::CallWindow>> windows{};
for (auto &it : windowMap)
{
windows.push_back(util::makeRef(*(it.second)));
}
return windows;
}
util::Reference<gui::MainCallWindow> ViewController::getMainWindow()
{
return util::makeRef(*mainWindow);
}
void ViewController::moveCallTabToNewWindow(size_t tabId)
{
if (!hasCall(tabId))
return;
auto newWindow = util::make_unique<gui::CallWindow>(
util::makeRef<ViewController>(*this), ++max_window_id);
removeCallTab(tabId);
newWindow->addTab(getCallTab(tabId));
newWindow->show();
if (doesShowExitProgramButton)
{
newWindow->showExitProgramButton();
}
windowMap[max_window_id] = std::move(newWindow);
removeEmptyWindowsWithDelay();
}
void ViewController::moveCallTabToWindow(size_t tabId, size_t windowId)
{
if (!hasCall(tabId))
return;
removeCallTab(tabId);
auto tab = getCallTab(tabId);
windowMap[windowId]->addTab(tab);
removeEmptyWindowsWithDelay();
}
void ViewController::removeCallTab(size_t tabId, bool deleteIt, bool deleteCall, bool updateUI)
{
auto *curWindow = getCurrentWindowOfTab(tabId);
if (curWindow->hasTab(tabId))
{
getCurrentWindowOfTab(tabId)->removeTab(tabId);
if (deleteIt)
{
callTabMap.erase(tabId);
}
}
if (deleteCall && hasCall(tabId))
{
if (updateUI)
{
ovPanel->removeElement(tabId);
}
impl::dataController().removeCall(tabId);
}
removeEmptyWindowsWithDelay();
}
void ViewController::openHelpBrowser(const QString &topic)
{
qtutil::openHelpBrowser(topic);
}
void ViewController::resumeProgramExecution()
{
QApplication::instance()->exit();
}
void ViewController::setDefaultSetting(const QString &scope, const QString &key,
const QString &value)
{
qtutil::setDefaultSetting(scope, key, value);
}
void ViewController::setSetting(const QString &scope, const QString &key,
const QString &value)
{
qtutil::setSetting(scope, key, value);
}
void ViewController::showCallTab(size_t tabId)
{
auto *window = getCurrentWindowOfTab(tabId);
window->showTab(tabId);
window->setWindowState((window->windowState() & ~Qt::WindowMinimized) |
Qt::WindowActive);
window->raise();
}
void ViewController::showAndOpenCallTab(size_t tabId)
{
auto curWindow = getCurrentWindowOfTab(tabId);
if (!curWindow->hasTab(tabId))
{
moveCallTabToWindow(tabId, 0);
curWindow = mainWindow;
}
curWindow->showTab(tabId);
}
void ViewController::openCallTab(size_t tabId)
{
auto curWindow = getCurrentWindowOfTab(tabId);
if (!curWindow->hasTab(tabId))
{
moveCallTabToWindow(tabId, 0);
curWindow = mainWindow;
}
}
void ViewController::showOverview()
{
mainWindow->setWindowState(
(mainWindow->windowState() & ~Qt::WindowMinimized) |
Qt::WindowActive);
mainWindow->raise();
mainWindow->showOverviewTab();
}
gui::CallWindow *ViewController::getCurrentWindowOfTab(size_t tabId)
{
for (auto &elem : windowMap)
{
if (elem.second->hasTab(tabId))
{
return elem.second.get();
}
}
return mainWindow;
}
gui::CallTab *ViewController::getCallTab(size_t tabId)
{
if (callTabMap.count(tabId) == 0)
{
auto *call = &(getCall(tabId));
if (callTabType.count(call->type()) == 0)
{
throw std::invalid_argument{
"no such type '" + call->type().toStdString() +
"'"
};
}
callTabMap[tabId] =
callTabType[call->type()](util::makeRef(*call));
}
return callTabMap[tabId].get();
}
void ViewController::removeWindowFromMaps(size_t windowId)
{
if (windowMap.count(windowId) > 0)
{
windowMap[windowId].release();
windowMap.erase(windowId);
}
}
void ViewController::removeEmptyWindows()
{
std::vector<size_t> remIds{};
for (auto &elem : windowMap)
{
if (elem.second->tabCount() == 0 && elem.second->getId() != 0)
{
remIds.push_back(elem.first);
}
}
for (auto windowId : remIds)
{
auto window = windowMap[windowId].release();
windowMap.erase(windowId);
window->deleteLater();
}
shouldRunRemoveEmptyWindows_ = false;
}
void ViewController::removeEmptyWindowsWithDelay()
{
shouldRunRemoveEmptyWindows_ = true;
}
bool ViewController::shouldRunRemoveEmptyWindows()
{
return shouldRunRemoveEmptyWindows_;
}
void ViewController::showExitProgramButton()
{
for (auto &elem : windowMap)
{
elem.second->showExitProgramButton();
}
doesShowExitProgramButton = true;
}
bool ViewController::hasCall(size_t id)
{
return impl::dataController().hasCall(id);
}
void ViewController::setMode(Mode newMode)
{
mode = newMode;
switch (newMode)
{
case Mode::NORMAL:
break;
case Mode::HIDE:
hideAll();
QApplication::instance()->exit();
break;
case Mode::FAST_FORWARD:
if (!doesShowExitProgramButton)
{
QApplication::instance()->exit();
}
else
{
mode = Mode::NORMAL;
}
break;
}
}
Mode ViewController::getMode()
{
return mode;
}
void ViewController::updateMode()
{
if (mode == Mode::FAST_FORWARD && hasFinalCall())
{
mode = Mode::NORMAL;
ovPanel->flushElementBuffer();
}
}
void ViewController::hideAll()
{
for (auto &window : windowMap)
{
window.second->hide();
}
}
bool ViewController::hasFinalCall()
{
return doesShowExitProgramButton;
}
}
}