ui: Added singleton QtContextMenu with global back and forward actions

* QtContextMenu holds default actions for back and forward
* additional actions can be passed to extend the default menu
* currently used in QtMainWindow and QtCodeArea
* fixed crash on undo when only view actions happened since project load

bug id = 108
This commit is contained in:
Eberhard Graether
2016-06-30 16:49:16 +02:00
parent 32f894422d
commit 4e18389d38
9 changed files with 181 additions and 20 deletions
+11 -9
View File
@@ -2,16 +2,13 @@
background-color: <color:code/background>;
}
* {
font-size: <setting:font_size>pt;
}
#code_file {
background-color: <color:code/snippet/background>;
border: 2px solid <color:code/file/background>;
border-radius: 12px;
border-top-left-radius: 14px;
border-top-right-radius: 14px;
font-size: <setting:font_size>pt;
padding-bottom: 7px;
}
@@ -19,6 +16,7 @@
background-color: <color:code/file/background>;
border-top-left-radius: 7px;
border-top-right-radius: 7px;
font-size: <setting:font_size>pt;
padding-right: 5px;
}
@@ -27,6 +25,7 @@
border: none;
border-radius: 3px;
color: <color:code/file/title/text>;
font-size: <setting:font_size>pt;
padding: 2px 4px;
margin: 1px 8px 3px;
}
@@ -52,10 +51,7 @@
#code_file #code_snippet {
background-color: <color:code/snippet/background>;
border-top: 2px solid <color:code/file/background>;
}
#code_file #code_snippet * {
font-family: "<setting:font_name>";
font-size: <setting:font_size>pt;
}
#code_file #code_snippet[isFirst=true] {
@@ -65,8 +61,10 @@
#code_file #code_snippet #scope_name, #code_file #code_snippet #dots {
background-color: <color:code/snippet/title/background>;
color: <color:code/snippet/title/text>;
border: none;
color: <color:code/snippet/title/text>;
font-family: "<setting:font_name>";
font-size: <setting:font_size>pt;
}
#code_file #code_snippet #scope_name:hover {
@@ -88,11 +86,15 @@
background-color: <color:code/snippet/line_number/background>;
border: none;
color: <color:code/snippet/line_number/text>;
font-family: "<setting:font_name>";
font-size: <setting:font_size>pt;
}
#code_area {
background-color: transparent;
color: <color:code/snippet/syntax/normal>;
font-family: "<setting:font_name>";
font-size: <setting:font_size>pt;
}
#code_file #maximize_button, #code_file #snippet_button, #code_file #minimize_button {
@@ -243,23 +243,40 @@ void UndoRedoController::handleMessage(MessageShowScope* message)
void UndoRedoController::handleMessage(MessageUndo* message)
{
if (!m_list.size() || std::prev(m_iterator) == m_list.begin())
if (!m_list.size())
{
return;
}
while (std::prev(m_iterator)->order == Command::ORDER_VIEW)
// return to last non view command
std::list<Command>::iterator it = m_iterator;
while (std::prev(it)->order == Command::ORDER_VIEW)
{
std::advance(m_iterator, -1);
std::advance(it, -1);
}
std::advance(m_iterator, -1);
std::advance(it, -1);
if (std::distance(m_list.begin(), m_iterator) <= 1)
// disable undo button if there is no non view command till the first command
std::list<Command>::iterator it2 = std::prev(it);
while (it2->order == Command::ORDER_VIEW)
{
std::advance(it2, -1);
}
if (it2 == m_list.begin())
{
getView()->setUndoButtonEnabled(false);
}
// abort if first command is reached
if (it == m_list.begin())
{
return;
}
getView()->setRedoButtonEnabled(true);
m_iterator = it;
replayCommands();
MessageFlushUpdates().dispatch();
@@ -392,3 +409,39 @@ MessageBase* UndoRedoController::lastMessage() const
{
return std::prev(m_iterator)->message.get();
}
void UndoRedoController::dump() const
{
std::cout << "Undo Redo Stack:\n\n";
std::list<Command>::const_iterator it = m_list.begin();
while (it != m_list.end())
{
switch (it->order)
{
case Command::ORDER_VIEW:
std::cout << "\t";
case Command::ORDER_ADAPT:
std::cout << "\t";
case Command::ORDER_ACTIVATE:
break;
}
std::cout << it->message->getType() << " " << it->replayLastOnly;
if (it == m_iterator)
{
std::cout << " <-";
}
std::cout << std::endl;
std::advance(it, 1);
}
if (m_list.end() == m_iterator)
{
std::cout << " <-";
}
std::cout << std::endl;
}
@@ -99,6 +99,8 @@ private:
bool sameMessageTypeAsLast(MessageBase* message) const;
MessageBase* lastMessage() const;
void dump() const;
std::list<Command> m_list;
std::list<Command>::iterator m_iterator;
};
+2
View File
@@ -52,6 +52,8 @@ add_files(
qt/network/QtTcpWrapper.cpp
qt/network/QtTcpWrapper.h
qt/utility/QtContextMenu.cpp
qt/utility/QtContextMenu.h
qt/utility/QtDeviceScaledPixmap.cpp
qt/utility/QtDeviceScaledPixmap.h
qt/utility/QtHighlighter.cpp
+2 -4
View File
@@ -21,6 +21,7 @@
#include "data/location/TokenLocationFile.h"
#include "qt/element/QtCodeFile.h"
#include "qt/element/QtCodeSnippet.h"
#include "qt/utility/QtContextMenu.h"
#include "qt/utility/QtHighlighter.h"
#include "settings/ApplicationSettings.h"
#include "settings/ColorScheme.h"
@@ -498,10 +499,7 @@ void QtCodeArea::contextMenuEvent(QContextMenuEvent* event)
if (m_setIDECursorPositionAction != nullptr)
{
m_eventPosition = event->pos();
QMenu menu(this);
menu.addAction(m_setIDECursorPositionAction);
menu.exec(event->globalPos());
QtContextMenu::getInstance()->showExtended(event, this, std::vector<QAction*>(1, m_setIDECursorPositionAction));
}
}
+67
View File
@@ -0,0 +1,67 @@
#include "qt/utility/QtContextMenu.h"
#include <QMenu>
#include <QContextMenuEvent>
#include "utility/messaging/type/MessageRedo.h"
#include "utility/messaging/type/MessageUndo.h"
std::shared_ptr<QtContextMenu> QtContextMenu::s_instance;
QtContextMenu* QtContextMenu::getInstance()
{
if (!s_instance)
{
s_instance = std::make_shared<QtContextMenu>();
}
return s_instance.get();
}
QtContextMenu::QtContextMenu()
{
m_undoAction = new QAction(tr("Back"), this);
m_undoAction->setStatusTip(tr("Go back to last active symbol"));
m_undoAction->setToolTip(tr("Go back to last active symbol"));
connect(m_undoAction, SIGNAL(triggered()), this, SLOT(undoActionTriggered()));
m_redoAction = new QAction(tr("Forward"), this);
m_redoAction->setStatusTip(tr("Go forward to next active symbol"));
m_redoAction->setToolTip(tr("Go forward to next active symbol"));
connect(m_redoAction, SIGNAL(triggered()), this, SLOT(redoActionTriggered()));
}
void QtContextMenu::showDefault(QContextMenuEvent* event, QWidget* origin)
{
showExtended(event, origin, std::vector<QAction*>());
}
void QtContextMenu::showExtended(QContextMenuEvent* event, QWidget* origin, const std::vector<QAction*>& actions)
{
QMenu menu(origin);
menu.addAction(m_undoAction);
menu.addAction(m_redoAction);
if (actions.size())
{
menu.addSeparator();
for (QAction* action : actions)
{
menu.addAction(action);
}
}
menu.exec(event->globalPos());
}
void QtContextMenu::undoActionTriggered()
{
MessageUndo().dispatch();
}
void QtContextMenu::redoActionTriggered()
{
MessageRedo().dispatch();
}
+31
View File
@@ -0,0 +1,31 @@
#ifndef QT_CONTEXT_MENU_H
#define QT_CONTEXT_MENU_H
#include <QAction>
#include <QObject>
class QtContextMenu
: public QObject
{
Q_OBJECT
public:
static QtContextMenu* getInstance();
QtContextMenu();
void showDefault(QContextMenuEvent* event, QWidget* origin);
void showExtended(QContextMenuEvent* event, QWidget* origin, const std::vector<QAction*>& actions);
private slots:
void undoActionTriggered();
void redoActionTriggered();
private:
static std::shared_ptr<QtContextMenu> s_instance;
QAction* m_undoAction;
QAction* m_redoAction;
};
#endif // QT_CONTEXT_MENU_H
+6 -2
View File
@@ -12,6 +12,7 @@
#include "component/view/View.h"
#include "component/view/CompositeView.h"
#include "qt/utility/QtContextMenu.h"
#include "qt/utility/utilityQt.h"
#include "qt/view/QtViewWidgetWrapper.h"
#include "qt/window/project_wizzard/QtProjectWizzard.h"
@@ -139,8 +140,6 @@ QtMainWindow::QtMainWindow()
setWindowIcon(QIcon((ResourcePaths::getGuiPath() + "icon/logo_1024_1024.png").c_str()));
setWindowFlags(Qt::Widget);
// QApplication::setOverrideCursor(Qt::ArrowCursor);
QApplication* app = dynamic_cast<QApplication*>(QCoreApplication::instance());
app->installEventFilter(new MouseReleaseFilter(this));
app->installEventFilter(new MouseWheelFilter(this));
@@ -314,6 +313,11 @@ void QtMainWindow::keyPressEvent(QKeyEvent* event)
}
}
void QtMainWindow::contextMenuEvent(QContextMenuEvent* event)
{
QtContextMenu::getInstance()->showDefault(event, this);
}
void QtMainWindow::activateWindow()
{
this->setEnabled(true);
+2
View File
@@ -89,6 +89,7 @@ public:
protected:
bool event(QEvent* event);
void keyPressEvent(QKeyEvent* event);
void contextMenuEvent(QContextMenuEvent* event);
public slots:
void activateWindow();
@@ -157,6 +158,7 @@ private:
QAction* m_viewSeparator;
QAction** m_recentProjectAction;
QAction* m_showTitleBarsAction;
bool m_showDockWidgetTitleBars;
QtWindowStack m_windowStack;