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:
@@ -620,6 +620,7 @@ void QtCodeArea::mousePressEvent(QMouseEvent* event)
|
||||
void QtCodeArea::mouseReleaseEvent(QMouseEvent* event)
|
||||
{
|
||||
const int panningThreshold = 5;
|
||||
|
||||
if (event->button() == Qt::LeftButton)
|
||||
{
|
||||
m_isSelecting = false;
|
||||
@@ -636,9 +637,7 @@ void QtCodeArea::mouseReleaseEvent(QMouseEvent* event)
|
||||
}
|
||||
else
|
||||
{
|
||||
QTextCursor cursor = this->cursorForPosition(event->pos());
|
||||
std::vector<const Annotation*> annotations = getInteractiveAnnotationsForPosition(cursor.position());
|
||||
|
||||
std::vector<const Annotation*> annotations = getInteractiveAnnotationsForPosition(event->pos());
|
||||
if (annotations.size())
|
||||
{
|
||||
if (m_navigator->hasErrors())
|
||||
@@ -657,6 +656,10 @@ void QtCodeArea::mouseReleaseEvent(QMouseEvent* event)
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
QtCodeField::mouseReleaseEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
void QtCodeArea::mouseMoveEvent(QMouseEvent* event)
|
||||
@@ -681,8 +684,7 @@ void QtCodeArea::mouseMoveEvent(QMouseEvent* event)
|
||||
scrollbar->setValue(scrollbar->value() - utility::roundToInt(deltaPosRatio * scrollbar->pageStep()));
|
||||
}
|
||||
|
||||
QTextCursor cursor = this->cursorForPosition(event->pos());
|
||||
std::vector<const Annotation*> annotations = getInteractiveAnnotationsForPosition(cursor.position());
|
||||
std::vector<const Annotation*> annotations = getInteractiveAnnotationsForPosition(event->pos());
|
||||
|
||||
bool same = annotations.size() == m_hoveredAnnotations.size();
|
||||
if (same)
|
||||
@@ -730,9 +732,12 @@ void QtCodeArea::contextMenuEvent(QContextMenuEvent* event)
|
||||
{
|
||||
m_eventPosition = event->pos();
|
||||
|
||||
checkOpenInTabActionEnabled(event->pos());
|
||||
m_setIDECursorPositionAction->setEnabled(!getSourceLocationFile()->getFilePath().empty());
|
||||
|
||||
QtContextMenu menu(event, this);
|
||||
menu.addAction(m_openInTabAction);
|
||||
menu.addUndoActions();
|
||||
menu.addSeparator();
|
||||
menu.addFileActions(getSourceLocationFile()->getFilePath());
|
||||
menu.addSeparator();
|
||||
|
||||
@@ -1,17 +1,20 @@
|
||||
#include "QtCodeField.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QPainter>
|
||||
#include <QTextBlock>
|
||||
#include <QTextCodec>
|
||||
|
||||
#include "SourceLocation.h"
|
||||
#include "SourceLocationFile.h"
|
||||
#include "QtContextMenu.h"
|
||||
#include "QtHighlighter.h"
|
||||
#include "ApplicationSettings.h"
|
||||
#include "ColorScheme.h"
|
||||
#include "MessageActivateLocalSymbols.h"
|
||||
#include "MessageActivateSourceLocations.h"
|
||||
#include "MessageActivateTokenIds.h"
|
||||
#include "MessageTabOpenWith.h"
|
||||
#include "MessageTooltipShow.h"
|
||||
#include "TextCodec.h"
|
||||
#include "tracing.h"
|
||||
@@ -99,6 +102,12 @@ QtCodeField::QtCodeField(
|
||||
font.setPixelSize(appSettings->getFontSize());
|
||||
setFont(font);
|
||||
setTabStopWidth(appSettings->getCodeTabWidth() * fontMetrics().width('9'));
|
||||
|
||||
m_openInTabAction = new QAction("Open in New Tab", this);
|
||||
m_openInTabAction->setStatusTip("Opens the node in a new tab");
|
||||
m_openInTabAction->setToolTip("Opens the node in a new tab");
|
||||
m_openInTabAction->setEnabled(false);
|
||||
connect(m_openInTabAction, &QAction::triggered, this, &QtCodeField::openInTab);
|
||||
}
|
||||
|
||||
QtCodeField::~QtCodeField()
|
||||
@@ -251,8 +260,7 @@ void QtCodeField::leaveEvent(QEvent* event)
|
||||
|
||||
void QtCodeField::mouseMoveEvent(QMouseEvent* event)
|
||||
{
|
||||
QTextCursor cursor = this->cursorForPosition(event->pos());
|
||||
std::vector<const Annotation*> annotations = getInteractiveAnnotationsForPosition(cursor.position());
|
||||
std::vector<const Annotation*> annotations = getInteractiveAnnotationsForPosition(event->pos());
|
||||
|
||||
bool same = annotations.size() == m_hoveredAnnotations.size();
|
||||
if (same)
|
||||
@@ -275,6 +283,13 @@ void QtCodeField::mouseMoveEvent(QMouseEvent* event)
|
||||
|
||||
void QtCodeField::mouseReleaseEvent(QMouseEvent* event)
|
||||
{
|
||||
if (event->button() == Qt::MiddleButton)
|
||||
{
|
||||
checkOpenInTabActionEnabled(event->pos());
|
||||
openInTab();
|
||||
return;
|
||||
}
|
||||
|
||||
if (event->button() != Qt::LeftButton)
|
||||
{
|
||||
return;
|
||||
@@ -282,9 +297,7 @@ void QtCodeField::mouseReleaseEvent(QMouseEvent* event)
|
||||
|
||||
viewport()->setCursor(Qt::ArrowCursor);
|
||||
|
||||
QTextCursor cursor = this->cursorForPosition(event->pos());
|
||||
std::vector<const Annotation*> annotations = getInteractiveAnnotationsForPosition(cursor.position());
|
||||
|
||||
std::vector<const Annotation*> annotations = getInteractiveAnnotationsForPosition(event->pos());
|
||||
if (!annotations.size())
|
||||
{
|
||||
return;
|
||||
@@ -293,6 +306,16 @@ void QtCodeField::mouseReleaseEvent(QMouseEvent* event)
|
||||
activateAnnotations(annotations);
|
||||
}
|
||||
|
||||
void QtCodeField::contextMenuEvent(QContextMenuEvent* event)
|
||||
{
|
||||
checkOpenInTabActionEnabled(event->pos());
|
||||
|
||||
QtContextMenu menu(event, nullptr);
|
||||
menu.addAction(m_openInTabAction);
|
||||
menu.addUndoActions();
|
||||
menu.show();
|
||||
}
|
||||
|
||||
void QtCodeField::focusTokenIds(const std::vector<Id>& focusedTokenIds)
|
||||
{
|
||||
annotateText(std::set<Id>(), std::set<Id>(), std::set<Id>(focusedTokenIds.begin(), focusedTokenIds.end()));
|
||||
@@ -639,10 +662,13 @@ void QtCodeField::setTextColorForAnnotation(const Annotation& annotation, QColor
|
||||
m_highlighter->applyFormat(annotation.start, annotation.end, format);
|
||||
}
|
||||
|
||||
std::vector<const QtCodeField::Annotation*> QtCodeField::getInteractiveAnnotationsForPosition(int pos) const
|
||||
std::vector<const QtCodeField::Annotation*> QtCodeField::getInteractiveAnnotationsForPosition(QPoint position) const
|
||||
{
|
||||
std::vector<const QtCodeField::Annotation*> annotations;
|
||||
|
||||
QTextCursor cursor = this->cursorForPosition(position);
|
||||
int pos = cursor.position();
|
||||
|
||||
for (const Annotation& annotation : m_annotations)
|
||||
{
|
||||
const LocationType& type = annotation.locationType;
|
||||
@@ -656,6 +682,38 @@ std::vector<const QtCodeField::Annotation*> QtCodeField::getInteractiveAnnotatio
|
||||
return annotations;
|
||||
}
|
||||
|
||||
void QtCodeField::checkOpenInTabActionEnabled(QPoint position)
|
||||
{
|
||||
std::vector<Id> locationIds;
|
||||
for (const Annotation* annotation : getInteractiveAnnotationsForPosition(position))
|
||||
{
|
||||
const LocationType& type = annotation->locationType;
|
||||
if (type == LOCATION_TOKEN || type == LOCATION_QUALIFIER)
|
||||
{
|
||||
locationIds.emplace_back(annotation->locationId);
|
||||
}
|
||||
}
|
||||
|
||||
if (locationIds.size())
|
||||
{
|
||||
m_openInTabLocationId = locationIds[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
m_openInTabLocationId = 0;
|
||||
}
|
||||
|
||||
m_openInTabAction->setEnabled(m_openInTabLocationId);
|
||||
}
|
||||
|
||||
void QtCodeField::openInTab()
|
||||
{
|
||||
if (m_openInTabLocationId)
|
||||
{
|
||||
MessageTabOpenWith(0, m_openInTabLocationId).dispatch();
|
||||
}
|
||||
}
|
||||
|
||||
void QtCodeField::createLineLengthCache()
|
||||
{
|
||||
m_endTextEditPosition = -1;
|
||||
|
||||
@@ -51,6 +51,8 @@ protected:
|
||||
virtual void mouseMoveEvent(QMouseEvent* event) Q_DECL_OVERRIDE;
|
||||
virtual void mouseReleaseEvent(QMouseEvent* event) Q_DECL_OVERRIDE;
|
||||
|
||||
virtual void contextMenuEvent(QContextMenuEvent* event) Q_DECL_OVERRIDE;
|
||||
|
||||
virtual void focusTokenIds(const std::vector<Id>& tokenIds);
|
||||
virtual void defocusTokenIds(const std::vector<Id>& tokenIds);
|
||||
|
||||
@@ -99,12 +101,20 @@ protected:
|
||||
const AnnotationColor& getAnnotationColorForAnnotation(const Annotation& annotation);
|
||||
void setTextColorForAnnotation(const Annotation& annotation, QColor color) const;
|
||||
|
||||
std::vector<const Annotation*> getInteractiveAnnotationsForPosition(int pos) const;
|
||||
std::vector<const Annotation*> getInteractiveAnnotationsForPosition(QPoint position) const;
|
||||
std::vector<Id> getInteractiveTokenIdsForPosition(QPoint position) const;
|
||||
|
||||
void checkOpenInTabActionEnabled(QPoint position);
|
||||
|
||||
std::vector<Annotation> m_annotations;
|
||||
std::vector<const Annotation*> m_hoveredAnnotations;
|
||||
std::vector<int> m_linesToRehighlight;
|
||||
|
||||
QAction* m_openInTabAction;
|
||||
|
||||
private slots:
|
||||
void openInTab();
|
||||
|
||||
private:
|
||||
static std::vector<AnnotationColor> s_annotationColors;
|
||||
|
||||
@@ -123,6 +133,8 @@ private:
|
||||
std::vector<std::vector<std::pair<int, int>>> m_multibyteCharacterLocations;
|
||||
|
||||
int m_endTextEditPosition;
|
||||
|
||||
Id m_openInTabLocationId;
|
||||
};
|
||||
|
||||
#endif // QT_CODE_FIELD_H
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
#include "QtCodeFileTitleButton.h"
|
||||
|
||||
#include <QMouseEvent>
|
||||
|
||||
#include "FileSystem.h"
|
||||
#include "MessageActivateFile.h"
|
||||
#include "MessageProjectEdit.h"
|
||||
#include "MessageTabOpenWith.h"
|
||||
#include "ResourcePaths.h"
|
||||
#include "utilityString.h"
|
||||
|
||||
@@ -25,6 +28,12 @@ QtCodeFileTitleButton::QtCodeFileTitleButton(QWidget* parent)
|
||||
setIconSize(QSize(16, 16));
|
||||
|
||||
connect(this, &QtCodeFileTitleButton::clicked, this, &QtCodeFileTitleButton::clickedTitle);
|
||||
|
||||
m_openInTabAction = new QAction("Open in New Tab", this);
|
||||
m_openInTabAction->setStatusTip("Opens the file in a new tab");
|
||||
m_openInTabAction->setToolTip("Opens the file in a new tab");
|
||||
m_openInTabAction->setEnabled(false);
|
||||
connect(m_openInTabAction, &QAction::triggered, this, &QtCodeFileTitleButton::openInTab);
|
||||
}
|
||||
|
||||
QtCodeFileTitleButton::~QtCodeFileTitleButton()
|
||||
@@ -147,6 +156,17 @@ void QtCodeFileTitleButton::updateFromOther(const QtCodeFileTitleButton* other)
|
||||
updateTexts();
|
||||
}
|
||||
|
||||
void QtCodeFileTitleButton::mouseReleaseEvent(QMouseEvent* event)
|
||||
{
|
||||
if (event->button() == Qt::MiddleButton)
|
||||
{
|
||||
openInTab();
|
||||
return;
|
||||
}
|
||||
|
||||
QtSelfRefreshIconButton::mouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
void QtCodeFileTitleButton::contextMenuEvent(QContextMenuEvent* event)
|
||||
{
|
||||
FilePath path = m_filePath;
|
||||
@@ -161,7 +181,11 @@ void QtCodeFileTitleButton::contextMenuEvent(QContextMenuEvent* event)
|
||||
path = currentProject->getProjectSettingsFilePath();
|
||||
}
|
||||
|
||||
m_openInTabAction->setEnabled(!m_filePath.empty());
|
||||
|
||||
QtContextMenu menu(event, this);
|
||||
menu.addAction(m_openInTabAction);
|
||||
menu.addUndoActions();
|
||||
menu.addSeparator();
|
||||
menu.addFileActions(path);
|
||||
menu.show();
|
||||
@@ -186,6 +210,14 @@ void QtCodeFileTitleButton::clickedTitle()
|
||||
}
|
||||
}
|
||||
|
||||
void QtCodeFileTitleButton::openInTab()
|
||||
{
|
||||
if (!m_filePath.empty())
|
||||
{
|
||||
MessageTabOpenWith(m_filePath).dispatch();
|
||||
}
|
||||
}
|
||||
|
||||
void QtCodeFileTitleButton::updateIcon()
|
||||
{
|
||||
if (m_filePath.empty())
|
||||
|
||||
@@ -31,12 +31,14 @@ public:
|
||||
void updateFromOther(const QtCodeFileTitleButton* other);
|
||||
|
||||
protected:
|
||||
void mouseReleaseEvent(QMouseEvent* event);
|
||||
void contextMenuEvent(QContextMenuEvent* event);
|
||||
|
||||
virtual void refresh();
|
||||
|
||||
private slots:
|
||||
void clickedTitle();
|
||||
void openInTab();
|
||||
|
||||
private:
|
||||
void updateIcon();
|
||||
@@ -46,6 +48,8 @@ private:
|
||||
TimeStamp m_modificationTime;
|
||||
bool m_isComplete;
|
||||
bool m_isIndexed;
|
||||
|
||||
QAction* m_openInTabAction;
|
||||
};
|
||||
|
||||
#endif // QT_CODE_FILE_TITLE_BUTTON_H
|
||||
|
||||
@@ -64,7 +64,7 @@ void QtCodeNavigateable::ensureWidgetVisibleAnimated(
|
||||
QScrollBar* scrollBar = area->verticalScrollBar();
|
||||
if (scrollBar && value)
|
||||
{
|
||||
if (animated && ApplicationSettings::getInstance()->getUseAnimations())
|
||||
if (animated && ApplicationSettings::getInstance()->getUseAnimations() && area->isVisible())
|
||||
{
|
||||
QPropertyAnimation* anim = new QPropertyAnimation(scrollBar, "value");
|
||||
anim->setDuration(300);
|
||||
@@ -136,7 +136,7 @@ void QtCodeNavigateable::ensurePercentVisibleAnimated(double percentA, double pe
|
||||
int diff = value - scrollBar->value();
|
||||
if (diff > 5 || diff < -5)
|
||||
{
|
||||
if (animated && ApplicationSettings::getInstance()->getUseAnimations())
|
||||
if (animated && ApplicationSettings::getInstance()->getUseAnimations() && area->isVisible())
|
||||
{
|
||||
QPropertyAnimation* anim = new QPropertyAnimation(scrollBar, "value");
|
||||
anim->setDuration(300);
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "MessageShowError.h"
|
||||
#include "MessageScrollCode.h"
|
||||
#include "ResourcePaths.h"
|
||||
#include "TabId.h"
|
||||
#include "utility.h"
|
||||
|
||||
#include "SourceLocation.h"
|
||||
@@ -26,6 +27,7 @@ QtCodeNavigator::QtCodeNavigator(QWidget* parent)
|
||||
: QWidget(parent)
|
||||
, m_mode(MODE_NONE)
|
||||
, m_oldMode(MODE_NONE)
|
||||
, m_schedulerId(TabId::ignore())
|
||||
, m_activeTokenId(0)
|
||||
, m_value(0)
|
||||
, m_refIndex(0)
|
||||
@@ -338,6 +340,16 @@ void QtCodeNavigator::setMode(Mode mode)
|
||||
}
|
||||
}
|
||||
|
||||
Id QtCodeNavigator::getSchedulerId() const
|
||||
{
|
||||
return m_schedulerId;
|
||||
}
|
||||
|
||||
void QtCodeNavigator::setSchedulerId(Id schedulerId)
|
||||
{
|
||||
m_schedulerId = schedulerId;
|
||||
}
|
||||
|
||||
const std::set<Id>& QtCodeNavigator::getCurrentActiveTokenIds() const
|
||||
{
|
||||
return m_currentActiveTokenIds;
|
||||
@@ -708,6 +720,11 @@ void QtCodeNavigator::deactivateScreenMatch(size_t matchIndex)
|
||||
m_activeScreenMatchId = 0;
|
||||
}
|
||||
|
||||
bool QtCodeNavigator::hasScreenMatches() const
|
||||
{
|
||||
return !m_screenMatches.empty();
|
||||
}
|
||||
|
||||
void QtCodeNavigator::clearScreenMatches()
|
||||
{
|
||||
if (m_activeScreenMatchId)
|
||||
@@ -847,7 +864,7 @@ void QtCodeNavigator::requestScroll(
|
||||
void QtCodeNavigator::handleScrollRequest()
|
||||
{
|
||||
const ScrollRequest& req = m_scrollRequest;
|
||||
if (req.filePath.empty())
|
||||
if (req.filePath.empty() || !isVisible())
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -871,6 +888,11 @@ void QtCodeNavigator::scrolled(int value)
|
||||
MessageScrollCode(value, m_mode == MODE_LIST).dispatch();
|
||||
}
|
||||
|
||||
void QtCodeNavigator::showEvent(QShowEvent* event)
|
||||
{
|
||||
emit scrollRequest();
|
||||
}
|
||||
|
||||
void QtCodeNavigator::setValue()
|
||||
{
|
||||
QAbstractScrollArea* area = m_current->getScrollArea();
|
||||
|
||||
@@ -56,6 +56,9 @@ public:
|
||||
|
||||
void setMode(Mode mode);
|
||||
|
||||
Id getSchedulerId() const override;
|
||||
void setSchedulerId(Id schedulerId);
|
||||
|
||||
const std::set<Id>& getCurrentActiveTokenIds() const;
|
||||
void setCurrentActiveTokenIds(const std::vector<Id>& currentActiveTokenIds);
|
||||
|
||||
@@ -101,6 +104,7 @@ public:
|
||||
size_t findScreenMatches(const std::wstring& query);
|
||||
void activateScreenMatch(size_t matchIndex);
|
||||
void deactivateScreenMatch(size_t matchIndex);
|
||||
bool hasScreenMatches() const;
|
||||
void clearScreenMatches();
|
||||
|
||||
void scrollToValue(int value, bool inListMode);
|
||||
@@ -118,6 +122,9 @@ signals:
|
||||
public slots:
|
||||
void scrolled(int value);
|
||||
|
||||
protected:
|
||||
void showEvent(QShowEvent* event) override;
|
||||
|
||||
private slots:
|
||||
void handleScrollRequest();
|
||||
void setValue();
|
||||
@@ -172,11 +179,11 @@ private:
|
||||
QtCodeNavigateable::ScrollTarget target;
|
||||
};
|
||||
|
||||
void handleMessage(MessageCodeReference* message);
|
||||
void handleMessage(MessageIndexingFinished* message);
|
||||
void handleMessage(MessageShowReference* message);
|
||||
void handleMessage(MessageSwitchColorScheme* message);
|
||||
void handleMessage(MessageWindowFocus* message);
|
||||
void handleMessage(MessageCodeReference* message) override;
|
||||
void handleMessage(MessageIndexingFinished* message) override;
|
||||
void handleMessage(MessageShowReference* message) override;
|
||||
void handleMessage(MessageSwitchColorScheme* message) override;
|
||||
void handleMessage(MessageWindowFocus* message) override;
|
||||
|
||||
QtThreadedLambdaFunctor m_onQtThread;
|
||||
|
||||
@@ -187,6 +194,8 @@ private:
|
||||
Mode m_mode;
|
||||
Mode m_oldMode;
|
||||
|
||||
Id m_schedulerId;
|
||||
|
||||
std::set<Id> m_currentActiveTokenIds;
|
||||
std::set<Id> m_currentActiveLocationIds;
|
||||
std::set<Id> m_currentActiveLocalLocationIds;
|
||||
|
||||
@@ -2,9 +2,11 @@
|
||||
|
||||
#include <QBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QMouseEvent>
|
||||
#include <QScrollBar>
|
||||
|
||||
#include "MessageHistoryToPosition.h"
|
||||
#include "MessageTabOpenWith.h"
|
||||
#include "ResourcePaths.h"
|
||||
#include "utilityString.h"
|
||||
|
||||
@@ -12,11 +14,11 @@
|
||||
#include "utilityQt.h"
|
||||
|
||||
#include "GraphViewStyle.h"
|
||||
#include "SearchMatch.h"
|
||||
#include "ColorScheme.h"
|
||||
|
||||
QtHistoryItem::QtHistoryItem(const SearchMatch& match, size_t index, bool isCurrent)
|
||||
: index(index)
|
||||
, m_match(match)
|
||||
{
|
||||
QBoxLayout* layout = new QHBoxLayout();
|
||||
layout->setSpacing(0);
|
||||
@@ -74,6 +76,11 @@ QSize QtHistoryItem::getSizeHint() const
|
||||
return QSize(m_name->fontMetrics().width(m_name->text()) + 40, m_name->fontMetrics().height() + 8);
|
||||
}
|
||||
|
||||
const SearchMatch& QtHistoryItem::getMatch() const
|
||||
{
|
||||
return m_match;
|
||||
}
|
||||
|
||||
void QtHistoryItem::enterEvent(QEvent *event)
|
||||
{
|
||||
QWidget::enterEvent(event);
|
||||
@@ -111,13 +118,36 @@ void QtHistoryItem::leaveEvent(QEvent *event)
|
||||
}
|
||||
|
||||
|
||||
|
||||
QtHistoryListWidget::QtHistoryListWidget(QWidget* parent)
|
||||
: QListWidget(parent)
|
||||
{
|
||||
}
|
||||
|
||||
void QtHistoryListWidget::mouseReleaseEvent(QMouseEvent* event)
|
||||
{
|
||||
if (event->button() == Qt::MiddleButton)
|
||||
{
|
||||
QtHistoryItem* item = dynamic_cast<QtHistoryItem*>(itemWidget(itemAt(event->pos())));
|
||||
if (item)
|
||||
{
|
||||
MessageTabOpenWith(item->getMatch()).dispatch();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
QListWidget::mouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
|
||||
|
||||
QtHistoryList::QtHistoryList(const std::vector<SearchMatch>& history, size_t currentIndex)
|
||||
: m_currentIndex(currentIndex)
|
||||
{
|
||||
setWindowFlags(Qt::Popup);
|
||||
setObjectName("history");
|
||||
|
||||
m_list = new QListWidget(this);
|
||||
m_list = new QtHistoryListWidget(this);
|
||||
m_list->setObjectName("history_list");
|
||||
m_list->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
|
||||
m_list->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
@@ -141,8 +171,8 @@ void QtHistoryList::showPopup(QPoint pos)
|
||||
QSize size(50, 2);
|
||||
for (int i = 0; i < m_list->count(); i++)
|
||||
{
|
||||
QtHistoryItem* it = dynamic_cast<QtHistoryItem*>(m_list->itemWidget(m_list->item(i)));
|
||||
QSize itemSize = it->getSizeHint();
|
||||
QtHistoryItem* item = dynamic_cast<QtHistoryItem*>(m_list->itemWidget(m_list->item(i)));
|
||||
QSize itemSize = item->getSizeHint();
|
||||
if (itemSize.width() > size.width())
|
||||
{
|
||||
size.setWidth(itemSize.width());
|
||||
|
||||
@@ -3,8 +3,9 @@
|
||||
|
||||
#include <QListWidget>
|
||||
|
||||
#include "SearchMatch.h"
|
||||
|
||||
class QLabel;
|
||||
struct SearchMatch;
|
||||
|
||||
class QtHistoryItem
|
||||
: public QWidget
|
||||
@@ -16,6 +17,8 @@ public:
|
||||
|
||||
QSize getSizeHint() const;
|
||||
|
||||
const SearchMatch& getMatch() const;
|
||||
|
||||
size_t index;
|
||||
|
||||
protected:
|
||||
@@ -29,6 +32,19 @@ private:
|
||||
QWidget* m_indicator;
|
||||
std::string m_indicatorColor;
|
||||
std::string m_indicatorHoverColor;
|
||||
|
||||
const SearchMatch m_match;
|
||||
};
|
||||
|
||||
|
||||
class QtHistoryListWidget
|
||||
: public QListWidget
|
||||
{
|
||||
public:
|
||||
QtHistoryListWidget(QWidget* parent = nullptr);
|
||||
|
||||
protected:
|
||||
void mouseReleaseEvent(QMouseEvent* event);
|
||||
};
|
||||
|
||||
|
||||
@@ -52,7 +68,7 @@ private slots:
|
||||
void onItemClicked(QListWidgetItem *item);
|
||||
|
||||
private:
|
||||
QListWidget* m_list;
|
||||
QtHistoryListWidget* m_list;
|
||||
size_t m_currentIndex;
|
||||
};
|
||||
|
||||
|
||||
@@ -141,10 +141,15 @@ void QtScreenSearchBox::setMatchIndex(size_t matchIndex)
|
||||
|
||||
void QtScreenSearchBox::addResponder(const std::string& name)
|
||||
{
|
||||
if (m_checkBoxes.find(name) != m_checkBoxes.end())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QCheckBox* box = new QCheckBox(name.c_str());
|
||||
box->setObjectName("filter_checkbox");
|
||||
box->setChecked(true);
|
||||
m_checkBoxes.push_back(box);
|
||||
m_checkBoxes.emplace(name, box);
|
||||
m_checkboxLayout->addWidget(box);
|
||||
|
||||
connect(box, &QCheckBox::stateChanged, this, &QtScreenSearchBox::findMatches);
|
||||
@@ -173,11 +178,11 @@ void QtScreenSearchBox::findMatches()
|
||||
[this](ScreenSearchController* controller)
|
||||
{
|
||||
std::set<std::string> responderNames;
|
||||
for (QCheckBox* box : m_checkBoxes)
|
||||
for (auto p : m_checkBoxes)
|
||||
{
|
||||
if (box->isChecked())
|
||||
if (p.second->isChecked())
|
||||
{
|
||||
responderNames.insert(box->text().toStdString());
|
||||
responderNames.insert(p.first);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ private:
|
||||
QtSelfRefreshIconButton* m_closeButton;
|
||||
|
||||
QHBoxLayout* m_checkboxLayout;
|
||||
std::vector<QCheckBox*> m_checkBoxes;
|
||||
std::map<std::string, QCheckBox*> m_checkBoxes;
|
||||
|
||||
size_t m_matchCount = 0;
|
||||
size_t m_matchIndex = 0;
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
#include "QtTabBar.h"
|
||||
|
||||
QtTabBar::QtTabBar(QWidget* parent)
|
||||
: QTabBar(parent)
|
||||
{
|
||||
setFocusPolicy(Qt::NoFocus);
|
||||
}
|
||||
|
||||
QSize QtTabBar::minimumSizeHint() const
|
||||
{
|
||||
return QSize(0, QTabBar::minimumSizeHint().height());
|
||||
}
|
||||
|
||||
QSize QtTabBar::tabSizeHint(int index) const
|
||||
{
|
||||
return QSize(300, QTabBar::tabSizeHint(index).height());
|
||||
}
|
||||
|
||||
QSize QtTabBar::minimumTabSizeHint(int index) const
|
||||
{
|
||||
return QSize(45, QTabBar::minimumTabSizeHint(index).height());
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#ifndef QT_TAB_BAR_H
|
||||
#define QT_TAB_BAR_H
|
||||
|
||||
#include <QTabBar>
|
||||
|
||||
class QtTabBar
|
||||
: public QTabBar
|
||||
{
|
||||
public:
|
||||
QtTabBar(QWidget* parent = nullptr);
|
||||
|
||||
protected:
|
||||
QSize minimumSizeHint() const override;
|
||||
|
||||
QSize tabSizeHint(int index) const override;
|
||||
QSize minimumTabSizeHint(int index) const override;
|
||||
};
|
||||
|
||||
#endif // QT_TAB_BAR_H
|
||||
Reference in New Issue
Block a user