ui: Added on-screen search feature (issue #79)
* Use menu action "Edit -> Find in View" or Ctrl + D * UI displayed as search bar at bottom of main window * Hide search bar with ECS or close button * Entering a query searches in name of graph nodes and code contents of code view * Use Enter to iterate through matches, well move match into view in graph and code view * Checkboxes allow for adding/removing results for certain views * Create Bookmark shortcut is now CTRL + S bug id = 79
This commit is contained in:
@@ -10,6 +10,7 @@ add_files(
|
||||
component/controller/helper/ListLayouter.h
|
||||
component/controller/helper/NetworkProtocolHelper.cpp
|
||||
component/controller/helper/NetworkProtocolHelper.h
|
||||
component/controller/helper/ScreenSearchInterfaces.h
|
||||
component/controller/helper/SnippetMerger.cpp
|
||||
component/controller/helper/SnippetMerger.h
|
||||
component/controller/helper/TrailLayouter.cpp
|
||||
@@ -32,6 +33,8 @@ add_files(
|
||||
component/controller/LogController.h
|
||||
component/controller/RefreshController.cpp
|
||||
component/controller/RefreshController.h
|
||||
component/controller/ScreenSearchController.cpp
|
||||
component/controller/ScreenSearchController.h
|
||||
component/controller/SearchController.cpp
|
||||
component/controller/SearchController.h
|
||||
component/controller/StatusBarController.cpp
|
||||
@@ -66,6 +69,8 @@ add_files(
|
||||
component/view/MainView.h
|
||||
component/view/RefreshView.cpp
|
||||
component/view/RefreshView.h
|
||||
component/view/ScreenSearchView.cpp
|
||||
component/view/ScreenSearchView.h
|
||||
component/view/SearchView.cpp
|
||||
component/view/SearchView.h
|
||||
component/view/StatusBarView.cpp
|
||||
|
||||
@@ -30,3 +30,13 @@ Component::~Component()
|
||||
m_view->setComponent(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
Controller* Component::getControllerPtr() const
|
||||
{
|
||||
return m_controller.get();
|
||||
}
|
||||
|
||||
View* Component::getViewPtr() const
|
||||
{
|
||||
return m_view.get();
|
||||
}
|
||||
|
||||
@@ -15,9 +15,13 @@ public:
|
||||
template <typename ControllerType>
|
||||
ControllerType* getController() const;
|
||||
|
||||
Controller* getControllerPtr() const;
|
||||
|
||||
template <typename ViewType>
|
||||
ViewType* getView() const;
|
||||
|
||||
View* getViewPtr() const;
|
||||
|
||||
private:
|
||||
const std::shared_ptr<Controller> m_controller;
|
||||
const std::shared_ptr<View> m_view;
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "component/controller/GraphController.h"
|
||||
#include "component/controller/LogController.h"
|
||||
#include "component/controller/RefreshController.h"
|
||||
#include "component/controller/ScreenSearchController.h"
|
||||
#include "component/controller/SearchController.h"
|
||||
#include "component/controller/StatusBarController.h"
|
||||
#include "component/controller/StatusController.h"
|
||||
@@ -18,6 +19,7 @@
|
||||
#include "component/view/ErrorView.h"
|
||||
#include "component/view/LogView.h"
|
||||
#include "component/view/RefreshView.h"
|
||||
#include "component/view/ScreenSearchView.h"
|
||||
#include "component/view/SearchView.h"
|
||||
#include "component/view/StatusBarView.h"
|
||||
#include "component/view/StatusView.h"
|
||||
@@ -58,14 +60,6 @@ std::shared_ptr<Component> ComponentFactory::createActivationComponent()
|
||||
return std::make_shared<Component>(nullptr, controller);
|
||||
}
|
||||
|
||||
std::shared_ptr<Component> ComponentFactory::createTooltipComponent(ViewLayout* viewLayout)
|
||||
{
|
||||
std::shared_ptr<TooltipView> view = m_viewFactory->createTooltipView(viewLayout);
|
||||
std::shared_ptr<Controller> controller = std::make_shared<TooltipController>(m_storageAccess);
|
||||
|
||||
return std::make_shared<Component>(view, controller);
|
||||
}
|
||||
|
||||
std::shared_ptr<Component> ComponentFactory::createBookmarkComponent(ViewLayout* viewLayout)
|
||||
{
|
||||
std::shared_ptr<BookmarkView> view = m_viewFactory->createBookmarkView(viewLayout);
|
||||
@@ -90,6 +84,14 @@ std::shared_ptr<Component> ComponentFactory::createErrorComponent(ViewLayout* vi
|
||||
return std::make_shared<Component>(view, controller);
|
||||
}
|
||||
|
||||
std::shared_ptr<Component> ComponentFactory::createGraphComponent(ViewLayout* viewLayout)
|
||||
{
|
||||
std::shared_ptr<View> view = m_viewFactory->createGraphView(viewLayout);
|
||||
std::shared_ptr<GraphController> controller = std::make_shared<GraphController>(m_storageAccess);
|
||||
|
||||
return std::make_shared<Component>(view, controller);
|
||||
}
|
||||
|
||||
std::shared_ptr<Component> ComponentFactory::createLogComponent(ViewLayout* viewLayout)
|
||||
{
|
||||
std::shared_ptr<LogView> view = m_viewFactory->createLogView(viewLayout);
|
||||
@@ -100,14 +102,6 @@ std::shared_ptr<Component> ComponentFactory::createLogComponent(ViewLayout* view
|
||||
return std::make_shared<Component>(view, controller);
|
||||
}
|
||||
|
||||
std::shared_ptr<Component> ComponentFactory::createGraphComponent(ViewLayout* viewLayout)
|
||||
{
|
||||
std::shared_ptr<View> view = m_viewFactory->createGraphView(viewLayout);
|
||||
std::shared_ptr<GraphController> controller = std::make_shared<GraphController>(m_storageAccess);
|
||||
|
||||
return std::make_shared<Component>(view, controller);
|
||||
}
|
||||
|
||||
std::shared_ptr<Component> ComponentFactory::createRefreshComponent(ViewLayout* viewLayout)
|
||||
{
|
||||
std::shared_ptr<View> view = m_viewFactory->createRefreshView(viewLayout);
|
||||
@@ -116,18 +110,18 @@ std::shared_ptr<Component> ComponentFactory::createRefreshComponent(ViewLayout*
|
||||
return std::make_shared<Component>(view, controller);
|
||||
}
|
||||
|
||||
std::shared_ptr<Component> ComponentFactory::createSearchComponent(ViewLayout* viewLayout)
|
||||
std::shared_ptr<Component> ComponentFactory::createScreenSearchComponent(ViewLayout* viewLayout)
|
||||
{
|
||||
std::shared_ptr<SearchView> view = m_viewFactory->createSearchView(viewLayout);
|
||||
std::shared_ptr<SearchController> controller = std::make_shared<SearchController>(m_storageAccess);
|
||||
std::shared_ptr<ScreenSearchView> view = m_viewFactory->createScreenSearchView(viewLayout);
|
||||
std::shared_ptr<ScreenSearchController> controller = std::make_shared<ScreenSearchController>();
|
||||
|
||||
return std::make_shared<Component>(view, controller);
|
||||
}
|
||||
|
||||
std::shared_ptr<Component> ComponentFactory::createUndoRedoComponent(ViewLayout* viewLayout)
|
||||
std::shared_ptr<Component> ComponentFactory::createSearchComponent(ViewLayout* viewLayout)
|
||||
{
|
||||
std::shared_ptr<UndoRedoView> view = m_viewFactory->createUndoRedoView(viewLayout);
|
||||
std::shared_ptr<UndoRedoController> controller = std::make_shared<UndoRedoController>(m_storageAccess);
|
||||
std::shared_ptr<SearchView> view = m_viewFactory->createSearchView(viewLayout);
|
||||
std::shared_ptr<SearchController> controller = std::make_shared<SearchController>(m_storageAccess);
|
||||
|
||||
return std::make_shared<Component>(view, controller);
|
||||
}
|
||||
@@ -148,6 +142,22 @@ std::shared_ptr<Component> ComponentFactory::createStatusComponent(ViewLayout* v
|
||||
return std::make_shared<Component>(view, controller);
|
||||
}
|
||||
|
||||
std::shared_ptr<Component> ComponentFactory::createTooltipComponent(ViewLayout* viewLayout)
|
||||
{
|
||||
std::shared_ptr<TooltipView> view = m_viewFactory->createTooltipView(viewLayout);
|
||||
std::shared_ptr<Controller> controller = std::make_shared<TooltipController>(m_storageAccess);
|
||||
|
||||
return std::make_shared<Component>(view, controller);
|
||||
}
|
||||
|
||||
std::shared_ptr<Component> ComponentFactory::createUndoRedoComponent(ViewLayout* viewLayout)
|
||||
{
|
||||
std::shared_ptr<UndoRedoView> view = m_viewFactory->createUndoRedoView(viewLayout);
|
||||
std::shared_ptr<UndoRedoController> controller = std::make_shared<UndoRedoController>(m_storageAccess);
|
||||
|
||||
return std::make_shared<Component>(view, controller);
|
||||
}
|
||||
|
||||
ComponentFactory::ComponentFactory()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ public:
|
||||
std::shared_ptr<Component> createGraphComponent(ViewLayout* viewLayout);
|
||||
std::shared_ptr<Component> createLogComponent(ViewLayout* viewLayout);
|
||||
std::shared_ptr<Component> createRefreshComponent(ViewLayout* viewLayout);
|
||||
std::shared_ptr<Component> createScreenSearchComponent(ViewLayout* viewLayout);
|
||||
std::shared_ptr<Component> createSearchComponent(ViewLayout* viewLayout);
|
||||
std::shared_ptr<Component> createStatusBarComponent(ViewLayout* viewLayout);
|
||||
std::shared_ptr<Component> createStatusComponent(ViewLayout* viewLayout);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "component/ComponentManager.h"
|
||||
|
||||
#include "component/controller/Controller.h"
|
||||
#include "component/controller/ScreenSearchController.h"
|
||||
#include "component/view/CompositeView.h"
|
||||
#include "component/view/DialogView.h"
|
||||
#include "component/view/TabbedView.h"
|
||||
@@ -52,6 +53,12 @@ void ComponentManager::setup(ViewLayout* viewLayout)
|
||||
std::shared_ptr<Component> tooltipComponent = m_componentFactory->createTooltipComponent(viewLayout);
|
||||
m_components.push_back(tooltipComponent);
|
||||
|
||||
std::shared_ptr<Component> screenSearchComponent = m_componentFactory->createScreenSearchComponent(viewLayout);
|
||||
ScreenSearchController* screenSearchController = screenSearchComponent->getController<ScreenSearchController>();
|
||||
screenSearchController->addResponder(dynamic_cast<ScreenSearchResponder*>(graphComponent->getViewPtr()));
|
||||
screenSearchController->addResponder(dynamic_cast<ScreenSearchResponder*>(codeComponent->getViewPtr()));
|
||||
m_components.push_back(screenSearchComponent);
|
||||
|
||||
m_dialogView = m_componentFactory->getViewFactory()->createDialogView(viewLayout, m_componentFactory->getStorageAccess());
|
||||
|
||||
std::shared_ptr<TabbedView> tabbedView =
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
#include "component/controller/ScreenSearchController.h"
|
||||
|
||||
#include "component/view/ScreenSearchView.h"
|
||||
|
||||
ScreenSearchController::ScreenSearchController()
|
||||
{
|
||||
}
|
||||
|
||||
ScreenSearchController::~ScreenSearchController()
|
||||
{
|
||||
}
|
||||
|
||||
void ScreenSearchController::clear()
|
||||
{
|
||||
}
|
||||
|
||||
void ScreenSearchController::foundMatches(ScreenSearchResponder* responder, size_t matchCount)
|
||||
{
|
||||
if (matchCount)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_matchMutex);
|
||||
|
||||
size_t responderId = getResponderId(responder);
|
||||
if (!responderId)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<std::pair<size_t, size_t>> newMatches;
|
||||
for (size_t i = 0; i < matchCount; i++)
|
||||
{
|
||||
newMatches.push_back(std::make_pair(responderId, i));
|
||||
}
|
||||
|
||||
size_t i = 0;
|
||||
while (i < m_matches.size() && responderId > m_matches[i].first)
|
||||
{
|
||||
i++;
|
||||
}
|
||||
|
||||
m_matches.insert(m_matches.begin() + i, newMatches.begin(), newMatches.end());
|
||||
m_matchIndex = m_matches.size();
|
||||
}
|
||||
|
||||
getView<ScreenSearchView>()->setMatchCount(m_matches.size());
|
||||
}
|
||||
|
||||
void ScreenSearchController::addResponder(ScreenSearchResponder* responder)
|
||||
{
|
||||
if (responder)
|
||||
{
|
||||
m_responders.push_back(responder);
|
||||
getView<ScreenSearchView>()->addResponder(responder->getName());
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenSearchController::search(const std::string& query, const std::set<std::string>& responderNames)
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_matchMutex);
|
||||
m_matches.clear();
|
||||
m_matchIndex = 0;
|
||||
}
|
||||
|
||||
getView<ScreenSearchView>()->setMatchCount(0);
|
||||
|
||||
for (ScreenSearchResponder* responder : m_responders)
|
||||
{
|
||||
if (!responder->isVisible())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (query.size() && responderNames.find(responder->getName()) != responderNames.end())
|
||||
{
|
||||
responder->findMatches(this, query);
|
||||
}
|
||||
else
|
||||
{
|
||||
responder->clearMatches();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenSearchController::activateMatch(bool next)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_matchMutex);
|
||||
if (!m_matches.size())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_matchIndex != m_matches.size())
|
||||
{
|
||||
auto match = m_matches[m_matchIndex];
|
||||
m_responders[match.first - 1]->deactivateMatch(match.second);
|
||||
}
|
||||
|
||||
if (next)
|
||||
{
|
||||
if (m_matchIndex == m_matches.size())
|
||||
{
|
||||
m_matchIndex = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_matchIndex = (m_matchIndex + 1) % m_matches.size();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_matchIndex == 0)
|
||||
{
|
||||
m_matchIndex = m_matches.size() - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_matchIndex--;
|
||||
}
|
||||
}
|
||||
|
||||
auto match = m_matches[m_matchIndex];
|
||||
m_responders[match.first - 1]->activateMatch(match.second);
|
||||
|
||||
getView<ScreenSearchView>()->setMatchIndex(m_matchIndex + 1);
|
||||
}
|
||||
|
||||
void ScreenSearchController::clearMatches()
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_matchMutex);
|
||||
m_matches.clear();
|
||||
m_matchIndex = 0;
|
||||
}
|
||||
|
||||
for (ScreenSearchResponder* responder : m_responders)
|
||||
{
|
||||
responder->clearMatches();
|
||||
}
|
||||
}
|
||||
|
||||
size_t ScreenSearchController::getResponderId(ScreenSearchResponder* responder) const
|
||||
{
|
||||
for (size_t i = 0; i < m_responders.size(); i++)
|
||||
{
|
||||
if (m_responders[i] == responder)
|
||||
{
|
||||
return i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
#ifndef SCREEN_SEARCH_CONTROLLER_H
|
||||
#define SCREEN_SEARCH_CONTROLLER_H
|
||||
|
||||
#include <mutex>
|
||||
#include <set>
|
||||
|
||||
#include "component/controller/Controller.h"
|
||||
#include "component/controller/helper/ScreenSearchInterfaces.h"
|
||||
#include "utility/messaging/MessageListener.h"
|
||||
|
||||
class ScreenSearchController
|
||||
: public Controller
|
||||
, public ScreenSearchSender
|
||||
{
|
||||
public:
|
||||
ScreenSearchController();
|
||||
virtual ~ScreenSearchController();
|
||||
|
||||
// Controller implementation
|
||||
virtual void clear();
|
||||
|
||||
// ScreenSearchSender implementation
|
||||
virtual void foundMatches(ScreenSearchResponder* responder, size_t matchCount);
|
||||
|
||||
void addResponder(ScreenSearchResponder* responder);
|
||||
void search(const std::string& query, const std::set<std::string>& responderNames);
|
||||
void activateMatch(bool next);
|
||||
void clearMatches();
|
||||
|
||||
private:
|
||||
size_t getResponderId(ScreenSearchResponder* responder) const;
|
||||
|
||||
std::vector<ScreenSearchResponder*> m_responders;
|
||||
|
||||
std::vector<std::pair<size_t, size_t>> m_matches;
|
||||
size_t m_matchIndex = 0;
|
||||
std::mutex m_matchMutex;
|
||||
};
|
||||
|
||||
#endif // SCREEN_SEARCH_CONTROLLER_H
|
||||
@@ -0,0 +1,47 @@
|
||||
#ifndef CONTROLLER_PROXY_H
|
||||
#define CONTROLLER_PROXY_H
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include "utility/scheduling/TaskLambda.h"
|
||||
|
||||
#include "component/view/View.h"
|
||||
|
||||
class ControllerProxy
|
||||
{
|
||||
public:
|
||||
ControllerProxy(View* view)
|
||||
: m_view(view)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename ControllerType>
|
||||
void execute(std::function<void(ControllerType*)> callback)
|
||||
{
|
||||
ControllerType* controller = m_view->getController<ControllerType>();
|
||||
if (controller)
|
||||
{
|
||||
callback(controller);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename ControllerType>
|
||||
void executeAsTask(std::function<void(ControllerType*)> callback)
|
||||
{
|
||||
ControllerType* controller = m_view->getController<ControllerType>();
|
||||
if (controller)
|
||||
{
|
||||
Task::dispatch(std::make_shared<TaskLambda>(
|
||||
[callback, controller]()
|
||||
{
|
||||
callback(controller);
|
||||
}
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
View* m_view;
|
||||
};
|
||||
|
||||
#endif // CONTROLLER_PROXY_H
|
||||
@@ -0,0 +1,28 @@
|
||||
#ifndef SCREEN_SEARCH_INTERFACES_H
|
||||
#define SCREEN_SEARCH_INTERFACES_H
|
||||
|
||||
class ScreenSearchResponder;
|
||||
|
||||
class ScreenSearchSender
|
||||
{
|
||||
public:
|
||||
virtual ~ScreenSearchSender() {}
|
||||
|
||||
virtual void foundMatches(ScreenSearchResponder* responder, size_t matchCount) = 0;
|
||||
};
|
||||
|
||||
class ScreenSearchResponder
|
||||
{
|
||||
public:
|
||||
virtual ~ScreenSearchResponder() {}
|
||||
|
||||
virtual std::string getName() const = 0;
|
||||
virtual bool isVisible() const = 0;
|
||||
|
||||
virtual void findMatches(ScreenSearchSender* sender, const std::string& query) = 0;
|
||||
virtual void activateMatch(size_t matchIndex) = 0;
|
||||
virtual void deactivateMatch(size_t matchIndex) = 0;
|
||||
virtual void clearMatches() = 0;
|
||||
};
|
||||
|
||||
#endif // SCREEN_SEARCH_INTERFACES_H
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#include "data/ErrorInfo.h"
|
||||
|
||||
#include "component/controller/helper/ScreenSearchInterfaces.h"
|
||||
#include "component/view/helper/CodeSnippetParams.h"
|
||||
#include "component/view/View.h"
|
||||
|
||||
@@ -14,6 +15,7 @@ class SourceLocationCollection;
|
||||
|
||||
class CodeView
|
||||
: public View
|
||||
, public ScreenSearchResponder
|
||||
{
|
||||
public:
|
||||
static const char* VIEW_NAME;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "utility/math/Vector2.h"
|
||||
#include "utility/types.h"
|
||||
|
||||
#include "component/controller/helper/ScreenSearchInterfaces.h"
|
||||
#include "component/view/View.h"
|
||||
|
||||
struct DummyEdge;
|
||||
@@ -14,6 +15,7 @@ class Graph;
|
||||
|
||||
class GraphView
|
||||
: public View
|
||||
, public ScreenSearchResponder
|
||||
{
|
||||
public:
|
||||
static const char* VIEW_NAME;
|
||||
|
||||
@@ -22,6 +22,7 @@ float GraphViewStyle::s_zoomFactor;
|
||||
|
||||
std::map<std::string, GraphViewStyle::NodeColor> GraphViewStyle::s_nodeColors;
|
||||
std::map<std::string, std::string> GraphViewStyle::s_edgeColors;
|
||||
std::map<bool, GraphViewStyle::NodeColor> GraphViewStyle::s_screenMatchColors;
|
||||
|
||||
Vec2i GraphViewStyle::alignOnRaster(Vec2i position)
|
||||
{
|
||||
@@ -142,6 +143,7 @@ void GraphViewStyle::loadStyleSettings()
|
||||
|
||||
s_nodeColors.clear();
|
||||
s_edgeColors.clear();
|
||||
s_screenMatchColors.clear();
|
||||
|
||||
s_gridCellPadding = getImpl()->getCharHeightForNodeType(Node::NODE_TYPE) - 8;
|
||||
s_gridCellSize = s_gridCellPadding / 2;
|
||||
@@ -713,6 +715,28 @@ const std::string& GraphViewStyle::getEdgeColor(const std::string& typeStr, bool
|
||||
return s_edgeColors.find(type)->second;
|
||||
}
|
||||
|
||||
const GraphViewStyle::NodeColor& GraphViewStyle::getScreenMatchColor(bool focus)
|
||||
{
|
||||
auto it = s_screenMatchColors.find(focus);
|
||||
if (it != s_screenMatchColors.end())
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
|
||||
NodeColor color;
|
||||
ColorScheme* scheme = ColorScheme::getInstance().get();
|
||||
|
||||
ColorScheme::ColorState state = focus ? ColorScheme::FOCUS : ColorScheme::NORMAL;
|
||||
|
||||
color.fill = scheme->getCodeAnnotationTypeColor("screen_search", "fill", state);
|
||||
color.border = scheme->getCodeAnnotationTypeColor("screen_search", "border", state);
|
||||
color.text = scheme->getCodeAnnotationTypeColor("screen_search", "text", state);
|
||||
|
||||
s_screenMatchColors.emplace(focus, color);
|
||||
|
||||
return s_screenMatchColors.find(focus)->second;
|
||||
}
|
||||
|
||||
void GraphViewStyle::addIcon(Node::NodeType type, bool hasChildren, NodeStyle* style)
|
||||
{
|
||||
switch (type)
|
||||
|
||||
@@ -138,6 +138,7 @@ public:
|
||||
|
||||
static const NodeColor& getNodeColor(const std::string& typeStr, bool focus);
|
||||
static const std::string& getEdgeColor(const std::string& typeStr, bool focus);
|
||||
static const NodeColor& getScreenMatchColor(bool focus);
|
||||
|
||||
static int s_gridCellSize;
|
||||
static int s_gridCellPadding;
|
||||
@@ -156,6 +157,7 @@ private:
|
||||
|
||||
static std::map<std::string, NodeColor> s_nodeColors;
|
||||
static std::map<std::string, std::string> s_edgeColors;
|
||||
static std::map<bool, NodeColor> s_screenMatchColors;
|
||||
};
|
||||
|
||||
#endif // GRAPH_VIEW_STYLE_H
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
#include "component/view/ScreenSearchView.h"
|
||||
|
||||
ScreenSearchView::ScreenSearchView(ViewLayout* viewLayout)
|
||||
: View(viewLayout)
|
||||
{
|
||||
}
|
||||
|
||||
ScreenSearchView::~ScreenSearchView()
|
||||
{
|
||||
}
|
||||
|
||||
std::string ScreenSearchView::getName() const
|
||||
{
|
||||
return "ScreenSearchView";
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#ifndef SCREEN_SEARCH_VIEW_H
|
||||
#define SCREEN_SEARCH_VIEW_H
|
||||
|
||||
#include "component/view/View.h"
|
||||
|
||||
class ScreenSearchView
|
||||
: public View
|
||||
{
|
||||
public:
|
||||
ScreenSearchView(ViewLayout* viewLayout);
|
||||
virtual ~ScreenSearchView();
|
||||
|
||||
// View implementation
|
||||
virtual std::string getName() const;
|
||||
|
||||
virtual void setMatchCount(size_t matchCount) = 0;
|
||||
virtual void setMatchIndex(size_t matchIndex) = 0;
|
||||
|
||||
virtual void addResponder(const std::string& name) = 0;
|
||||
};
|
||||
|
||||
#endif // SCREEN_SEARCH_VIEW_H
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "component/view/ViewLayout.h"
|
||||
|
||||
class ViewWidgetWrapper;
|
||||
class ControllerProxy;
|
||||
|
||||
class View
|
||||
{
|
||||
@@ -43,6 +44,8 @@ protected:
|
||||
void setWidgetWrapper(std::shared_ptr<ViewWidgetWrapper> widgetWrapper);
|
||||
|
||||
private:
|
||||
friend ControllerProxy;
|
||||
|
||||
Component* m_component;
|
||||
ViewLayout* const m_viewLayout;
|
||||
std::shared_ptr<ViewWidgetWrapper> m_widgetWrapper;
|
||||
|
||||
@@ -13,6 +13,7 @@ class GraphView;
|
||||
class MainView;
|
||||
class LogView;
|
||||
class RefreshView;
|
||||
class ScreenSearchView;
|
||||
class SearchView;
|
||||
class StatusBarView;
|
||||
class StatusView;
|
||||
@@ -39,6 +40,7 @@ public:
|
||||
virtual std::shared_ptr<GraphView> createGraphView(ViewLayout* viewLayout) const = 0;
|
||||
virtual std::shared_ptr<LogView> createLogView(ViewLayout* viewLayout) const = 0;
|
||||
virtual std::shared_ptr<RefreshView> createRefreshView(ViewLayout* viewLayout) const = 0;
|
||||
virtual std::shared_ptr<ScreenSearchView> createScreenSearchView(ViewLayout* viewLayout) const = 0;
|
||||
virtual std::shared_ptr<SearchView> createSearchView(ViewLayout* viewLayout) const = 0;
|
||||
virtual std::shared_ptr<StatusBarView> createStatusBarView(ViewLayout* viewLayout) const = 0;
|
||||
virtual std::shared_ptr<StatusView> createStatusView(ViewLayout* viewLayout) const = 0;
|
||||
|
||||
@@ -10,10 +10,12 @@ int locationTypeToInt(LocationType type)
|
||||
return 1;
|
||||
case LOCATION_LOCAL_SYMBOL:
|
||||
return 2;
|
||||
case LOCATION_FULLTEXT:
|
||||
return 3;
|
||||
case LOCATION_ERROR:
|
||||
return 3;
|
||||
case LOCATION_FULLTEXT_SEARCH:
|
||||
return 4;
|
||||
case LOCATION_SCREEN_SEARCH:
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,9 +30,11 @@ LocationType intToLocationType(int value)
|
||||
case 2:
|
||||
return LOCATION_LOCAL_SYMBOL;
|
||||
case 3:
|
||||
return LOCATION_FULLTEXT;
|
||||
case 4:
|
||||
return LOCATION_ERROR;
|
||||
case 4:
|
||||
return LOCATION_FULLTEXT_SEARCH;
|
||||
case 5:
|
||||
return LOCATION_SCREEN_SEARCH;
|
||||
}
|
||||
return LOCATION_TOKEN;
|
||||
}
|
||||
|
||||
@@ -6,8 +6,9 @@ enum LocationType
|
||||
LOCATION_TOKEN,
|
||||
LOCATION_SCOPE,
|
||||
LOCATION_LOCAL_SYMBOL,
|
||||
LOCATION_FULLTEXT,
|
||||
LOCATION_ERROR
|
||||
LOCATION_ERROR,
|
||||
LOCATION_FULLTEXT_SEARCH,
|
||||
LOCATION_SCREEN_SEARCH
|
||||
};
|
||||
|
||||
int locationTypeToInt(LocationType type);
|
||||
|
||||
@@ -177,7 +177,7 @@ bool SourceLocation::isScopeLocation() const
|
||||
|
||||
bool SourceLocation::isFullTextSearchMatch() const
|
||||
{
|
||||
return m_type == LOCATION_FULLTEXT;
|
||||
return m_type == LOCATION_FULLTEXT_SEARCH;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& ostream, const SourceLocation& location)
|
||||
|
||||
@@ -557,7 +557,7 @@ std::shared_ptr<SourceLocationCollection> PersistentStorage::getFullTextSearchLo
|
||||
Id locationId = ~(~Id(0) >> 1) + collection->getSourceLocationCount() + 1;
|
||||
|
||||
collection->addSourceLocation(
|
||||
LOCATION_FULLTEXT,
|
||||
LOCATION_FULLTEXT_SEARCH,
|
||||
locationId,
|
||||
std::vector<Id>(),
|
||||
filePath,
|
||||
|
||||
@@ -48,6 +48,8 @@ add_files(
|
||||
qt/element/QtProgressBar.h
|
||||
qt/element/QtRefreshBar.cpp
|
||||
qt/element/QtRefreshBar.h
|
||||
qt/element/QtScreenSearchBox.cpp
|
||||
qt/element/QtScreenSearchBox.h
|
||||
qt/element/QtSearchBar.cpp
|
||||
qt/element/QtSearchBar.h
|
||||
qt/element/QtSmartSearchBox.cpp
|
||||
@@ -145,6 +147,8 @@ add_files(
|
||||
qt/view/QtMainView.h
|
||||
qt/view/QtRefreshView.cpp
|
||||
qt/view/QtRefreshView.h
|
||||
qt/view/QtScreenSearchView.cpp
|
||||
qt/view/QtScreenSearchView.h
|
||||
qt/view/QtSearchView.cpp
|
||||
qt/view/QtSearchView.h
|
||||
qt/view/QtStatusBarView.cpp
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "utility/messaging/type/MessageMoveIDECursor.h"
|
||||
#include "utility/messaging/type/MessageShowErrors.h"
|
||||
#include "utility/utility.h"
|
||||
#include "utility/utilityString.h"
|
||||
|
||||
#include "qt/element/QtCodeNavigator.h"
|
||||
#include "qt/utility/QtContextMenu.h"
|
||||
@@ -163,6 +164,18 @@ void QtCodeArea::lineNumberAreaPaintEvent(QPaintEvent *event)
|
||||
}
|
||||
break;
|
||||
|
||||
case LOCATION_ERROR:
|
||||
case LOCATION_SCREEN_SEARCH:
|
||||
if (annotation.isFocused || annotation.isActive)
|
||||
{
|
||||
focus = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
active = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case LOCATION_TOKEN:
|
||||
case LOCATION_SCOPE:
|
||||
if (annotation.isFocused && utility::shareElement(activeSymbolIds, annotation.tokenIds))
|
||||
@@ -356,6 +369,65 @@ QRectF QtCodeArea::getLineRectForLineNumber(uint lineNumber) const
|
||||
return blockBoundingGeometry(block);
|
||||
}
|
||||
|
||||
void QtCodeArea::findScreenMatches(const std::string& query, std::vector<std::pair<QtCodeArea*, Id>>* screenMatches)
|
||||
{
|
||||
const std::string& code = utility::toLowerCase(getCode());
|
||||
size_t pos = 0;
|
||||
while (pos != std::string::npos)
|
||||
{
|
||||
pos = code.find(query, pos);
|
||||
if (pos == std::string::npos)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
Annotation matchAnnotation;
|
||||
matchAnnotation.start = pos;
|
||||
matchAnnotation.end = pos + query.size();
|
||||
|
||||
std::pair<int, int> start = toLineColumn(matchAnnotation.start);
|
||||
matchAnnotation.startLine = start.first;
|
||||
matchAnnotation.startCol = start.second;
|
||||
|
||||
std::pair<int, int> end = toLineColumn(matchAnnotation.end);
|
||||
matchAnnotation.endLine = end.first;
|
||||
matchAnnotation.endCol = end.second;
|
||||
|
||||
// Set first 2 bits to 1 to avoid collisions
|
||||
matchAnnotation.locationId = ~(~Id(0) >> 2) + screenMatches->size() + 1;
|
||||
matchAnnotation.locationType = LOCATION_SCREEN_SEARCH;
|
||||
|
||||
matchAnnotation.isActive = false;
|
||||
matchAnnotation.isFocused = false;
|
||||
|
||||
m_annotations.push_back(matchAnnotation);
|
||||
screenMatches->push_back(std::make_pair(this, matchAnnotation.locationId));
|
||||
|
||||
pos += query.size();
|
||||
}
|
||||
|
||||
if (screenMatches->size() && screenMatches->back().first == this)
|
||||
{
|
||||
viewport()->update();
|
||||
}
|
||||
}
|
||||
|
||||
void QtCodeArea::clearScreenMatches()
|
||||
{
|
||||
size_t i = m_annotations.size();
|
||||
while (i > 0 && m_annotations[i - 1].locationType == LOCATION_SCREEN_SEARCH)
|
||||
{
|
||||
i--;
|
||||
m_linesToRehighlight.push_back(m_annotations[i].startLine - getStartLineNumber());
|
||||
}
|
||||
|
||||
if (i != m_annotations.size())
|
||||
{
|
||||
m_annotations.erase(m_annotations.begin() + i, m_annotations.end());
|
||||
viewport()->update();
|
||||
}
|
||||
}
|
||||
|
||||
void QtCodeArea::resizeEvent(QResizeEvent *e)
|
||||
{
|
||||
QPlainTextEdit::resizeEvent(e);
|
||||
|
||||
@@ -83,6 +83,9 @@ public:
|
||||
|
||||
QRectF getLineRectForLineNumber(uint lineNumber) const;
|
||||
|
||||
void findScreenMatches(const std::string& query, std::vector<std::pair<QtCodeArea*, Id>>* screenMatches);
|
||||
void clearScreenMatches();
|
||||
|
||||
protected:
|
||||
virtual void resizeEvent(QResizeEvent* event) Q_DECL_OVERRIDE;
|
||||
virtual void mouseReleaseEvent(QMouseEvent* event) Q_DECL_OVERRIDE;
|
||||
|
||||
@@ -549,7 +549,7 @@ const QtCodeField::AnnotationColor& QtCodeField::getAnnotationColorForAnnotation
|
||||
if (!s_annotationColors.size())
|
||||
{
|
||||
ColorScheme* scheme = ColorScheme::getInstance().get();
|
||||
std::vector<std::string> types = { "token", "local_symbol", "scope", "error", "fulltext" };
|
||||
std::vector<std::string> types = { "token", "local_symbol", "scope", "error", "fulltext_search", "screen_search" };
|
||||
std::vector<ColorScheme::ColorState> states = { ColorScheme::NORMAL, ColorScheme::FOCUS, ColorScheme::ACTIVE };
|
||||
|
||||
for (const std::string& type : types)
|
||||
@@ -579,10 +579,14 @@ const QtCodeField::AnnotationColor& QtCodeField::getAnnotationColorForAnnotation
|
||||
{
|
||||
i = 9;
|
||||
}
|
||||
else if (annotation.locationType == LOCATION_FULLTEXT)
|
||||
else if (annotation.locationType == LOCATION_FULLTEXT_SEARCH)
|
||||
{
|
||||
i = 12;
|
||||
}
|
||||
else if (annotation.locationType == LOCATION_SCREEN_SEARCH)
|
||||
{
|
||||
i = 15;
|
||||
}
|
||||
|
||||
if (annotation.isActive)
|
||||
{
|
||||
|
||||
@@ -99,6 +99,7 @@ protected:
|
||||
|
||||
std::vector<Annotation> m_annotations;
|
||||
std::vector<const Annotation*> m_hoveredAnnotations;
|
||||
std::vector<int> m_linesToRehighlight;
|
||||
|
||||
private:
|
||||
static std::vector<AnnotationColor> s_annotationColors;
|
||||
@@ -113,7 +114,6 @@ private:
|
||||
QtHighlighter* m_highlighter;
|
||||
|
||||
std::vector<int> m_lineLengths;
|
||||
std::vector<int> m_linesToRehighlight;
|
||||
|
||||
int m_endTextEditPosition;
|
||||
};
|
||||
|
||||
@@ -143,13 +143,12 @@ QtCodeSnippet* QtCodeFile::addCodeSnippet(const CodeSnippetParams& params)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
m_isCollapsed = false;
|
||||
std::shared_ptr<QtCodeSnippet> snippet(new QtCodeSnippet(params, m_navigator, this));
|
||||
|
||||
if (params.reduced)
|
||||
{
|
||||
m_title->setProject(params.title);
|
||||
m_isCollapsed = false;
|
||||
}
|
||||
|
||||
m_snippetLayout->addWidget(snippet.get());
|
||||
@@ -172,10 +171,6 @@ QtCodeSnippet* QtCodeFile::addCodeSnippet(const CodeSnippetParams& params)
|
||||
|
||||
return m_fileSnippet.get();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_isCollapsed = false;
|
||||
}
|
||||
|
||||
m_snippets.push_back(snippet);
|
||||
|
||||
@@ -229,6 +224,11 @@ QtCodeSnippet* QtCodeFile::insertCodeSnippet(const CodeSnippetParams& params)
|
||||
|
||||
QtCodeSnippet* QtCodeFile::getSnippetForLocationId(Id locationId) const
|
||||
{
|
||||
if (m_fileSnippet && m_fileSnippet->isVisible() && m_fileSnippet->getLineNumberForLocationId(locationId))
|
||||
{
|
||||
return m_fileSnippet.get();
|
||||
}
|
||||
|
||||
for (const std::shared_ptr<QtCodeSnippet>& snippet : m_snippets)
|
||||
{
|
||||
if (snippet->getLineNumberForLocationId(locationId))
|
||||
@@ -438,6 +438,23 @@ void QtCodeFile::updateTitleBar()
|
||||
m_title->updateTexts();
|
||||
}
|
||||
|
||||
void QtCodeFile::findScreenMatches(const std::string& query, std::vector<std::pair<QtCodeArea*, Id>>* screenMatches)
|
||||
{
|
||||
if (m_fileSnippet && m_fileSnippet->isVisible())
|
||||
{
|
||||
m_fileSnippet->findScreenMatches(query, screenMatches);
|
||||
return;
|
||||
}
|
||||
|
||||
for (const std::shared_ptr<QtCodeSnippet>& snippet : m_snippets)
|
||||
{
|
||||
if (snippet->isVisible())
|
||||
{
|
||||
snippet->findScreenMatches(query, screenMatches);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QtCodeFile::clickedMinimizeButton()
|
||||
{
|
||||
// overview stats
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
class QLabel;
|
||||
class QPushButton;
|
||||
class QtCodeArea;
|
||||
class QtCodeFileTitleButton;
|
||||
class QtCodeNavigator;
|
||||
class QtCodeSnippet;
|
||||
@@ -59,6 +60,8 @@ public:
|
||||
void updateSnippets();
|
||||
void updateTitleBar();
|
||||
|
||||
void findScreenMatches(const std::string& query, std::vector<std::pair<QtCodeArea*, Id>>* screenMatches);
|
||||
|
||||
public slots:
|
||||
void clickedMinimizeButton();
|
||||
void clickedSnippetButton();
|
||||
|
||||
@@ -199,6 +199,14 @@ void QtCodeFileList::onWindowFocus()
|
||||
}
|
||||
}
|
||||
|
||||
void QtCodeFileList::findScreenMatches(const std::string& query, std::vector<std::pair<QtCodeArea*, Id>>* screenMatches)
|
||||
{
|
||||
for (const std::shared_ptr<QtCodeFile>& filePtr : m_files)
|
||||
{
|
||||
filePtr->findScreenMatches(query, screenMatches);
|
||||
}
|
||||
}
|
||||
|
||||
void QtCodeFileList::setFileMinimized(const FilePath path)
|
||||
{
|
||||
getFile(path)->setMinimized();
|
||||
|
||||
@@ -43,6 +43,8 @@ public:
|
||||
|
||||
virtual void onWindowFocus();
|
||||
|
||||
virtual void findScreenMatches(const std::string& query, std::vector<std::pair<QtCodeArea*, Id>>* screenMatches);
|
||||
|
||||
void setFileMinimized(const FilePath path);
|
||||
void setFileSnippets(const FilePath path);
|
||||
void setFileMaximized(const FilePath path);
|
||||
|
||||
@@ -225,6 +225,14 @@ void QtCodeFileSingle::onWindowFocus()
|
||||
m_title->updateTexts();
|
||||
}
|
||||
|
||||
void QtCodeFileSingle::findScreenMatches(const std::string& query, std::vector<std::pair<QtCodeArea*, Id>>* screenMatches)
|
||||
{
|
||||
if (m_area)
|
||||
{
|
||||
m_area->findScreenMatches(query, screenMatches);
|
||||
}
|
||||
}
|
||||
|
||||
const FilePath& QtCodeFileSingle::getCurrentFilePath() const
|
||||
{
|
||||
return m_currentFilePath;
|
||||
|
||||
@@ -43,6 +43,8 @@ public:
|
||||
|
||||
virtual void onWindowFocus() override;
|
||||
|
||||
virtual void findScreenMatches(const std::string& query, std::vector<std::pair<QtCodeArea*, Id>>* screenMatches) override;
|
||||
|
||||
const FilePath& getCurrentFilePath() const;
|
||||
bool hasFileCached(const FilePath& filePath) const;
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
class FilePath;
|
||||
class QRectF;
|
||||
class QAbstractScrollArea;
|
||||
class QtCodeArea;
|
||||
class QWidget;
|
||||
|
||||
class QtCodeNavigateable
|
||||
@@ -29,6 +30,8 @@ public:
|
||||
|
||||
virtual void onWindowFocus() = 0;
|
||||
|
||||
virtual void findScreenMatches(const std::string& query, std::vector<std::pair<QtCodeArea*, Id>>* screenMatches) = 0;
|
||||
|
||||
protected:
|
||||
void ensureWidgetVisibleAnimated(QWidget* parentWidget, QWidget *childWidget, QRectF rect, bool animated, bool onTop);
|
||||
void ensurePercentVisibleAnimated(double percentA, double percentB, bool animated, bool onTop);
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "data/location/SourceLocation.h"
|
||||
#include "data/location/SourceLocationCollection.h"
|
||||
#include "data/location/SourceLocationFile.h"
|
||||
#include "qt/element/QtCodeArea.h"
|
||||
#include "qt/element/QtCodeFile.h"
|
||||
#include "qt/element/QtCodeSnippet.h"
|
||||
#include "qt/utility/utilityQt.h"
|
||||
@@ -255,6 +256,9 @@ void QtCodeNavigator::clearCodeSnippets()
|
||||
m_refIndex = 0;
|
||||
|
||||
m_singleHasNewFile = false;
|
||||
|
||||
m_screenMatches.clear();
|
||||
m_activeScreenMatchId = 0;
|
||||
}
|
||||
|
||||
void QtCodeNavigator::clearFile()
|
||||
@@ -549,6 +553,60 @@ void QtCodeNavigator::refreshStyle()
|
||||
clearCaches();
|
||||
}
|
||||
|
||||
size_t QtCodeNavigator::findScreenMatches(const std::string& query)
|
||||
{
|
||||
clearScreenMatches();
|
||||
|
||||
m_current->findScreenMatches(query, &m_screenMatches);
|
||||
|
||||
return m_screenMatches.size();
|
||||
}
|
||||
|
||||
void QtCodeNavigator::activateScreenMatch(size_t matchIndex)
|
||||
{
|
||||
if (matchIndex >= m_screenMatches.size())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::pair<QtCodeArea*, Id> p = m_screenMatches[matchIndex];
|
||||
m_activeScreenMatchId = p.second;
|
||||
m_currentActiveLocationIds.insert(m_activeScreenMatchId);
|
||||
p.first->updateContent();
|
||||
|
||||
requestScroll(p.first->getSourceLocationFile()->getFilePath(), 0, m_activeScreenMatchId, true, false);
|
||||
emit scrollRequest();
|
||||
}
|
||||
|
||||
void QtCodeNavigator::deactivateScreenMatch(size_t matchIndex)
|
||||
{
|
||||
if (matchIndex >= m_screenMatches.size())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_currentActiveLocationIds.erase(m_screenMatches[matchIndex].second);
|
||||
m_screenMatches[matchIndex].first->updateContent();
|
||||
|
||||
m_activeScreenMatchId = 0;
|
||||
}
|
||||
|
||||
void QtCodeNavigator::clearScreenMatches()
|
||||
{
|
||||
if (m_activeScreenMatchId)
|
||||
{
|
||||
m_currentActiveLocationIds.erase(m_activeScreenMatchId);
|
||||
m_activeScreenMatchId = 0;
|
||||
}
|
||||
|
||||
for (auto p : m_screenMatches)
|
||||
{
|
||||
p.first->clearScreenMatches();
|
||||
}
|
||||
|
||||
m_screenMatches.clear();
|
||||
}
|
||||
|
||||
void QtCodeNavigator::scrollToValue(int value, bool inListMode)
|
||||
{
|
||||
if ((m_mode == MODE_LIST) == inListMode)
|
||||
|
||||
@@ -83,6 +83,11 @@ public:
|
||||
|
||||
void refreshStyle();
|
||||
|
||||
size_t findScreenMatches(const std::string& query);
|
||||
void activateScreenMatch(size_t matchIndex);
|
||||
void deactivateScreenMatch(size_t matchIndex);
|
||||
void clearScreenMatches();
|
||||
|
||||
void scrollToValue(int value, bool inListMode);
|
||||
void scrollToLine(const FilePath& filePath, unsigned int line);
|
||||
void scrollToDefinition(bool animated, bool ignoreActiveReference);
|
||||
@@ -192,6 +197,9 @@ private:
|
||||
|
||||
ScrollRequest m_scrollRequest;
|
||||
bool m_singleHasNewFile;
|
||||
|
||||
std::vector<std::pair<QtCodeArea*, Id>> m_screenMatches;
|
||||
Id m_activeScreenMatchId = 0;
|
||||
};
|
||||
|
||||
#endif // QT_CODE_NAVIGATOR_H
|
||||
|
||||
@@ -187,6 +187,11 @@ std::string QtCodeSnippet::getCode() const
|
||||
return m_codeArea->getCode();
|
||||
}
|
||||
|
||||
void QtCodeSnippet::findScreenMatches(const std::string& query, std::vector<std::pair<QtCodeArea*, Id>>* screenMatches)
|
||||
{
|
||||
m_codeArea->findScreenMatches(query, screenMatches);
|
||||
}
|
||||
|
||||
void QtCodeSnippet::clickedTitle()
|
||||
{
|
||||
if (m_titleId > 0)
|
||||
|
||||
@@ -51,6 +51,8 @@ public:
|
||||
|
||||
std::string getCode() const;
|
||||
|
||||
void findScreenMatches(const std::string& query, std::vector<std::pair<QtCodeArea*, Id>>* screenMatches);
|
||||
|
||||
private slots:
|
||||
void clickedTitle();
|
||||
void clickedFooter();
|
||||
|
||||
@@ -0,0 +1,263 @@
|
||||
#include "qt/element/QtScreenSearchBox.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QCheckBox>
|
||||
#include <QFocusEvent>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLineEdit>
|
||||
#include <QPushButton>
|
||||
#include <QTimer>
|
||||
|
||||
#include "component/controller/helper/ControllerProxy.h"
|
||||
#include "component/controller/ScreenSearchController.h"
|
||||
#include "qt/utility/utilityQt.h"
|
||||
#include "utility/ResourcePaths.h"
|
||||
|
||||
|
||||
QtFocusInFilter::QtFocusInFilter()
|
||||
{
|
||||
}
|
||||
|
||||
bool QtFocusInFilter::eventFilter(QObject* obj, QEvent* event)
|
||||
{
|
||||
QLineEdit* lineEdit = dynamic_cast<QLineEdit*>(obj);
|
||||
if (lineEdit && event->type() == QEvent::FocusIn && dynamic_cast<QFocusEvent*>(event)->reason() == Qt::MouseFocusReason)
|
||||
{
|
||||
emit focusIn();
|
||||
}
|
||||
|
||||
return QObject::eventFilter(obj, event);
|
||||
}
|
||||
|
||||
|
||||
QtScreenSearchBox::QtScreenSearchBox(ControllerProxy* controllerProxy, QWidget* parent)
|
||||
: QFrame(parent)
|
||||
, m_controllerProxy(controllerProxy)
|
||||
{
|
||||
setObjectName("screen_search_box");
|
||||
|
||||
QHBoxLayout* layout = new QHBoxLayout();
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
layout->setSpacing(0);
|
||||
setLayout(layout);
|
||||
|
||||
// search field
|
||||
{
|
||||
m_searchButton = new QPushButton();
|
||||
m_searchButton->setAttribute(Qt::WA_LayoutUsesWidgetRect); // fixes layouting on Mac
|
||||
m_searchButton->setObjectName("search_button");
|
||||
layout->addWidget(m_searchButton);
|
||||
|
||||
connect(m_searchButton, &QPushButton::clicked, this, &QtScreenSearchBox::setFocus);
|
||||
|
||||
m_searchBox = new QLineEdit(this);
|
||||
m_searchBox->setObjectName("search_box");
|
||||
m_searchBox->setAttribute(Qt::WA_LayoutUsesWidgetRect); // fixes layouting on Mac
|
||||
m_searchBox->setAttribute(Qt::WA_MacShowFocusRect, 0); // remove blue focus box on Mac
|
||||
layout->addWidget(m_searchBox);
|
||||
|
||||
connect(m_searchBox, &QLineEdit::textChanged, this, &QtScreenSearchBox::searchQueryChanged);
|
||||
connect(m_searchBox, &QLineEdit::returnPressed, this, &QtScreenSearchBox::returnPressed);
|
||||
|
||||
QtFocusInFilter* filter = new QtFocusInFilter();
|
||||
m_searchBox->installEventFilter(filter);
|
||||
connect(filter, &QtFocusInFilter::focusIn, this, &QtScreenSearchBox::findMatches);
|
||||
}
|
||||
|
||||
// match label
|
||||
{
|
||||
m_matchLabel = new QPushButton();
|
||||
m_matchLabel->setAttribute(Qt::WA_LayoutUsesWidgetRect); // fixes layouting on Mac
|
||||
m_matchLabel->setObjectName("match_label");
|
||||
layout->addWidget(m_matchLabel);
|
||||
|
||||
connect(m_matchLabel, &QPushButton::clicked, this, &QtScreenSearchBox::setFocus);
|
||||
}
|
||||
|
||||
// buttons
|
||||
{
|
||||
m_prevButton = new QPushButton();
|
||||
m_nextButton = new QPushButton();
|
||||
|
||||
m_prevButton->setAttribute(Qt::WA_LayoutUsesWidgetRect); // fixes layouting on Mac
|
||||
m_nextButton->setAttribute(Qt::WA_LayoutUsesWidgetRect); // fixes layouting on Mac
|
||||
|
||||
m_prevButton->setObjectName("prev_button");
|
||||
m_nextButton->setObjectName("next_button");
|
||||
|
||||
layout->addWidget(m_prevButton);
|
||||
layout->addWidget(m_nextButton);
|
||||
|
||||
connect(m_prevButton, &QPushButton::clicked, this, &QtScreenSearchBox::previousPressed);
|
||||
connect(m_nextButton, &QPushButton::clicked, this, &QtScreenSearchBox::nextPressed);
|
||||
}
|
||||
|
||||
// filter
|
||||
{
|
||||
m_checkboxLayout = new QHBoxLayout();
|
||||
layout->addLayout(m_checkboxLayout);
|
||||
layout->addStretch();
|
||||
}
|
||||
|
||||
// buttons
|
||||
{
|
||||
m_closeButton = new QPushButton();
|
||||
m_closeButton->setObjectName("close_button");
|
||||
m_closeButton->setAttribute(Qt::WA_LayoutUsesWidgetRect); // fixes layouting on Mac
|
||||
layout->addWidget(m_closeButton);
|
||||
|
||||
connect(m_closeButton, &QPushButton::clicked, [this](){ emit closePressed(); });
|
||||
}
|
||||
|
||||
m_timer = new QTimer(this);
|
||||
m_timer->setSingleShot(true);
|
||||
connect(m_timer, &QTimer::timeout, this, &QtScreenSearchBox::findMatches);
|
||||
|
||||
refreshStyle();
|
||||
setMatchCount(0);
|
||||
}
|
||||
|
||||
QtScreenSearchBox::~QtScreenSearchBox()
|
||||
{
|
||||
}
|
||||
|
||||
void QtScreenSearchBox::refreshStyle()
|
||||
{
|
||||
m_searchButton->setIcon(utility::createButtonIcon(
|
||||
ResourcePaths::getGuiPath().str() + "search_view/images/search.png",
|
||||
"screen_search/button"
|
||||
));
|
||||
|
||||
m_prevButton->setIcon(utility::createButtonIcon(
|
||||
ResourcePaths::getGuiPath().str() + "code_view/images/arrow_left.png",
|
||||
"screen_search/button"
|
||||
));
|
||||
|
||||
m_nextButton->setIcon(utility::createButtonIcon(
|
||||
ResourcePaths::getGuiPath().str() + "code_view/images/arrow_right.png",
|
||||
"screen_search/button"
|
||||
));
|
||||
|
||||
m_closeButton->setIcon(utility::createButtonIcon(
|
||||
ResourcePaths::getGuiPath().str() + "screen_search_view/images/close.png",
|
||||
"screen_search/button"
|
||||
));
|
||||
|
||||
m_searchButton->setIconSize(QSize(12, 12));
|
||||
m_prevButton->setIconSize(QSize(12, 12));
|
||||
m_nextButton->setIconSize(QSize(12, 12));
|
||||
m_closeButton->setIconSize(QSize(15, 15));
|
||||
}
|
||||
|
||||
void QtScreenSearchBox::setMatchCount(size_t matchCount)
|
||||
{
|
||||
m_matchCount = matchCount;
|
||||
m_matchIndex = 0;
|
||||
updateMatchLabel();
|
||||
|
||||
m_prevButton->setEnabled(matchCount > 0);
|
||||
m_nextButton->setEnabled(matchCount > 0);
|
||||
}
|
||||
|
||||
void QtScreenSearchBox::setMatchIndex(size_t matchIndex)
|
||||
{
|
||||
m_matchIndex = matchIndex;
|
||||
updateMatchLabel();
|
||||
}
|
||||
|
||||
void QtScreenSearchBox::addResponder(const std::string& name)
|
||||
{
|
||||
QCheckBox* box = new QCheckBox(name.c_str());
|
||||
box->setObjectName("filter_checkbox");
|
||||
box->setChecked(true);
|
||||
m_checkBoxes.push_back(box);
|
||||
m_checkboxLayout->addWidget(box);
|
||||
|
||||
connect(box, &QCheckBox::stateChanged, this, &QtScreenSearchBox::findMatches);
|
||||
}
|
||||
|
||||
void QtScreenSearchBox::setFocus()
|
||||
{
|
||||
m_searchBox->setFocus();
|
||||
|
||||
if (m_searchBox->text().size())
|
||||
{
|
||||
m_searchBox->selectAll();
|
||||
searchQueryChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void QtScreenSearchBox::searchQueryChanged()
|
||||
{
|
||||
m_timer->stop();
|
||||
m_timer->start(200);
|
||||
}
|
||||
|
||||
void QtScreenSearchBox::findMatches()
|
||||
{
|
||||
m_controllerProxy->executeAsTask<ScreenSearchController>(
|
||||
[this](ScreenSearchController* controller)
|
||||
{
|
||||
std::set<std::string> responderNames;
|
||||
for (QCheckBox* box : m_checkBoxes)
|
||||
{
|
||||
if (box->isChecked())
|
||||
{
|
||||
responderNames.insert(box->text().toStdString());
|
||||
}
|
||||
}
|
||||
|
||||
controller->search(m_searchBox->text().toLower().toStdString(), responderNames);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void QtScreenSearchBox::returnPressed()
|
||||
{
|
||||
if (Qt::KeyboardModifier::ShiftModifier & QApplication::keyboardModifiers())
|
||||
{
|
||||
previousPressed();
|
||||
}
|
||||
else
|
||||
{
|
||||
nextPressed();
|
||||
}
|
||||
}
|
||||
|
||||
void QtScreenSearchBox::previousPressed()
|
||||
{
|
||||
activateMatch(false);
|
||||
}
|
||||
|
||||
void QtScreenSearchBox::nextPressed()
|
||||
{
|
||||
activateMatch(true);
|
||||
}
|
||||
|
||||
void QtScreenSearchBox::activateMatch(bool next)
|
||||
{
|
||||
m_controllerProxy->executeAsTask<ScreenSearchController>(
|
||||
[next, this](ScreenSearchController* controller)
|
||||
{
|
||||
controller->activateMatch(next);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void QtScreenSearchBox::updateMatchLabel()
|
||||
{
|
||||
QString text;
|
||||
|
||||
if (m_matchIndex > 0)
|
||||
{
|
||||
text += QString::number(m_matchIndex) + " of ";
|
||||
}
|
||||
|
||||
text += QString::number(m_matchCount) + " match";
|
||||
if (m_matchCount != 1)
|
||||
{
|
||||
text += "es";
|
||||
}
|
||||
|
||||
m_matchLabel->setText(text);
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
#ifndef QT_SCREEN_SEARCH_BOX_H
|
||||
#define QT_SCREEN_SEARCH_BOX_H
|
||||
|
||||
#include <QFrame>
|
||||
|
||||
class ControllerProxy;
|
||||
class QCheckBox;
|
||||
class QHBoxLayout;
|
||||
class QLineEdit;
|
||||
class QPushButton;
|
||||
class QTimer;
|
||||
|
||||
|
||||
class QtFocusInFilter
|
||||
: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QtFocusInFilter();
|
||||
|
||||
signals:
|
||||
void focusIn();
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject* obj, QEvent* event);
|
||||
};
|
||||
|
||||
|
||||
class QtScreenSearchBox
|
||||
: public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QtScreenSearchBox(ControllerProxy* controllerProxy, QWidget* parent = nullptr);
|
||||
virtual ~QtScreenSearchBox();
|
||||
|
||||
void refreshStyle();
|
||||
|
||||
void setMatchCount(size_t matchCount);
|
||||
void setMatchIndex(size_t matchIndex);
|
||||
|
||||
void addResponder(const std::string& name);
|
||||
|
||||
signals:
|
||||
void closePressed();
|
||||
|
||||
public slots:
|
||||
void setFocus();
|
||||
|
||||
private slots:
|
||||
void searchQueryChanged();
|
||||
void findMatches();
|
||||
void returnPressed();
|
||||
|
||||
void previousPressed();
|
||||
void nextPressed();
|
||||
|
||||
private:
|
||||
void activateMatch(bool next);
|
||||
|
||||
void updateMatchLabel();
|
||||
|
||||
ControllerProxy* m_controllerProxy;
|
||||
|
||||
QLineEdit* m_searchBox;
|
||||
QPushButton* m_matchLabel;
|
||||
|
||||
QPushButton* m_searchButton;
|
||||
QPushButton* m_prevButton;
|
||||
QPushButton* m_nextButton;
|
||||
QPushButton* m_closeButton;
|
||||
|
||||
QHBoxLayout* m_checkboxLayout;
|
||||
std::vector<QCheckBox*> m_checkBoxes;
|
||||
|
||||
size_t m_matchCount = 0;
|
||||
size_t m_matchIndex = 0;
|
||||
|
||||
QTimer* m_timer;
|
||||
};
|
||||
|
||||
#endif // QT_SCREEN_SEARCH_BOX_H
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <QTextDocument>
|
||||
|
||||
#include "settings/ColorScheme.h"
|
||||
#include "utility/utility.h"
|
||||
|
||||
QVector<QtHighlighter::HighlightingRule> QtHighlighter::s_highlightingRules;
|
||||
QVector<QtHighlighter::HighlightingRule> QtHighlighter::s_highlightingRulesCpp;
|
||||
@@ -110,16 +111,16 @@ QtHighlighter::QtHighlighter(QTextDocument *document, LanguageType language)
|
||||
: m_document(document)
|
||||
, m_language(language)
|
||||
{
|
||||
if (m_language == LANGUAGE_UNKNOWN)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!s_highlightingRules.size())
|
||||
{
|
||||
createHighlightingRules();
|
||||
}
|
||||
|
||||
if (m_language == LANGUAGE_UNKNOWN)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_language == LANGUAGE_JAVA)
|
||||
{
|
||||
m_highlightingRules = s_highlightingRulesJava;
|
||||
@@ -134,11 +135,6 @@ QtHighlighter::QtHighlighter(QTextDocument *document, LanguageType language)
|
||||
|
||||
void QtHighlighter::highlightDocument()
|
||||
{
|
||||
if (m_language == LANGUAGE_UNKNOWN)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QTextDocument* doc = document();
|
||||
|
||||
int docStart = 0;
|
||||
@@ -150,26 +146,29 @@ void QtHighlighter::highlightDocument()
|
||||
docEnd -= 1;
|
||||
applyFormat(docStart, docEnd, s_textFormat);
|
||||
|
||||
m_ranges.clear();
|
||||
|
||||
m_highlightedLines.clear();
|
||||
m_highlightedLines.resize(document()->blockCount(), false);
|
||||
|
||||
for (QTextBlock it = doc->begin(); it != doc->end(); it = it.next())
|
||||
{
|
||||
formatBlock(it, s_quotationRule, &m_ranges, true);
|
||||
}
|
||||
|
||||
highlightMultiLineComments(&m_ranges);
|
||||
}
|
||||
|
||||
void QtHighlighter::highlightRange(int startLine, int endLine)
|
||||
{
|
||||
if (m_language == LANGUAGE_UNKNOWN)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_quotationRanges.clear();
|
||||
m_multiLineCommentRanges.clear();
|
||||
|
||||
std::vector<std::pair<int, int>> ranges;
|
||||
ranges.push_back(std::pair<int, int>(docStart, docEnd));
|
||||
for (QTextBlock it = doc->begin(); it != doc->end(); it = it.next())
|
||||
{
|
||||
utility::append(m_quotationRanges, formatBlockForRule(it, s_quotationRule, &ranges));
|
||||
}
|
||||
|
||||
highlightMultiLineComments();
|
||||
}
|
||||
|
||||
void QtHighlighter::highlightRange(int startLine, int endLine)
|
||||
{
|
||||
if (startLine < 0 || endLine < 0 || startLine > endLine || endLine > int(m_highlightedLines.size()))
|
||||
{
|
||||
return;
|
||||
@@ -199,22 +198,19 @@ void QtHighlighter::highlightRange(int startLine, int endLine)
|
||||
{
|
||||
if (!m_highlightedLines[index])
|
||||
{
|
||||
applyFormatWithoutRanges(it.position(), it.position() + it.length() - 1, s_textFormat, m_ranges);
|
||||
applyFormat(it.position(), it.position() + it.length() - 1, s_textFormat);
|
||||
|
||||
foreach (const HighlightingRule &rule, m_highlightingRules)
|
||||
if (m_language != LANGUAGE_UNKNOWN)
|
||||
{
|
||||
formatBlock(it, rule, &m_ranges, false);
|
||||
}
|
||||
}
|
||||
index++;
|
||||
}
|
||||
foreach (const HighlightingRule &rule, m_highlightingRules)
|
||||
{
|
||||
formatBlockForRule(it, rule);
|
||||
}
|
||||
|
||||
index = startLine;
|
||||
for (QTextBlock it = start; it != end; it = it.next())
|
||||
{
|
||||
if (!m_highlightedLines[index])
|
||||
{
|
||||
formatBlock(it, s_commentRule, &m_ranges, false);
|
||||
formatBlockIfInRange(it, s_quotationRule.format, &m_quotationRanges);
|
||||
formatBlockForRule(it, s_commentRule, &m_quotationRanges);
|
||||
formatBlockIfInRange(it, s_commentRule.format, &m_multiLineCommentRanges);
|
||||
}
|
||||
}
|
||||
index++;
|
||||
}
|
||||
@@ -244,40 +240,6 @@ void QtHighlighter::applyFormat(int startPosition, int endPosition, const QTextC
|
||||
cursor.setCharFormat(format);
|
||||
}
|
||||
|
||||
void QtHighlighter::applyFormatWithoutRanges(
|
||||
int startPosition, int endPosition, const QTextCharFormat& format, const std::vector<std::pair<int, int>>& ranges
|
||||
){
|
||||
std::vector<std::pair<int, int>> highlightRanges;
|
||||
|
||||
for (const std::pair<int, int> p : ranges)
|
||||
{
|
||||
if (p.first <= startPosition && p.second >= endPosition)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (p.first > startPosition && p.first < endPosition)
|
||||
{
|
||||
highlightRanges.push_back(std::pair<int, int>(startPosition, p.first - 1));
|
||||
}
|
||||
|
||||
if (p.second > startPosition && p.second < endPosition)
|
||||
{
|
||||
highlightRanges.push_back(std::pair<int, int>(p.second + 1, endPosition));
|
||||
}
|
||||
}
|
||||
|
||||
if (!highlightRanges.size())
|
||||
{
|
||||
highlightRanges.push_back(std::pair<int, int>(startPosition, endPosition));
|
||||
}
|
||||
|
||||
for (const std::pair<int, int> p : highlightRanges)
|
||||
{
|
||||
applyFormat(p.first, p.second, format);
|
||||
}
|
||||
}
|
||||
|
||||
QTextCharFormat QtHighlighter::getFormat(int startPosition, int endPosition) const
|
||||
{
|
||||
QTextCursor cursor(document());
|
||||
@@ -285,7 +247,7 @@ QTextCharFormat QtHighlighter::getFormat(int startPosition, int endPosition) con
|
||||
return cursor.charFormat();
|
||||
}
|
||||
|
||||
void QtHighlighter::highlightMultiLineComments(std::vector<std::pair<int, int>>* ranges)
|
||||
void QtHighlighter::highlightMultiLineComments()
|
||||
{
|
||||
QTextDocument* doc = document();
|
||||
|
||||
@@ -305,7 +267,7 @@ void QtHighlighter::highlightMultiLineComments(std::vector<std::pair<int, int>>*
|
||||
cursorStart.setPosition(cursorStart.selectionEnd() - 2);
|
||||
}
|
||||
}
|
||||
while (isInRange(cursorStart.position(), *ranges));
|
||||
while (isInRange(cursorStart.position(), m_quotationRanges));
|
||||
|
||||
if (cursorStart.isNull())
|
||||
{
|
||||
@@ -318,9 +280,7 @@ void QtHighlighter::highlightMultiLineComments(std::vector<std::pair<int, int>>*
|
||||
break;
|
||||
}
|
||||
|
||||
applyFormat(cursorStart.selectionStart(), cursorEnd.position(), s_commentRule.format);
|
||||
ranges->push_back(std::pair<int, int>(cursorStart.selectionStart(), cursorEnd.position()));
|
||||
|
||||
m_multiLineCommentRanges.push_back(std::pair<int, int>(cursorStart.selectionStart(), cursorEnd.position()));
|
||||
cursorStart = cursorEnd;
|
||||
}
|
||||
}
|
||||
@@ -348,34 +308,47 @@ bool QtHighlighter::isInRange(int pos, const std::vector<std::pair<int, int>>& r
|
||||
return false;
|
||||
}
|
||||
|
||||
void QtHighlighter::formatBlock(
|
||||
const QTextBlock& block, const HighlightingRule& rule, std::vector<std::pair<int, int>>* ranges, bool saveRange
|
||||
std::vector<std::pair<int, int>> QtHighlighter::formatBlockForRule(
|
||||
const QTextBlock& block, const HighlightingRule& rule, std::vector<std::pair<int, int>>* ranges
|
||||
){
|
||||
QRegExp expression(rule.pattern);
|
||||
int pos = block.position();
|
||||
int index = expression.indexIn(block.text());
|
||||
|
||||
std::vector<std::pair<int, int>> newRanges;
|
||||
|
||||
while (index >= 0)
|
||||
{
|
||||
int length = expression.matchedLength();
|
||||
|
||||
if (!isInRange(pos + index, *ranges))
|
||||
if (!ranges || !isInRange(pos + index, *ranges))
|
||||
{
|
||||
applyFormat(pos + index, pos + index + length, rule.format);
|
||||
}
|
||||
|
||||
if (saveRange)
|
||||
{
|
||||
newRanges.push_back(std::pair<int, int>(pos + index, pos + index + length - 1));
|
||||
}
|
||||
newRanges.push_back(std::pair<int, int>(pos + index, pos + index + length));
|
||||
|
||||
index = expression.indexIn(block.text(), index + length);
|
||||
}
|
||||
|
||||
if (saveRange)
|
||||
return newRanges;
|
||||
}
|
||||
|
||||
void QtHighlighter::formatBlockIfInRange(
|
||||
const QTextBlock& block, const QTextCharFormat& format, std::vector<std::pair<int, int>>* ranges
|
||||
){
|
||||
int startPos = block.position();
|
||||
int endPos = startPos + block.length() - 1;
|
||||
|
||||
for (auto range : *ranges)
|
||||
{
|
||||
ranges->insert(ranges->end(), newRanges.begin(), newRanges.end());
|
||||
int start = std::max(range.first, startPos);
|
||||
int end = std::min(range.second, endPos);
|
||||
|
||||
if (start <= end)
|
||||
{
|
||||
applyFormat(start, end, format);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,8 +21,6 @@ public:
|
||||
void rehighlightLines(const std::vector<int>& lines);
|
||||
|
||||
void applyFormat(int startPosition, int endPosition, const QTextCharFormat& format);
|
||||
void applyFormatWithoutRanges(
|
||||
int startPosition, int endPosition, const QTextCharFormat& format, const std::vector<std::pair<int, int>>& ranges);
|
||||
|
||||
QTextCharFormat getFormat(int startPosition, int endPosition) const;
|
||||
|
||||
@@ -36,11 +34,13 @@ private:
|
||||
QTextCharFormat format;
|
||||
};
|
||||
|
||||
void highlightMultiLineComments(std::vector<std::pair<int, int>>* ranges);
|
||||
void highlightMultiLineComments();
|
||||
|
||||
bool isInRange(int index, const std::vector<std::pair<int, int>>& ranges) const;
|
||||
void formatBlock(
|
||||
const QTextBlock& block, const HighlightingRule& rule, std::vector<std::pair<int, int>>* ranges, bool saveRange);
|
||||
std::vector<std::pair<int, int>> formatBlockForRule(
|
||||
const QTextBlock& block, const HighlightingRule& rule, std::vector<std::pair<int, int>>* ranges = nullptr);
|
||||
void formatBlockIfInRange(
|
||||
const QTextBlock& block, const QTextCharFormat& format, std::vector<std::pair<int, int>>* ranges);
|
||||
|
||||
QTextDocument* document() const;
|
||||
|
||||
@@ -56,7 +56,8 @@ private:
|
||||
LanguageType m_language;
|
||||
|
||||
QVector<HighlightingRule> m_highlightingRules;
|
||||
std::vector<std::pair<int, int>> m_ranges;
|
||||
std::vector<std::pair<int, int>> m_quotationRanges;
|
||||
std::vector<std::pair<int, int>> m_multiLineCommentRanges;
|
||||
std::vector<bool> m_highlightedLines;
|
||||
};
|
||||
|
||||
|
||||
@@ -45,6 +45,52 @@ void QtCodeView::refreshView()
|
||||
});
|
||||
}
|
||||
|
||||
bool QtCodeView::isVisible() const
|
||||
{
|
||||
return m_widget->isVisible();
|
||||
}
|
||||
|
||||
void QtCodeView::findMatches(ScreenSearchSender* sender, const std::string& query)
|
||||
{
|
||||
m_onQtThread(
|
||||
[sender, query, this]()
|
||||
{
|
||||
size_t matchCount = m_widget->findScreenMatches(query);
|
||||
sender->foundMatches(this, matchCount);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void QtCodeView::activateMatch(size_t matchIndex)
|
||||
{
|
||||
m_onQtThread(
|
||||
[matchIndex, this]()
|
||||
{
|
||||
m_widget->activateScreenMatch(matchIndex);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void QtCodeView::deactivateMatch(size_t matchIndex)
|
||||
{
|
||||
m_onQtThread(
|
||||
[matchIndex, this]()
|
||||
{
|
||||
m_widget->deactivateScreenMatch(matchIndex);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void QtCodeView::clearMatches()
|
||||
{
|
||||
m_onQtThread(
|
||||
[this]()
|
||||
{
|
||||
m_widget->clearScreenMatches();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void QtCodeView::clear()
|
||||
{
|
||||
m_onQtThread([=]()
|
||||
|
||||
@@ -18,6 +18,13 @@ public:
|
||||
virtual void initView();
|
||||
virtual void refreshView();
|
||||
|
||||
// ScreenSearchResponder implementation
|
||||
virtual bool isVisible() const;
|
||||
virtual void findMatches(ScreenSearchSender* sender, const std::string& query);
|
||||
virtual void activateMatch(size_t matchIndex);
|
||||
virtual void deactivateMatch(size_t matchIndex);
|
||||
virtual void clearMatches();
|
||||
|
||||
// CodeView implementation
|
||||
virtual void clear();
|
||||
|
||||
|
||||
@@ -168,6 +168,80 @@ void QtGraphView::refreshView()
|
||||
getView()->refreshStyle();
|
||||
}
|
||||
|
||||
bool QtGraphView::isVisible() const
|
||||
{
|
||||
return QtViewWidgetWrapper::getWidgetOfView(this)->isVisible();
|
||||
}
|
||||
|
||||
void QtGraphView::findMatches(ScreenSearchSender* sender, const std::string& query)
|
||||
{
|
||||
m_onQtThread(
|
||||
[sender, query, this]()
|
||||
{
|
||||
m_matchedNodes.clear();
|
||||
|
||||
for (std::shared_ptr<QtGraphNode> node : m_oldNodes)
|
||||
{
|
||||
node->matchNameRecursive(query, &m_matchedNodes);
|
||||
}
|
||||
|
||||
sender->foundMatches(this, m_matchedNodes.size());
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void QtGraphView::activateMatch(size_t matchIndex)
|
||||
{
|
||||
m_onQtThread(
|
||||
[matchIndex, this]()
|
||||
{
|
||||
if (matchIndex >= m_matchedNodes.size())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QtGraphNode* node = m_matchedNodes[matchIndex];
|
||||
|
||||
node->setActiveMatch(true);
|
||||
node->updateStyle();
|
||||
|
||||
centerNode(node);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void QtGraphView::deactivateMatch(size_t matchIndex)
|
||||
{
|
||||
m_onQtThread(
|
||||
[matchIndex, this]()
|
||||
{
|
||||
if (matchIndex >= m_matchedNodes.size())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QtGraphNode* node = m_matchedNodes[matchIndex];
|
||||
node->setActiveMatch(false);
|
||||
node->updateStyle();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void QtGraphView::clearMatches()
|
||||
{
|
||||
m_onQtThread(
|
||||
[this]()
|
||||
{
|
||||
for (QtGraphNode* node : m_matchedNodes)
|
||||
{
|
||||
node->removeNameMatch();
|
||||
}
|
||||
|
||||
m_matchedNodes.clear();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void QtGraphView::rebuildGraph(
|
||||
std::shared_ptr<Graph> graph,
|
||||
const std::vector<std::shared_ptr<DummyNode>>& nodes,
|
||||
@@ -599,6 +673,8 @@ void QtGraphView::doRebuildGraph(
|
||||
m_graph = graph;
|
||||
}
|
||||
|
||||
m_matchedNodes.clear();
|
||||
|
||||
QGraphicsView* view = getView();
|
||||
|
||||
|
||||
@@ -682,6 +758,8 @@ void QtGraphView::doClear()
|
||||
|
||||
m_graph.reset();
|
||||
m_oldGraph.reset();
|
||||
|
||||
m_matchedNodes.clear();
|
||||
}
|
||||
|
||||
void QtGraphView::doResize()
|
||||
|
||||
@@ -39,6 +39,14 @@ public:
|
||||
virtual void initView();
|
||||
virtual void refreshView();
|
||||
|
||||
// ScreenSearchResponder implementation
|
||||
virtual bool isVisible() const;
|
||||
virtual void findMatches(ScreenSearchSender* sender, const std::string& query);
|
||||
virtual void activateMatch(size_t matchIndex);
|
||||
virtual void deactivateMatch(size_t matchIndex);
|
||||
virtual void clearMatches();
|
||||
|
||||
// GraphView implementation
|
||||
virtual void rebuildGraph(
|
||||
std::shared_ptr<Graph> graph,
|
||||
const std::vector<std::shared_ptr<DummyNode>>& nodes,
|
||||
@@ -164,6 +172,9 @@ private:
|
||||
QLabel* m_trailDepthLabel;
|
||||
|
||||
std::vector<QRectF> m_virtualNodeRects;
|
||||
|
||||
// Name matches
|
||||
std::vector<QtGraphNode*> m_matchedNodes;
|
||||
};
|
||||
|
||||
#endif // QT_GRAPH_VIEW_H
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
#include "qt/view/QtScreenSearchView.h"
|
||||
|
||||
#include <QToolBar>
|
||||
|
||||
#include "component/controller/ScreenSearchController.h"
|
||||
#include "qt/element/QtScreenSearchBox.h"
|
||||
#include "qt/utility/utilityQt.h"
|
||||
#include "qt/view/QtMainView.h"
|
||||
#include "qt/view/QtViewWidgetWrapper.h"
|
||||
#include "qt/window/QtMainWindow.h"
|
||||
#include "utility/ResourcePaths.h"
|
||||
|
||||
QtScreenSearchView::QtScreenSearchView(ViewLayout* viewLayout)
|
||||
: ScreenSearchView(viewLayout)
|
||||
, m_controllerProxy(this)
|
||||
{
|
||||
m_widget = new QtScreenSearchBox(&m_controllerProxy);
|
||||
|
||||
m_bar = new QToolBar();
|
||||
m_bar->setObjectName("screen_search_bar");
|
||||
m_bar->setMovable(false);
|
||||
m_bar->addWidget(m_widget);
|
||||
|
||||
QtMainWindow* mainWindow = dynamic_cast<QtMainView*>(getViewLayout())->getMainWindow();
|
||||
|
||||
QObject::connect(m_widget, &QtScreenSearchBox::closePressed, this, &QtScreenSearchView::hide);
|
||||
QObject::connect(mainWindow, &QtMainWindow::showScreenSearch, this, &QtScreenSearchView::show);
|
||||
QObject::connect(mainWindow, &QtMainWindow::hideScreenSearch, this, &QtScreenSearchView::hide);
|
||||
}
|
||||
|
||||
QtScreenSearchView::~QtScreenSearchView()
|
||||
{
|
||||
}
|
||||
|
||||
void QtScreenSearchView::createWidgetWrapper()
|
||||
{
|
||||
setWidgetWrapper(std::make_shared<QtViewWidgetWrapper>(m_widget));
|
||||
}
|
||||
|
||||
void QtScreenSearchView::initView()
|
||||
{
|
||||
}
|
||||
|
||||
void QtScreenSearchView::refreshView()
|
||||
{
|
||||
m_onQtThread([=]()
|
||||
{
|
||||
m_bar->setStyleSheet(
|
||||
utility::getStyleSheet(ResourcePaths::getGuiPath().concat(
|
||||
FilePath("screen_search_view/screen_search_view.css"))).c_str()
|
||||
);
|
||||
|
||||
m_widget->refreshStyle();
|
||||
});
|
||||
}
|
||||
|
||||
void QtScreenSearchView::setMatchCount(size_t matchCount)
|
||||
{
|
||||
m_onQtThread([=]()
|
||||
{
|
||||
m_widget->setMatchCount(matchCount);
|
||||
});
|
||||
}
|
||||
|
||||
void QtScreenSearchView::setMatchIndex(size_t matchIndex)
|
||||
{
|
||||
m_onQtThread([=]()
|
||||
{
|
||||
m_widget->setMatchIndex(matchIndex);
|
||||
});
|
||||
}
|
||||
|
||||
void QtScreenSearchView::addResponder(const std::string& name)
|
||||
{
|
||||
m_widget->addResponder(name);
|
||||
}
|
||||
|
||||
void QtScreenSearchView::show()
|
||||
{
|
||||
QtMainWindow* mainWindow = dynamic_cast<QtMainView*>(getViewLayout())->getMainWindow();
|
||||
mainWindow->addToolBar(Qt::BottomToolBarArea, m_bar);
|
||||
|
||||
m_bar->show();
|
||||
m_widget->setFocus();
|
||||
}
|
||||
|
||||
void QtScreenSearchView::hide()
|
||||
{
|
||||
m_bar->hide();
|
||||
m_widget->setMatchCount(0);
|
||||
|
||||
m_controllerProxy.executeAsTask<ScreenSearchController>(
|
||||
[](ScreenSearchController* controller)
|
||||
{
|
||||
controller->clearMatches();
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
#ifndef QT_SCREEN_SEARCH_VIEW_H
|
||||
#define QT_SCREEN_SEARCH_VIEW_H
|
||||
|
||||
#include "component/controller/helper/ControllerProxy.h"
|
||||
#include "component/view/ScreenSearchView.h"
|
||||
#include "qt/utility/QtThreadedFunctor.h"
|
||||
|
||||
class QtScreenSearchBox;
|
||||
class QToolBar;
|
||||
|
||||
class QtScreenSearchView
|
||||
: public QObject
|
||||
, public ScreenSearchView
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QtScreenSearchView(ViewLayout* viewLayout);
|
||||
~QtScreenSearchView();
|
||||
|
||||
// View implementation
|
||||
virtual void createWidgetWrapper() override;
|
||||
virtual void initView() override;
|
||||
virtual void refreshView() override;
|
||||
|
||||
// ScreenSearchView implementation
|
||||
virtual void setMatchCount(size_t matchCount) override;
|
||||
virtual void setMatchIndex(size_t matchIndex) override;
|
||||
|
||||
virtual void addResponder(const std::string& name) override;
|
||||
|
||||
public slots:
|
||||
void show();
|
||||
void hide();
|
||||
|
||||
private:
|
||||
ControllerProxy m_controllerProxy;
|
||||
QtThreadedLambdaFunctor m_onQtThread;
|
||||
|
||||
QtScreenSearchBox* m_widget;
|
||||
QToolBar* m_bar;
|
||||
};
|
||||
|
||||
#endif // QT_SCREEN_SEARCH_VIEW_H
|
||||
@@ -5,13 +5,12 @@
|
||||
#include "qt/view/QtMainView.h"
|
||||
#include "qt/view/QtViewWidgetWrapper.h"
|
||||
#include "qt/window/QtMainWindow.h"
|
||||
#include "settings/ColorScheme.h"
|
||||
#include "utility/ResourcePaths.h"
|
||||
|
||||
QtTooltipView::QtTooltipView(ViewLayout* viewLayout)
|
||||
: TooltipView(viewLayout)
|
||||
{
|
||||
m_widget = new QtTooltip(dynamic_cast<QtMainView*>(getViewLayout())->getMainWindow());
|
||||
m_widget = new QtTooltip(dynamic_cast<QtMainView*>(viewLayout)->getMainWindow());
|
||||
}
|
||||
|
||||
QtTooltipView::~QtTooltipView()
|
||||
@@ -31,7 +30,9 @@ void QtTooltipView::refreshView()
|
||||
{
|
||||
m_onQtThread([=]()
|
||||
{
|
||||
setStyleSheet();
|
||||
m_widget->setStyleSheet(
|
||||
utility::getStyleSheet(ResourcePaths::getGuiPath().concat(FilePath("tooltip_view/tooltip_view.css"))).c_str()
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -68,10 +69,3 @@ bool QtTooltipView::tooltipVisible() const
|
||||
{
|
||||
return m_widget->isVisible();
|
||||
}
|
||||
|
||||
void QtTooltipView::setStyleSheet()
|
||||
{
|
||||
m_widget->setStyleSheet(
|
||||
utility::getStyleSheet(ResourcePaths::getGuiPath().concat(FilePath("tooltip_view/tooltip_view.css"))).c_str()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -25,9 +25,6 @@ public:
|
||||
virtual bool tooltipVisible() const;
|
||||
|
||||
private:
|
||||
void setStyleSheet();
|
||||
void doRefreshView();
|
||||
|
||||
QtThreadedLambdaFunctor m_onQtThread;
|
||||
|
||||
QtTooltip* m_widget;
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "qt/view/QtLogView.h"
|
||||
#include "qt/view/QtMainView.h"
|
||||
#include "qt/view/QtRefreshView.h"
|
||||
#include "qt/view/QtScreenSearchView.h"
|
||||
#include "qt/view/QtSearchView.h"
|
||||
#include "qt/view/QtStatusBarView.h"
|
||||
#include "qt/view/QtStatusView.h"
|
||||
@@ -84,6 +85,11 @@ std::shared_ptr<RefreshView> QtViewFactory::createRefreshView(ViewLayout* viewLa
|
||||
return View::createInitAndAddToLayout<QtRefreshView>(viewLayout);
|
||||
}
|
||||
|
||||
std::shared_ptr<ScreenSearchView> QtViewFactory::createScreenSearchView(ViewLayout* viewLayout) const
|
||||
{
|
||||
return View::createAndInit<QtScreenSearchView>(viewLayout);
|
||||
}
|
||||
|
||||
std::shared_ptr<SearchView> QtViewFactory::createSearchView(ViewLayout* viewLayout) const
|
||||
{
|
||||
return View::createInitAndAddToLayout<QtSearchView>(viewLayout);
|
||||
|
||||
@@ -20,6 +20,7 @@ public:
|
||||
virtual std::shared_ptr<GraphView> createGraphView(ViewLayout* viewLayout) const;
|
||||
virtual std::shared_ptr<LogView> createLogView(ViewLayout* viewLayout) const;
|
||||
virtual std::shared_ptr<RefreshView> createRefreshView(ViewLayout* viewLayout) const;
|
||||
virtual std::shared_ptr<ScreenSearchView> createScreenSearchView(ViewLayout* viewLayout) const;
|
||||
virtual std::shared_ptr<SearchView> createSearchView(ViewLayout* viewLayout) const;
|
||||
virtual std::shared_ptr<StatusBarView> createStatusBarView(ViewLayout* viewLayout) const;
|
||||
virtual std::shared_ptr<StatusView> createStatusView(ViewLayout* viewLayout) const;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <QBrush>
|
||||
#include <QFont>
|
||||
#include <QFontMetrics>
|
||||
#include <QGraphicsSceneEvent>
|
||||
#include <QPen>
|
||||
|
||||
@@ -11,6 +12,7 @@
|
||||
#include "qt/view/graphElements/nodeComponents/QtGraphNodeComponent.h"
|
||||
#include "qt/view/graphElements/QtGraphEdge.h"
|
||||
#include "utility/ResourcePaths.h"
|
||||
#include "utility/utilityString.h"
|
||||
|
||||
void QtGraphNode::blendIn()
|
||||
{
|
||||
@@ -40,10 +42,6 @@ QFont QtGraphNode::getFontForNodeType(Node::NodeType type)
|
||||
}
|
||||
|
||||
QtGraphNode::QtGraphNode()
|
||||
: m_icon(nullptr)
|
||||
, m_isActive(false)
|
||||
, m_multipleActive(false)
|
||||
, m_isHovering(false)
|
||||
{
|
||||
this->setPen(QPen(Qt::transparent));
|
||||
|
||||
@@ -244,6 +242,35 @@ void QtGraphNode::focusOut()
|
||||
updateStyle();
|
||||
}
|
||||
|
||||
void QtGraphNode::matchNameRecursive(const std::string& query, std::vector<QtGraphNode*>* matchedNodes)
|
||||
{
|
||||
matchName(query, matchedNodes);
|
||||
|
||||
for (auto subNode : m_subNodes)
|
||||
{
|
||||
subNode->matchNameRecursive(query, matchedNodes);
|
||||
}
|
||||
}
|
||||
|
||||
void QtGraphNode::removeNameMatch()
|
||||
{
|
||||
if (m_matchLength)
|
||||
{
|
||||
m_matchRect->hide();
|
||||
m_matchText->hide();
|
||||
|
||||
m_matchPos = 0;
|
||||
m_matchLength = 0;
|
||||
|
||||
updateStyle();
|
||||
}
|
||||
}
|
||||
|
||||
void QtGraphNode::setActiveMatch(bool active)
|
||||
{
|
||||
m_isActiveMatch = active;
|
||||
}
|
||||
|
||||
bool QtGraphNode::isDataNode() const
|
||||
{
|
||||
return false;
|
||||
@@ -407,6 +434,40 @@ void QtGraphNode::notifyEdgesAfterMove()
|
||||
}
|
||||
}
|
||||
|
||||
void QtGraphNode::matchName(const std::string& query, std::vector<QtGraphNode*>* matchedNodes)
|
||||
{
|
||||
m_isActiveMatch = false;
|
||||
std::string name = getName();
|
||||
size_t pos = utility::toLowerCase(name).find(query);
|
||||
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
if (!m_matchText)
|
||||
{
|
||||
m_matchRect = new QtRoundedRectItem(this);
|
||||
m_matchText = new QGraphicsSimpleTextItem(this);
|
||||
}
|
||||
|
||||
m_matchRect->show();
|
||||
m_matchText->show();
|
||||
|
||||
std::string matchName(name.length(), ' ');
|
||||
matchName.replace(pos, query.length(), name.substr(pos, query.length()));
|
||||
m_matchText->setText(matchName.c_str());
|
||||
|
||||
matchedNodes->push_back(this);
|
||||
|
||||
m_matchPos = pos;
|
||||
m_matchLength = query.length();
|
||||
|
||||
updateStyle();
|
||||
}
|
||||
else if (m_matchLength)
|
||||
{
|
||||
removeNameMatch();
|
||||
}
|
||||
}
|
||||
|
||||
void QtGraphNode::setStyle(const GraphViewStyle::NodeStyle& style)
|
||||
{
|
||||
QPen pen(Qt::transparent);
|
||||
@@ -462,4 +523,25 @@ void QtGraphNode::setStyle(const GraphViewStyle::NodeStyle& style)
|
||||
m_text->setFont(font);
|
||||
m_text->setBrush(QBrush(style.color.text.c_str()));
|
||||
m_text->setPos(style.iconOffset.x + style.iconSize + style.textOffset.x, style.textOffset.y);
|
||||
|
||||
if (m_matchLength)
|
||||
{
|
||||
GraphViewStyle::NodeColor color = GraphViewStyle::getScreenMatchColor(m_isActiveMatch);
|
||||
|
||||
m_matchText->setFont(font);
|
||||
m_matchText->setBrush(QBrush(color.text.c_str()));
|
||||
m_matchText->setPos(style.iconOffset.x + style.iconSize + style.textOffset.x, style.textOffset.y);
|
||||
|
||||
float charWidth = QFontMetrics(font).width("QtGraphNode::QtGraphNode::QtGraphNode") / 37.0f;
|
||||
float charHeight = QFontMetrics(font).height();
|
||||
m_matchRect->setRect(
|
||||
style.iconOffset.x + style.iconSize + style.textOffset.x + m_matchPos * charWidth,
|
||||
style.textOffset.y,
|
||||
m_matchLength * charWidth,
|
||||
charHeight
|
||||
);
|
||||
m_matchRect->setPen(QPen(color.border.c_str()));
|
||||
m_matchRect->setBrush(QBrush(color.fill.c_str()));
|
||||
m_matchRect->setRadius(3);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,6 +74,10 @@ public:
|
||||
void focusIn();
|
||||
void focusOut();
|
||||
|
||||
void matchNameRecursive(const std::string& query, std::vector<QtGraphNode*>* matchedNodes);
|
||||
void removeNameMatch();
|
||||
void setActiveMatch(bool active);
|
||||
|
||||
virtual bool isDataNode() const;
|
||||
virtual bool isAccessNode() const;
|
||||
virtual bool isExpandToggleNode() const;
|
||||
@@ -99,6 +103,8 @@ protected:
|
||||
|
||||
void notifyEdgesAfterMove();
|
||||
|
||||
virtual void matchName(const std::string& query, std::vector<QtGraphNode*>* matchedNodes);
|
||||
|
||||
void setStyle(const GraphViewStyle::NodeStyle& style);
|
||||
|
||||
std::list<std::shared_ptr<QtGraphEdge>> m_outEdges;
|
||||
@@ -107,19 +113,26 @@ protected:
|
||||
std::weak_ptr<QtGraphNode> m_parentNode;
|
||||
std::list<std::shared_ptr<QtGraphNode>> m_subNodes;
|
||||
|
||||
QGraphicsSimpleTextItem* m_text;
|
||||
QtRoundedRectItem* m_rect;
|
||||
QtRoundedRectItem* m_undefinedRect;
|
||||
QGraphicsPixmapItem* m_icon;
|
||||
QGraphicsSimpleTextItem* m_text = nullptr;
|
||||
QtRoundedRectItem* m_rect = nullptr;
|
||||
QtRoundedRectItem* m_undefinedRect = nullptr;
|
||||
QGraphicsPixmapItem* m_icon = nullptr;
|
||||
|
||||
Vec2i m_size;
|
||||
|
||||
bool m_isActive;
|
||||
bool m_multipleActive;
|
||||
bool m_isHovering;
|
||||
bool m_isActive = false;
|
||||
bool m_multipleActive = false;
|
||||
bool m_isHovering = false;
|
||||
|
||||
private:
|
||||
std::list<std::shared_ptr<QtGraphNodeComponent>> m_components;
|
||||
|
||||
// Name match
|
||||
QGraphicsSimpleTextItem* m_matchText = nullptr;
|
||||
QtRoundedRectItem* m_matchRect = nullptr;
|
||||
size_t m_matchPos = 0;
|
||||
size_t m_matchLength = 0;
|
||||
bool m_isActiveMatch = false;
|
||||
};
|
||||
|
||||
#endif // QT_GRAPH_NODE_H
|
||||
|
||||
@@ -23,6 +23,9 @@ public:
|
||||
|
||||
void hideLabel();
|
||||
|
||||
protected:
|
||||
virtual void matchName(const std::string& query, std::vector<QtGraphNode*>* matchedNodes) {}
|
||||
|
||||
private:
|
||||
AccessKind m_accessKind;
|
||||
|
||||
|
||||
@@ -19,6 +19,9 @@ public:
|
||||
virtual void onClick();
|
||||
virtual void updateStyle();
|
||||
|
||||
protected:
|
||||
virtual void matchName(const std::string& query, std::vector<QtGraphNode*>* matchedNodes) {}
|
||||
|
||||
private:
|
||||
QGraphicsPixmapItem* m_icon;
|
||||
bool m_invisibleSubNodeCount;
|
||||
|
||||
@@ -26,6 +26,8 @@ protected:
|
||||
virtual void hoverEnterEvent(QGraphicsSceneHoverEvent* event);
|
||||
virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent* event);
|
||||
|
||||
virtual void matchName(const std::string& query, std::vector<QtGraphNode*>* matchedNodes) {}
|
||||
|
||||
private:
|
||||
const NameHierarchy m_qualifierName;
|
||||
|
||||
|
||||
@@ -357,6 +357,7 @@ void QtMainWindow::keyPressEvent(QKeyEvent* event)
|
||||
|
||||
case Qt::Key_Escape:
|
||||
MessageInterruptTasks().dispatch();
|
||||
emit hideScreenSearch();
|
||||
break;
|
||||
|
||||
case Qt::Key_Space:
|
||||
@@ -565,6 +566,11 @@ void QtMainWindow::findFulltext()
|
||||
MessageFind(true).dispatch();
|
||||
}
|
||||
|
||||
void QtMainWindow::findInView()
|
||||
{
|
||||
emit showScreenSearch();
|
||||
}
|
||||
|
||||
void QtMainWindow::codeReferencePrevious()
|
||||
{
|
||||
MessageCodeReference(MessageCodeReference::REFERENCE_PREVIOUS).dispatch();
|
||||
@@ -771,6 +777,7 @@ void QtMainWindow::setupEditMenu()
|
||||
|
||||
menu->addAction(tr("&Find Symbol"), this, &QtMainWindow::find, QKeySequence::Find);
|
||||
menu->addAction(tr("&Find Text"), this, &QtMainWindow::findFulltext, QKeySequence(Qt::SHIFT + Qt::CTRL + Qt::Key_F));
|
||||
menu->addAction(tr("&Find in View"), this, &QtMainWindow::findInView, QKeySequence(Qt::CTRL + Qt::Key_D));
|
||||
|
||||
menu->addSeparator();
|
||||
|
||||
@@ -858,7 +865,7 @@ void QtMainWindow::setupBookmarksMenu()
|
||||
m_bookmarksMenu->clear();
|
||||
}
|
||||
|
||||
m_bookmarksMenu->addAction(tr("Bookmark Active Symbol..."), this, &QtMainWindow::showBookmarkCreator, QKeySequence(Qt::CTRL + Qt::Key_D));
|
||||
m_bookmarksMenu->addAction(tr("Bookmark Active Symbol..."), this, &QtMainWindow::showBookmarkCreator, QKeySequence::Save);
|
||||
m_bookmarksMenu->addAction(tr("Bookmark Manager"), this, &QtMainWindow::showBookmarkBrowser, QKeySequence(Qt::CTRL + Qt::Key_B));
|
||||
|
||||
m_bookmarksMenu->addSeparator();
|
||||
|
||||
@@ -78,6 +78,10 @@ public:
|
||||
|
||||
void setContentEnabled(bool enabled);
|
||||
|
||||
signals:
|
||||
void showScreenSearch();
|
||||
void hideScreenSearch();
|
||||
|
||||
protected:
|
||||
void keyPressEvent(QKeyEvent* event);
|
||||
void contextMenuEvent(QContextMenuEvent* event);
|
||||
@@ -109,6 +113,7 @@ public slots:
|
||||
|
||||
void find();
|
||||
void findFulltext();
|
||||
void findInView();
|
||||
void codeReferencePrevious();
|
||||
void codeReferenceNext();
|
||||
void overview();
|
||||
|
||||
Reference in New Issue
Block a user