ui: Added tabs UI to top of main window (issue #215)

* Added tab bar to top of main window with UI/shortcuts similar to web browsers
* ComponentManager offers components for 2 use-cases: application and tab
* Application components: log view (status/errors), bookmarks, screen search, status bar, tabs, tooltips, dialogs and all tab views disabled
* Tab components: graph, code, history and search
* When a project is loaded there is always at least one tab, otherwise there is none
* Each tab replaces the application views of the same name in the main layout when activated
* Each tab has it's own TaskScheduler, to process tasks independent from other tabs
* The application has a global TaskScheduler for application wide tasks
* The singloton class TaskManager is responsible for managing the TaskSchedulers
* MessageListeners and Messages hold an optional schedulerId, both must be set to only send to a specific TaskScheduler
* Bookmark buttons where split off into a separate view per tab, bookmark managemement is done in the application
* History menu processing is done by the QtMainWindow now
* Screen search is an application component, the responders are always changed to the active tab
* Plugin messages are opened in a new tab
* Symbols can be opened in a new tab via middle click/context menu in graph, code, history dropdown
* Full text index creation is mutexed now in PersistenStorage to make it fully thread-safe
* All tabs are closed when switching projects
* Tab contents are only animated when visible

fortune cookie message = Catch your lucky star!
This commit is contained in:
Eberhard Graether
2018-11-05 01:28:12 +01:00
parent bd4a554b27
commit f13aec70dd
170 changed files with 2972 additions and 823 deletions
+5 -4
View File
@@ -1,15 +1,16 @@
#include "Task.h"
#include "TaskManager.h"
#include "TaskScheduler.h"
void Task::dispatch(std::shared_ptr<Task> task)
void Task::dispatch(Id schedulerId, std::shared_ptr<Task> task)
{
TaskScheduler::getInstance()->pushTask(task);
TaskManager::getScheduler(schedulerId)->pushTask(task);
}
void Task::dispatchNext(std::shared_ptr<Task> task)
void Task::dispatchNext(Id schedulerId, std::shared_ptr<Task> task)
{
TaskScheduler::getInstance()->pushNextTask(task);
TaskManager::getScheduler(schedulerId)->pushNextTask(task);
}
void Task::setIsBackgroundTask(bool background)
+4 -2
View File
@@ -3,6 +3,8 @@
#include <memory>
#include "types.h"
class Blackboard;
class Task
@@ -16,8 +18,8 @@ public:
STATE_FAILURE
};
static void dispatch(std::shared_ptr<Task> task);
static void dispatchNext(std::shared_ptr<Task> task);
static void dispatch(Id schedulerId, std::shared_ptr<Task> task);
static void dispatchNext(Id schedulerId, std::shared_ptr<Task> task);
virtual ~Task() = default;
@@ -0,0 +1,37 @@
#include "TaskManager.h"
#include "TaskScheduler.h"
std::map<Id, std::shared_ptr<TaskScheduler>> TaskManager::s_schedulers;
std::mutex TaskManager::s_schedulersMutex;
std::shared_ptr<TaskScheduler> TaskManager::createScheduler(Id schedulerId)
{
return getScheduler(schedulerId);
}
void TaskManager::destroyScheduler(Id schedulerId)
{
std::lock_guard<std::mutex> lock(s_schedulersMutex);
auto it = s_schedulers.find(schedulerId);
if (it != s_schedulers.end())
{
s_schedulers.erase(it);
}
}
std::shared_ptr<TaskScheduler> TaskManager::getScheduler(Id schedulerId)
{
std::lock_guard<std::mutex> lock(s_schedulersMutex);
auto it = s_schedulers.find(schedulerId);
if (it != s_schedulers.end())
{
return it->second;
}
std::shared_ptr<TaskScheduler> scheduler = std::make_shared<TaskScheduler>(schedulerId);
s_schedulers.emplace(schedulerId, scheduler);
return scheduler;
}
+25
View File
@@ -0,0 +1,25 @@
#ifndef TASK_MANAGER_H
#define TASK_MANAGER_H
#include <map>
#include <memory>
#include <mutex>
#include "types.h"
class TaskScheduler;
class TaskManager
{
public:
static std::shared_ptr<TaskScheduler> createScheduler(Id schedulerId);
static void destroyScheduler(Id schedulerId);
static std::shared_ptr<TaskScheduler> getScheduler(Id schedulerId);
private:
static std::map<Id, std::shared_ptr<TaskScheduler>> s_schedulers;
static std::mutex s_schedulersMutex;
};
#endif // TASK_MANAGER_H
+19 -2
View File
@@ -1,7 +1,8 @@
#include "TaskRunner.h"
#include "logging.h"
#include "Blackboard.h"
#include "logging.h"
#include "TaskManager.h"
#include "TaskScheduler.h"
TaskRunner::TaskRunner(std::shared_ptr<Task> task)
@@ -10,6 +11,17 @@ TaskRunner::TaskRunner(std::shared_ptr<Task> task)
{
}
Task::TaskState TaskRunner::update(Id schedulerId)
{
if (!m_blackboard)
{
m_blackboard = std::make_shared<Blackboard>();
m_blackboard->set<Id>("scheduler_id", schedulerId);
}
return update(m_blackboard);
}
Task::TaskState TaskRunner::update(std::shared_ptr<Blackboard> blackboard)
{
if (!blackboard)
@@ -41,7 +53,12 @@ Task::TaskState TaskRunner::update(std::shared_ptr<Blackboard> blackboard)
LOG_ERROR("Unknown exception thrown during task running");
}
TaskScheduler::getInstance()->terminateRunningTasks();
Id schedulerId = 0;
if (blackboard->get<Id>("scheduler_id", schedulerId))
{
TaskManager::getScheduler(schedulerId)->terminateRunningTasks();
}
return Task::STATE_FAILURE;
}
+1
View File
@@ -10,6 +10,7 @@ class TaskRunner
public:
TaskRunner(std::shared_ptr<Task> task);
Task::TaskState update(Id schedulerId);
Task::TaskState update(std::shared_ptr<Blackboard> blackboard);
void reset();
void terminate(); // caution: this should only be called just before quitting the app.
+10 -16
View File
@@ -6,14 +6,17 @@
#include "logging.h"
#include "ScopedFunctor.h"
std::shared_ptr<TaskScheduler> TaskScheduler::getInstance()
TaskScheduler::TaskScheduler(Id schedulerId)
: m_schedulerId(schedulerId)
, m_loopIsRunning(false)
, m_threadIsRunning(false)
, m_terminateRunningTasks(false)
{
if (!s_instance)
{
s_instance = std::shared_ptr<TaskScheduler>(new TaskScheduler());
}
}
return s_instance;
TaskScheduler::~TaskScheduler()
{
stopSchedulerLoop();
}
void TaskScheduler::pushTask(std::shared_ptr<Task> task)
@@ -127,15 +130,6 @@ void TaskScheduler::terminateRunningTasks()
m_terminateRunningTasks = true;
}
std::shared_ptr<TaskScheduler> TaskScheduler::s_instance;
TaskScheduler::TaskScheduler()
: m_loopIsRunning(false)
, m_threadIsRunning(false)
, m_terminateRunningTasks(false)
{
}
void TaskScheduler::processTasks()
{
std::lock_guard<std::mutex> lock(m_tasksMutex);
@@ -163,7 +157,7 @@ void TaskScheduler::processTasks()
}
}
state = runner->update(nullptr);
state = runner->update(m_schedulerId);
if (state != Task::STATE_RUNNING)
{
break;
+4 -7
View File
@@ -7,11 +7,13 @@
#include "Task.h"
#include "TaskRunner.h"
#include "types.h"
class TaskScheduler
{
public:
static std::shared_ptr<TaskScheduler> getInstance();
TaskScheduler(Id schedulerId);
~TaskScheduler();
void pushTask(std::shared_ptr<Task> task);
void pushNextTask(std::shared_ptr<Task> task);
@@ -26,14 +28,9 @@ public:
void terminateRunningTasks();
private:
static std::shared_ptr<TaskScheduler> s_instance;
TaskScheduler();
TaskScheduler(const TaskScheduler&);
void operator=(const TaskScheduler&);
void processTasks();
const Id m_schedulerId;
bool m_loopIsRunning;
bool m_threadIsRunning;