mirror of
https://github.com/opencv/opencv_contrib.git
synced 2025-10-23 00:49:38 +08:00
385 lines
8.1 KiB
C++
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;
|
|
}
|
|
}
|
|
}
|