ui: switch to single file mode with snippet maximize

* switch back to snippet view with snippet button in file title bar
* use new title bar widget in single view as well
* restore view mode on undo, store current view mode for every message id (added id to message)
* treat view mode switch as adapt message on undo stack
* fixed crash after snippet expansion
* fixed hatching in file title not shown
This commit is contained in:
Eberhard Graether
2017-12-20 20:40:38 +01:00
parent 8672d14319
commit bfa43df491
31 changed files with 462 additions and 323 deletions
+1
View File
@@ -454,6 +454,7 @@ add_files(
utility/messaging/type/MessageZoom.h
utility/messaging/Message.h
utility/messaging/MessageBase.cpp
utility/messaging/MessageBase.h
utility/messaging/MessageFilter.h
utility/messaging/MessageInterruptTasksCounter.cpp
@@ -61,6 +61,7 @@ void ActivationController::handleMessage(MessageActivateFile* message)
MessageChangeFileView msg(
message->filePath,
MessageChangeFileView::FILE_MAXIMIZED,
MessageChangeFileView::VIEW_CURRENT,
true,
true
);
+32 -13
View File
@@ -31,6 +31,7 @@ void CodeController::handleMessage(MessageActivateAll* message)
{
TRACE("code all");
saveOrRestoreViewMode(message);
clear();
Project* currentProject = Application::getInstance()->getCurrentProject().get();
@@ -107,6 +108,8 @@ void CodeController::handleMessage(MessageActivateTokens* message)
{
TRACE("code activate");
saveOrRestoreViewMode(message);
CodeView* view = getView();
CodeView::CodeParams params;
@@ -180,6 +183,8 @@ void CodeController::handleMessage(MessageActivateTrailEdge* message)
{
TRACE("trail edge activate");
saveOrRestoreViewMode(message);
CodeView::ScrollParams scrollParams(CodeView::ScrollParams::SCROLL_TO_DEFINITION);
getView()->scrollTo(scrollParams);
@@ -197,14 +202,6 @@ void CodeController::handleMessage(MessageChangeFileView* message)
{
TRACE("code change file");
if (!m_collection)
{
return;
}
CodeView* view = getView();
bool inListMode = view->isInListMode();
CodeView::FileState state;
switch (message->state)
{
@@ -219,13 +216,15 @@ void CodeController::handleMessage(MessageChangeFileView* message)
case MessageChangeFileView::FILE_MAXIMIZED:
state = CodeView::FILE_MAXIMIZED;
break;
case MessageChangeFileView::FILE_DEFAULT_FOR_MODE:
state = inListMode ? CodeView::FILE_SNIPPETS : CodeView::FILE_MAXIMIZED;
break;
}
if (message->needsData)
CodeView* view = getView();
if (message->viewMode != MessageChangeFileView::VIEW_CURRENT)
{
view->setMode(message->viewMode == MessageChangeFileView::VIEW_LIST);
}
if (message->needsData && !message->filePath.empty())
{
CodeView::CodeParams params;
view->showCodeSnippets(getSnippetsForFileWithState(message->filePath, state, !message->showErrors), params);
@@ -302,6 +301,8 @@ void CodeController::handleMessage(MessageShowErrors* message)
{
TRACE("code errors");
saveOrRestoreViewMode(message);
CodeView* view = getView();
if (!view->showsErrors() || !message->errorId)
{
@@ -337,6 +338,8 @@ void CodeController::handleMessage(MessageSearchFullText* message)
{
TRACE("code fulltext");
saveOrRestoreViewMode(message);
m_collection = m_storageAccess->getFullTextSearchLocations(message->searchTerm, message->caseSensitive);
CodeView::ScrollParams scrollParams(CodeView::ScrollParams::SCROLL_TO_DEFINITION);
@@ -892,3 +895,19 @@ void CodeController::addActiveSourceLocations(std::shared_ptr<SourceLocationFile
);
}
}
void CodeController::saveOrRestoreViewMode(MessageBase* message)
{
if (message->isReplayed())
{
auto it = m_messageIdToViewModeMap.find(message->getId());
if (it != m_messageIdToViewModeMap.end())
{
getView()->setMode(it->second);
}
}
else
{
m_messageIdToViewModeMap.emplace(message->getId(), getView()->isInListMode());
}
}
@@ -100,8 +100,12 @@ private:
void addModificationTimes(std::vector<CodeSnippetParams>& snippets) const;
void addActiveSourceLocations(std::shared_ptr<SourceLocationFile> locationFile) const;
void saveOrRestoreViewMode(MessageBase* message);
StorageAccess* m_storageAccess;
mutable std::shared_ptr<SourceLocationCollection> m_collection;
std::map<Id, bool> m_messageIdToViewModeMap;
};
#endif // CODE_CONTROLLER_H
@@ -108,7 +108,8 @@ void UndoRedoController::handleMessage(MessageActivateTrailEdge* message)
void UndoRedoController::handleMessage(MessageChangeFileView* message)
{
Command command(std::make_shared<MessageChangeFileView>(*message), Command::ORDER_VIEW);
Command command(std::make_shared<MessageChangeFileView>(*message),
message->switchesViewMode ? Command::ORDER_ADAPT : Command::ORDER_VIEW);
processCommand(command);
}
+2
View File
@@ -94,6 +94,8 @@ public:
virtual void showContents() = 0;
virtual bool isInListMode() const = 0;
virtual void setMode(bool listMode) = 0;
virtual bool hasSingleFileCached(const FilePath& filePath) const = 0;
private:
@@ -0,0 +1,3 @@
#include "utility/messaging/MessageBase.h"
Id MessageBase::s_nextId = 1;
+13 -1
View File
@@ -4,11 +4,14 @@
#include <ostream>
#include <sstream>
#include "utility/types.h"
class MessageBase
{
public:
MessageBase()
: m_isParallel(false)
: m_id(s_nextId++)
, m_isParallel(false)
, m_isReplayed(false)
, m_sendAsTask(true)
, m_keepContent(false)
@@ -24,6 +27,11 @@ public:
virtual std::string getType() const = 0;
virtual void dispatch() = 0;
Id getId() const
{
return m_id;
}
bool sendAsTask() const
{
return m_sendAsTask;
@@ -95,6 +103,10 @@ public:
}
private:
static size_t s_nextId;
Id m_id;
bool m_isParallel;
bool m_isReplayed;
@@ -1,3 +1,3 @@
#include "utility/messaging/MessageListenerBase.h"
uint MessageListenerBase::s_nextId = 0;
Id MessageListenerBase::s_nextId = 1;
@@ -26,7 +26,7 @@ public:
}
}
uint getId() const
Id getId() const
{
return m_id;
}
@@ -57,9 +57,9 @@ private:
virtual std::string doGetType() const = 0;
virtual void doHandleMessageBase(MessageBase*) = 0;
static uint s_nextId;
static Id s_nextId;
uint m_id;
Id m_id;
bool m_alive;
};
+3 -3
View File
@@ -64,12 +64,12 @@ void MessageQueue::unregisterListener(MessageListenerBase* listener)
LOG_ERROR("Listener was not found");
}
MessageListenerBase* MessageQueue::getListenerById(const uint id) const
MessageListenerBase* MessageQueue::getListenerById(Id listenerId) const
{
std::lock_guard<std::mutex> lock(m_listenersMutex);
for (size_t i = 0; i < m_listeners.size(); i++)
{
if (m_listeners[i]->getId() == id)
if (m_listeners[i]->getId() == listenerId)
{
return m_listeners[i];
}
@@ -284,7 +284,7 @@ void MessageQueue::sendMessageAsTask(std::shared_ptr<MessageBase> message, bool
if (listener->getType() == message->getType())
{
uint listenerId = listener->getId();
Id listenerId = listener->getId();
taskGroup->addTask(std::make_shared<TaskLambda>(
[listenerId, message]()
{
+1 -1
View File
@@ -24,7 +24,7 @@ public:
void registerListener(MessageListenerBase* listener);
void unregisterListener(MessageListenerBase* listener);
MessageListenerBase* getListenerById(const uint id) const;
MessageListenerBase* getListenerById(Id listenerId) const;
void addMessageFilter(std::shared_ptr<MessageFilter> filter);
@@ -12,20 +12,30 @@ public:
{
FILE_MINIMIZED,
FILE_SNIPPETS,
FILE_MAXIMIZED,
FILE_DEFAULT_FOR_MODE
FILE_MAXIMIZED
};
enum ViewMode
{
VIEW_LIST,
VIEW_SINGLE,
VIEW_CURRENT
};
MessageChangeFileView(
const FilePath& filePath,
FileState state,
ViewMode viewMode,
bool needsData,
bool showErrors
bool showErrors,
bool switchesViewMode = false
)
: filePath(filePath)
, state(state)
, viewMode(viewMode)
, needsData(needsData)
, showErrors(showErrors)
, switchesViewMode(switchesViewMode)
{
}
@@ -41,7 +51,13 @@ public:
case FILE_MINIMIZED: os << "minimize"; break;
case FILE_SNIPPETS: os << "snippets"; break;
case FILE_MAXIMIZED: os << "maximize"; break;
case FILE_DEFAULT_FOR_MODE: os << "default"; break;
}
switch (viewMode)
{
case VIEW_LIST: os << ", list"; break;
case VIEW_SINGLE: os << ", single"; break;
case VIEW_CURRENT: os << ", current"; break;
}
if (needsData)
@@ -50,11 +66,12 @@ public:
}
}
FilePath filePath;
FileState state;
bool needsData;
bool showErrors;
const FilePath filePath;
const FileState state;
const ViewMode viewMode;
const bool needsData;
const bool showErrors;
const bool switchesViewMode;
};
#endif // MESSAGE_CHANGE_FILE_VIEW_H
+13 -1
View File
@@ -347,7 +347,7 @@ Id QtCodeArea::getLocationIdOfFirstActiveScopeLocation(Id tokenId) const
return 0;
}
uint QtCodeArea::getActiveLocationCount() const
size_t QtCodeArea::getActiveLocationCount() const
{
uint count = 0;
@@ -359,6 +359,18 @@ uint QtCodeArea::getActiveLocationCount() const
}
}
if (!count)
{
for (const Annotation& annotation : m_annotations)
{
if (annotation.locationType == LocationType::LOCATION_FULLTEXT_SEARCH ||
annotation.locationType == LocationType::LOCATION_ERROR)
{
count++;
}
}
}
return count;
}
+1 -1
View File
@@ -79,7 +79,7 @@ public:
Id getLocationIdOfFirstActiveLocation(Id tokenId) const;
Id getLocationIdOfFirstActiveScopeLocation(Id tokenId) const;
uint getActiveLocationCount() const;
size_t getActiveLocationCount() const;
QRectF getLineRectForLineNumber(uint lineNumber) const;
+56 -62
View File
@@ -100,7 +100,7 @@ QtCodeSnippet* QtCodeFile::addCodeSnippet(const CodeSnippetParams& params)
m_fileSnippet->setIsActiveFile(true);
}
setMaximized();
setSnippets();
if (params.refCount != -1)
{
updateRefCount(0);
@@ -140,6 +140,7 @@ QtCodeSnippet* QtCodeFile::insertCodeSnippet(const CodeSnippetParams& params)
}
else if (s->getStartLineNumber() < start || s->getEndLineNumber() > end)
{
m_navigator->clearSnippetReferences();
snippet = QtCodeSnippet::merged(snippet.get(), s.get(), m_navigator, this);
}
@@ -256,7 +257,25 @@ void QtCodeFile::requestContent()
bool needsData = (state == MessageChangeFileView::FILE_MAXIMIZED) ? (getFileSnippet() == nullptr) : (m_snippets.size() == 0);
MessageChangeFileView(m_filePath, state, needsData, m_navigator->hasErrors()).dispatch();
MessageChangeFileView(m_filePath, state, MessageChangeFileView::VIEW_LIST, needsData, m_navigator->hasErrors()).dispatch();
}
void QtCodeFile::requestWholeFileContent()
{
if (!getFileSnippet())
{
MessageChangeFileView(
m_filePath,
MessageChangeFileView::FILE_MAXIMIZED,
MessageChangeFileView::VIEW_LIST,
true,
m_navigator->hasErrors()
).dispatch();
}
else
{
setSnippets();
}
}
void QtCodeFile::updateContent()
@@ -299,21 +318,28 @@ void QtCodeFile::setMinimized()
m_fileSnippet->hide();
}
m_titleBar->setMinimized(!m_isWholeFile);
m_titleBar->setMinimized();
setStyleSheet("#code_file { padding-bottom: 0; } #code_file #title_widget { border-radius: 7px; }");
setStyleSheet("#code_file { padding-bottom: 0; } #code_file #title_bar { border-radius: 7px; }");
}
void QtCodeFile::setSnippets()
{
for (const std::shared_ptr<QtCodeSnippet>& snippet : m_snippets)
{
snippet->show();
}
if (m_fileSnippet)
{
m_fileSnippet->hide();
m_fileSnippet->show();
for (const std::shared_ptr<QtCodeSnippet>& snippet : m_snippets)
{
snippet->hide();
}
}
else
{
for (const std::shared_ptr<QtCodeSnippet>& snippet : m_snippets)
{
snippet->show();
}
}
m_titleBar->setSnippets();
@@ -323,19 +349,7 @@ void QtCodeFile::setSnippets()
void QtCodeFile::setMaximized()
{
for (const std::shared_ptr<QtCodeSnippet>& snippet : m_snippets)
{
snippet->hide();
}
if (m_fileSnippet)
{
m_fileSnippet->show();
}
m_titleBar->setMaximized(!m_isWholeFile);
setStyleSheet("");
setSnippets();
}
bool QtCodeFile::hasSnippets() const
@@ -396,18 +410,12 @@ void QtCodeFile::findScreenMatches(const std::string& query, std::vector<std::pa
void QtCodeFile::clickedMinimizeButton()
{
// overview stats
if (m_filePath.empty())
{
setMinimized();
return;
}
m_navigator->requestScroll(m_filePath, 0, 0, false, QtCodeNavigateable::SCROLL_VISIBLE);
MessageChangeFileView(
m_filePath,
MessageChangeFileView::FILE_MINIMIZED,
MessageChangeFileView::VIEW_LIST,
false,
m_navigator->hasErrors()
).dispatch();
@@ -420,55 +428,41 @@ void QtCodeFile::clickedSnippetButton()
MessageChangeFileView(
m_filePath,
MessageChangeFileView::FILE_SNIPPETS,
!m_snippets.size(),
MessageChangeFileView::VIEW_LIST,
isCollapsed(),
m_navigator->hasErrors()
).dispatch();
}
void QtCodeFile::clickedMaximizeButton()
{
// overview stats
if (m_filePath.empty())
uint firstLineNumber = 1;
std::vector<QtCodeSnippet*> snippets = getVisibleSnippets();
if (snippets.size())
{
setMaximized();
return;
firstLineNumber = snippets[0]->getStartLineNumber();
}
m_navigator->requestScroll(m_filePath, 0, 0, false, QtCodeNavigateable::SCROLL_VISIBLE);
m_navigator->requestScroll(m_filePath, firstLineNumber, 0, false, QtCodeNavigateable::SCROLL_CENTER);
MessageChangeFileView(
m_filePath,
MessageChangeFileView::FILE_MAXIMIZED,
!getFileSnippet(),
m_navigator->hasErrors()
MessageChangeFileView::VIEW_SINGLE,
true, // TODO: check if data is really needed
m_navigator->hasErrors(),
true
).dispatch();
}
void QtCodeFile::updateRefCount(int refCount)
{
if (refCount > 0 && !m_isWholeFile)
if (m_isWholeFile)
{
bool hasErrors = m_navigator->hasErrors();
QString label = hasErrors ? "error" : "reference";
if (refCount > 1)
{
label += "s";
}
if (hasErrors)
{
size_t fatalErrorCount = m_navigator->getFatalErrorCountForFile(m_filePath);
if (fatalErrorCount > 0)
{
label += " (" + QString::number(fatalErrorCount) + " fatal)";
}
}
m_titleBar->setRefString(QString::number(refCount) + " " + label);
}
else
{
m_titleBar->setRefString("");
refCount = 0;
}
bool hasErrors = m_navigator->hasErrors();
size_t fatalErrorCount = hasErrors ? m_navigator->getFatalErrorCountForFile(m_filePath) : 0;
m_titleBar->updateRefCount(refCount, hasErrors, fatalErrorCount);
}
+1
View File
@@ -47,6 +47,7 @@ public:
bool isCollapsed() const;
void requestContent();
void requestWholeFileContent();
void updateContent();
void setWholeFile(bool isWholeFile, int refCount);
+48 -6
View File
@@ -72,6 +72,11 @@ void QtCodeFileList::clear()
m_files.clear();
m_scrollArea->verticalScrollBar()->setValue(0);
clearSnippetTitleAndScrollBar();
}
void QtCodeFileList::clearSnippetTitleAndScrollBar()
{
updateFirstSnippetTitleBar(nullptr);
updateLastSnippetScrollBar(nullptr);
}
@@ -221,6 +226,7 @@ void QtCodeFileList::showContents()
{
for (QtCodeFile* file : m_files)
{
file->updateTitleBar();
file->show();
}
}
@@ -248,17 +254,55 @@ void QtCodeFileList::findScreenMatches(const std::string& query, std::vector<std
void QtCodeFileList::setFileMinimized(const FilePath path)
{
getFile(path)->setMinimized();
if (path.empty())
{
if (m_files.size())
{
m_files[0]->setMinimized();
}
}
else
{
getFile(path)->setMinimized();
}
}
void QtCodeFileList::setFileSnippets(const FilePath path)
{
getFile(path)->setSnippets();
if (path.empty())
{
if (m_files.size())
{
m_files[0]->setSnippets();
}
}
else
{
getFile(path)->setSnippets();
}
}
void QtCodeFileList::setFileMaximized(const FilePath path)
{
getFile(path)->setMaximized();
if (path.empty())
{
if (m_files.size())
{
m_files[0]->setMaximized();
}
}
else
{
getFile(path)->setMaximized();
}
}
void QtCodeFileList::maximizeFirstFile()
{
if (m_files.size())
{
m_files[0]->clickedMaximizeButton();
}
}
std::pair<QtCodeSnippet*, Id> QtCodeFileList::getFirstSnippetWithActiveLocationId(Id tokenId) const
@@ -284,9 +328,7 @@ std::pair<QtCodeSnippet*, Id> QtCodeFileList::getFirstSnippetWithActiveLocationI
void QtCodeFileList::resizeEvent(QResizeEvent* event)
{
updateFirstSnippetTitleBar(nullptr);
updateLastSnippetScrollBar(nullptr);
clearSnippetTitleAndScrollBar();
updateSnippetTitleAndScrollBar();
}
+3
View File
@@ -26,6 +26,7 @@ public:
virtual ~QtCodeFileList();
void clear();
void clearSnippetTitleAndScrollBar();
QtCodeFile* getFile(const FilePath filePath);
void addFile(const FilePath& filePath, bool isWholeFile, int refCount, TimeStamp modificationTime, bool isComplete);
@@ -49,6 +50,8 @@ public:
void setFileSnippets(const FilePath path);
void setFileMaximized(const FilePath path);
void maximizeFirstFile();
std::pair<QtCodeSnippet*, Id> getFirstSnippetWithActiveLocationId(Id tokenId) const;
protected:
+37 -62
View File
@@ -12,6 +12,7 @@
#include "data/location/SourceLocationFile.h"
#include "qt/element/QtCodeArea.h"
#include "qt/element/QtCodeFileTitleBar.h"
#include "qt/element/QtCodeFileTitleButton.h"
#include "qt/element/QtCodeNavigator.h"
#include "qt/utility/utilityQt.h"
@@ -28,35 +29,11 @@ QtCodeFileSingle::QtCodeFileSingle(QtCodeNavigator* navigator, QWidget* parent)
layout()->setContentsMargins(0, 0, 0, 0);
layout()->setSpacing(0);
{
QWidget* titleBar = new QWidget();
titleBar->setObjectName("single_file_title_bar");
m_titleBar = new QtCodeFileTitleBar(this, false, true);
m_titleBar->setObjectName("title_bar_single");
layout()->addWidget(m_titleBar);
QHBoxLayout* titleLayout = new QHBoxLayout();
titleLayout->setSpacing(0);
titleLayout->setMargin(0);
m_title = new QtCodeFileTitleButton();
m_title->setObjectName("file_title");
titleLayout->addWidget(m_title);
m_title->hide();
m_referenceCount = new QLabel();
m_referenceCount->setObjectName("references_label");
m_referenceCount->hide();
titleLayout->addWidget(m_referenceCount);
QPushButton* filler = new QPushButton();
filler->setObjectName("file_title");
filler->setEnabled(false);
titleLayout->addWidget(filler);
titleLayout->addStretch();
titleBar->setLayout(titleLayout);
layout()->addWidget(titleBar);
}
connect(m_titleBar, &QtCodeFileTitleBar::snippet, this, &QtCodeFileSingle::clickedSnippetButton);
m_areaWrapper = new QWidget();
m_areaWrapper->setObjectName("code_file_single");
@@ -160,7 +137,8 @@ void QtCodeFileSingle::requestFileContent(const FilePath& filePath)
MessageChangeFileView(
filePath,
MessageChangeFileView::FILE_DEFAULT_FOR_MODE,
MessageChangeFileView::FILE_MAXIMIZED,
MessageChangeFileView::VIEW_SINGLE,
true,
m_navigator->hasErrors()
).dispatch();
@@ -228,12 +206,13 @@ void QtCodeFileSingle::showContents()
if (m_area)
{
m_area->show();
updateRefCount(m_area->getActiveLocationCount());
}
}
void QtCodeFileSingle::onWindowFocus()
{
m_title->updateTexts();
m_titleBar->getTitleButton()->updateTexts();
}
void QtCodeFileSingle::findScreenMatches(const std::string& query, std::vector<std::pair<QtCodeArea*, Id>>* screenMatches)
@@ -270,6 +249,20 @@ Id QtCodeFileSingle::getLocationIdOfFirstActiveLocationOfTokenId(Id tokenId) con
return m_area->getLocationIdOfFirstActiveLocation(tokenId);
}
void QtCodeFileSingle::clickedSnippetButton()
{
m_navigator->requestScroll(m_currentFilePath, 0, 0, false, QtCodeNavigateable::SCROLL_TOP);
MessageChangeFileView(
m_currentFilePath,
MessageChangeFileView::FILE_SNIPPETS,
MessageChangeFileView::VIEW_LIST,
true, // TODO: check if data is really needed
m_navigator->hasErrors(),
true
).dispatch();
}
QtCodeFileSingle::FileData QtCodeFileSingle::getFileData(const FilePath& filePath) const
{
std::map<FilePath, FileData>::const_iterator it = m_fileDatas.find(filePath);
@@ -285,11 +278,6 @@ void QtCodeFileSingle::setFileData(const FileData& file)
{
if (file.area == m_area)
{
if (m_area)
{
updateRefCount(m_area->getActiveLocationCount());
m_area->updateContent();
}
return;
}
@@ -302,6 +290,7 @@ void QtCodeFileSingle::setFileData(const FileData& file)
m_areaWrapper->layout()->takeAt(0);
QtCodeFileTitleButton* titleButton = m_titleBar->getTitleButton();
if (file.area)
{
m_area = file.area;
@@ -310,54 +299,40 @@ void QtCodeFileSingle::setFileData(const FileData& file)
m_area->updateContent();
m_currentFilePath = file.filePath;
m_titleBar->setMaximized();
if (file.title.size())
{
m_title->setProject(file.title);
m_title->setIsComplete(true);
titleButton->setProject(file.title);
titleButton->setIsComplete(true);
}
else
{
m_title->setFilePath(file.filePath);
m_title->setModificationTime(file.modificationTime);
m_title->setIsComplete(file.isComplete);
titleButton->setFilePath(file.filePath);
titleButton->setModificationTime(file.modificationTime);
titleButton->setIsComplete(file.isComplete);
}
updateRefCount(m_area->getActiveLocationCount());
m_title->show();
titleButton->updateTexts();
titleButton->show();
m_area->show();
m_scrollRequested = false;
}
else
{
m_title->hide();
titleButton->hide();
updateRefCount(0);
m_titleBar->setSnippets();
}
}
void QtCodeFileSingle::updateRefCount(int refCount)
{
if (refCount > 0)
{
QString label = m_navigator->hasErrors() ? "error" : "reference";
if (refCount > 1)
{
label += "s";
}
bool hasErrors = m_navigator->hasErrors();
size_t fatalErrorCount = hasErrors ? m_navigator->getFatalErrorCountForFile(m_currentFilePath) : 0;
size_t fatalErrorCount = m_navigator->getFatalErrorCountForFile(m_currentFilePath);
if (fatalErrorCount > 0)
{
label += " (" + QString::number(fatalErrorCount) + " fatal)";
}
m_referenceCount->setText(QString::number(refCount) + " " + label);
m_referenceCount->show();
}
else
{
m_referenceCount->hide();
}
m_titleBar->updateRefCount(refCount, hasErrors, fatalErrorCount);
}
+5 -3
View File
@@ -14,7 +14,7 @@
class QLabel;
class QPushButton;
class QtCodeArea;
class QtCodeFileTitleButton;
class QtCodeFileTitleBar;
class QtCodeNavigator;
class QtCodeFileSingle
@@ -52,6 +52,9 @@ public:
Id getLocationIdOfFirstActiveLocationOfTokenId(Id tokenId) const;
public slots:
void clickedSnippetButton();
private:
struct FileData
{
@@ -73,8 +76,7 @@ private:
QWidget* m_areaWrapper;
FilePath m_currentFilePath;
QtCodeFileTitleButton* m_title;
QLabel* m_referenceCount;
QtCodeFileTitleBar* m_titleBar;
QtCodeArea* m_area;
std::map<FilePath, FileData> m_fileDatas;
+69 -41
View File
@@ -6,13 +6,20 @@
#include "utility/ResourcePaths.h"
QtCodeFileTitleBar::QtCodeFileTitleBar(QWidget* parent, bool isHovering)
QtCodeFileTitleBar::QtCodeFileTitleBar(QWidget* parent, bool isHovering, bool isSingle)
: QtHoverButton(parent)
{
setObjectName("title_widget");
setObjectName("title_bar");
setProperty("hovering", isHovering);
setAttribute(Qt::WA_LayoutUsesWidgetRect); // fixes layouting on Mac
if (!isSingle)
{
connect(this, &QPushButton::clicked, this, &QtCodeFileTitleBar::clickedTitleBar);
connect(this, &QtHoverButton::hoveredIn, this, &QtCodeFileTitleBar::enteredTitleBar);
connect(this, &QtHoverButton::hoveredOut, this, &QtCodeFileTitleBar::leftTitleBar);
}
QHBoxLayout* titleLayout = new QHBoxLayout();
titleLayout->setMargin(0);
titleLayout->setSpacing(0);
@@ -20,7 +27,11 @@ QtCodeFileTitleBar::QtCodeFileTitleBar(QWidget* parent, bool isHovering)
setLayout(titleLayout);
m_titleButton = new QtCodeFileTitleButton(this);
QSizePolicy policy = m_titleButton->sizePolicy();
policy.setRetainSizeWhenHidden(true);
m_titleButton->setSizePolicy(policy);
titleLayout->addWidget(m_titleButton);
setMinimumHeight(m_titleButton->height() + 4);
m_referenceCount = new QLabel(this);
@@ -31,58 +42,51 @@ QtCodeFileTitleBar::QtCodeFileTitleBar(QWidget* parent, bool isHovering)
titleLayout->addStretch(3);
std::string imageDir = ResourcePaths::getGuiPath().str() + "code_view/images/";
QColor inactiveColor(0x5E, 0x5D, 0x5D);
m_minimizeButton = new QtIconStateButton(this);
m_minimizeButton->addState(QtIconStateButton::STATE_DEFAULT, (imageDir + "minimize_active.png").c_str());
// m_minimizeButton->addState(QtIconStateButton::STATE_HOVERED, (imageDir + "minimize_inactive.png").c_str(), "#5E5D5D");
m_minimizeButton->addState(QtIconStateButton::STATE_HOVERED, (imageDir + "minimize_inactive.png").c_str(), QColor(0x5E, 0x5D, 0x5D));
m_minimizeButton->addState(QtIconStateButton::STATE_HOVERED, (imageDir + "minimize_inactive.png").c_str(), inactiveColor);
m_minimizeButton->addState(QtIconStateButton::STATE_DISABLED, (imageDir + "minimize_inactive.png").c_str());
m_minimizeButton->setIconSize(QSize(16, 16));
m_minimizeButton->setObjectName("file_button");
m_minimizeButton->setToolTip("minimize");
titleLayout->addWidget(m_minimizeButton);
m_snippetButton = new QtIconStateButton(this);
m_snippetButton->addState(QtIconStateButton::STATE_DEFAULT, (imageDir + "snippet_active.png").c_str());
// m_snippetButton->addState(QtIconStateButton::STATE_HOVERED, (imageDir + "snippet_inactive.png").c_str(), "#5E5D5D");
m_snippetButton->addState(QtIconStateButton::STATE_HOVERED, (imageDir + "snippet_inactive.png").c_str(), QColor(0x5E, 0x5D, 0x5D));
m_snippetButton->addState(QtIconStateButton::STATE_HOVERED, (imageDir + "snippet_inactive.png").c_str(), inactiveColor);
m_snippetButton->addState(QtIconStateButton::STATE_DISABLED, (imageDir + "snippet_inactive.png").c_str());
m_snippetButton->setIconSize(QSize(16, 16));
m_snippetButton->setObjectName("file_button");
m_snippetButton->setToolTip("show snippets");
titleLayout->addWidget(m_snippetButton);
m_maximizeButton = new QtIconStateButton(this);
m_maximizeButton->addState(QtIconStateButton::STATE_DEFAULT, (imageDir + "maximize_active.png").c_str());
// m_maximizeButton->addState(QtIconStateButton::STATE_HOVERED, (imageDir + "maximize_inactive.png").c_str(), "#5E5D5D");
m_maximizeButton->addState(QtIconStateButton::STATE_HOVERED, (imageDir + "maximize_inactive.png").c_str(), QColor(0x5E, 0x5D, 0x5D));
m_maximizeButton->addState(QtIconStateButton::STATE_HOVERED, (imageDir + "maximize_inactive.png").c_str(), inactiveColor);
m_maximizeButton->addState(QtIconStateButton::STATE_DISABLED, (imageDir + "maximize_inactive.png").c_str());
m_maximizeButton->setIconSize(QSize(16, 16));
m_maximizeButton->setObjectName("file_button");
m_maximizeButton->setToolTip("maximize");
titleLayout->addWidget(m_maximizeButton);
titleLayout->addSpacing(3);
for (QtIconStateButton* button : { m_minimizeButton, m_snippetButton, m_maximizeButton })
{
button->setIconSize(QSize(16, 16));
button->setObjectName("file_button");
button->setEnabled(false);
titleLayout->addWidget(button);
connect(this, &QPushButton::clicked, this, &QtCodeFileTitleBar::clickedTitleBar);
connect(this, &QtHoverButton::hoveredIn, this, &QtCodeFileTitleBar::enteredTitleBar);
connect(this, &QtHoverButton::hoveredOut, this, &QtCodeFileTitleBar::leftTitleBar);
if (!isSingle)
{
connect(button, &QtIconStateButton::hoveredIn, this, &QtCodeFileTitleBar::leftTitleBar);
connect(button, &QtIconStateButton::hoveredOut, this, &QtCodeFileTitleBar::enteredTitleBar);
}
}
connect(m_minimizeButton, &QtIconStateButton::hoveredIn, this, &QtCodeFileTitleBar::leftTitleBar);
connect(m_minimizeButton, &QtIconStateButton::hoveredOut, this, &QtCodeFileTitleBar::enteredTitleBar);
connect(m_minimizeButton, &QtIconStateButton::clicked, this, &QtCodeFileTitleBar::clickedMinimizeButton);
connect(m_snippetButton, &QtIconStateButton::hoveredIn, this, &QtCodeFileTitleBar::leftTitleBar);
connect(m_snippetButton, &QtIconStateButton::hoveredOut, this, &QtCodeFileTitleBar::enteredTitleBar);
connect(m_snippetButton, &QtIconStateButton::clicked, this, &QtCodeFileTitleBar::clickedSnippetButton);
connect(m_maximizeButton, &QtIconStateButton::hoveredIn, this, &QtCodeFileTitleBar::leftTitleBar);
connect(m_maximizeButton, &QtIconStateButton::hoveredOut, this, &QtCodeFileTitleBar::enteredTitleBar);
connect(m_maximizeButton, &QtIconStateButton::clicked, this, &QtCodeFileTitleBar::clickedMaximizeButton);
m_minimizeButton->setEnabled(false);
m_snippetButton->setEnabled(false);
m_maximizeButton->setEnabled(false);
if (isSingle)
{
m_minimizeButton->hide();
m_maximizeButton->hide();
}
titleLayout->addSpacing(3);
}
QtCodeFileTitleButton* QtCodeFileTitleBar::getTitleButton() const
@@ -90,11 +94,26 @@ QtCodeFileTitleButton* QtCodeFileTitleBar::getTitleButton() const
return m_titleButton;
}
void QtCodeFileTitleBar::setRefString(const QString& refString)
void QtCodeFileTitleBar::updateRefCount(int refCount, bool hasErrors, size_t fatalErrorCount)
{
if (refString.size())
if (refCount > 0)
{
m_referenceCount->setText(refString);
QString label = hasErrors ? "error" : "reference";
if (refCount > 1)
{
label += "s";
}
if (fatalErrorCount > 0)
{
label += " (" + QString::number(fatalErrorCount) + " fatal)";
}
QString text = QString::number(refCount) + " " + label;
if (text != m_referenceCount->text())
{
m_referenceCount->setText(text);
}
m_referenceCount->show();
}
else
@@ -103,10 +122,10 @@ void QtCodeFileTitleBar::setRefString(const QString& refString)
}
}
void QtCodeFileTitleBar::setMinimized(bool hasSnippets)
void QtCodeFileTitleBar::setMinimized()
{
m_minimizeButton->setEnabled(false);
m_snippetButton->setEnabled(hasSnippets);
m_snippetButton->setEnabled(true);
m_maximizeButton->setEnabled(true);
m_minimizeButton->hoverOut();
@@ -125,10 +144,10 @@ void QtCodeFileTitleBar::setSnippets()
m_maximizeButton->hoverOut();
}
void QtCodeFileTitleBar::setMaximized(bool hasSnippets)
void QtCodeFileTitleBar::setMaximized()
{
m_minimizeButton->setEnabled(true);
m_snippetButton->setEnabled(hasSnippets);
m_minimizeButton->setEnabled(false);
m_snippetButton->setEnabled(true);
m_maximizeButton->setEnabled(false);
m_minimizeButton->hoverOut();
@@ -140,7 +159,16 @@ void QtCodeFileTitleBar::updateFromOther(const QtCodeFileTitleBar* other)
{
m_titleButton->updateFromOther(other->getTitleButton());
setRefString(other->m_referenceCount->text());
QString refString = other->m_referenceCount->text();
if (refString.size())
{
m_referenceCount->setText(refString);
m_referenceCount->show();
}
else
{
m_referenceCount->hide();
}
m_minimizeButton->setEnabled(other->m_minimizeButton->isEnabled());
m_snippetButton->setEnabled(other->m_snippetButton->isEnabled());
+4 -4
View File
@@ -19,15 +19,15 @@ signals:
void maximize();
public:
QtCodeFileTitleBar(QWidget* parent = nullptr, bool isHovering = false);
QtCodeFileTitleBar(QWidget* parent = nullptr, bool isHovering = false, bool isSingle = false);
QtCodeFileTitleButton* getTitleButton() const;
void setRefString(const QString& refString);
void updateRefCount(int refCount, bool hasErrors, size_t fatalErrorCount);
void setMinimized(bool hasSnippets);
void setMinimized();
void setSnippets();
void setMaximized(bool hasSnippets);
void setMaximized();
void updateFromOther(const QtCodeFileTitleBar* other);
@@ -15,7 +15,7 @@ QtCodeFileTitleButton::QtCodeFileTitleButton(QWidget* parent)
: QPushButton(parent)
, m_isComplete(true)
{
setObjectName("title_label");
setObjectName("title_button");
minimumSizeHint(); // force font loading
setAttribute(Qt::WA_LayoutUsesWidgetRect); // fixes layouting on Mac
@@ -35,18 +35,16 @@ void QtCodeFileTitleButton::setFilePath(const FilePath& filePath)
{
setEnabled(true);
if (m_filePath.empty())
{
std::string text = ResourcePaths::getGuiPath().str() + "code_view/images/file.png";
setIcon(utility::colorizePixmap(
QPixmap(text.c_str()),
ColorScheme::getInstance()->getColor("code/file/title/icon").c_str()
));
}
m_filePath = filePath;
setText("");
setText(filePath.fileName().c_str());
setToolTip(filePath.str().c_str());
std::string text = ResourcePaths::getGuiPath().str() + "code_view/images/file.png";
setIcon(utility::colorizePixmap(
QPixmap(text.c_str()),
ColorScheme::getInstance()->getColor("code/file/title/icon").c_str()
));
}
void QtCodeFileTitleButton::setModificationTime(const TimeStamp modificationTime)
@@ -54,7 +52,6 @@ void QtCodeFileTitleButton::setModificationTime(const TimeStamp modificationTime
if (modificationTime.isValid())
{
m_modificationTime = modificationTime;
updateTexts();
}
}
@@ -75,25 +72,24 @@ void QtCodeFileTitleButton::setIsComplete(bool isComplete)
);
setStyleSheet((
"#title_label, #file_title { background-image: url(" + hatchingFilePath.str() + "); }"
"#title_button { background-image: url(" + hatchingFilePath.str() + "); }"
).c_str());
}
else
{
setStyleSheet("");
}
updateTexts();
}
void QtCodeFileTitleButton::setProject(const std::string& name)
{
setText(name.c_str());
m_filePath = FilePath();
std::string text = ResourcePaths::getGuiPath().str() + "code_view/images/edit.png";
setText(name.c_str());
setToolTip("edit project");
std::string text = ResourcePaths::getGuiPath().str() + "code_view/images/edit.png";
setIcon(utility::colorizePixmap(
QPixmap(text.c_str()),
ColorScheme::getInstance()->getColor("code/file/title/icon").c_str()
@@ -139,6 +135,7 @@ void QtCodeFileTitleButton::updateFromOther(const QtCodeFileTitleButton* other)
setModificationTime(other->m_modificationTime);
setIsComplete(other->m_isComplete);
updateTexts();
}
void QtCodeFileTitleButton::contextMenuEvent(QContextMenuEvent* event)
@@ -43,15 +43,10 @@ void QtCodeNavigateable::ensureWidgetVisibleAnimated(
switch (target)
{
case SCROLL_VISIBLE:
if (focusRect.top() < visibleRect.top())
if (focusRect.top() > visibleRect.top() && focusRect.bottom() < visibleRect.bottom())
{
value = focusRect.top() - visibleRect.top() - 20;
return;
}
else if (focusRect.bottom() > visibleRect.bottom())
{
value = focusRect.bottom() - visibleRect.bottom() + 20;
}
break;
case SCROLL_CENTER:
value = focusRect.center().y() - visibleRect.center().y();
+69 -52
View File
@@ -24,6 +24,7 @@
QtCodeNavigator::QtCodeNavigator(QWidget* parent)
: QWidget(parent)
, m_mode(MODE_NONE)
, m_oldMode(MODE_NONE)
, m_activeTokenId(0)
, m_value(0)
, m_refIndex(0)
@@ -104,14 +105,8 @@ QtCodeNavigator::QtCodeNavigator(QWidget* parent)
m_single = new QtCodeFileSingle(this);
layout->addWidget(m_single);
if (ApplicationSettings::getInstance()->getCodeViewModeSingle())
{
setModeSingle();
}
else
{
setModeList();
}
setMode(ApplicationSettings::getInstance()->getCodeViewModeSingle() ? MODE_SINGLE : MODE_LIST);
showContents();
refreshStyle();
@@ -259,6 +254,25 @@ void QtCodeNavigator::clearCaches()
m_single->clearCache();
}
void QtCodeNavigator::clearSnippetReferences()
{
m_list->clearSnippetTitleAndScrollBar();
}
void QtCodeNavigator::setMode(Mode mode)
{
m_mode = mode;
if (mode == MODE_LIST)
{
m_current = m_list;
}
else
{
m_current = m_single;
}
}
const std::set<Id>& QtCodeNavigator::getCurrentActiveTokenIds() const
{
return m_currentActiveTokenIds;
@@ -504,10 +518,41 @@ void QtCodeNavigator::setFileMaximized(const FilePath path)
void QtCodeNavigator::updateFiles()
{
m_current->updateFiles();
updateRefLabel();
}
void QtCodeNavigator::showContents()
{
if (m_oldMode != m_mode)
{
m_listButton->setChecked(m_mode == MODE_LIST);
m_fileButton->setChecked(m_mode == MODE_SINGLE);
switch (m_mode)
{
case MODE_SINGLE:
m_list->hide();
m_single->show();
m_separatorLine->hide();
break;
case MODE_LIST:
m_single->hide();
m_list->show();
m_separatorLine->show();
break;
default:
LOG_ERROR("Wrong mode set in code navigator");
return;
}
ApplicationSettings::getInstance()->setCodeViewModeSingle(m_mode == MODE_SINGLE);
ApplicationSettings::getInstance()->save();
m_oldMode = m_mode;
}
m_current->showContents();
}
@@ -715,7 +760,7 @@ void QtCodeNavigator::requestScroll(
// std::cout << "scroll request: " << req.filePath.str() << " " << req.lineNumber << " " << req.locationId;
// std::cout << " " << req.animated << " " << req.target << std::endl;
if ((!m_scrollRequest.lineNumber || !m_scrollRequest.locationId) && !req.filePath.empty())
if ((!m_scrollRequest.lineNumber && !m_scrollRequest.locationId) && !req.filePath.empty())
{
m_scrollRequest = req;
}
@@ -802,50 +847,12 @@ void QtCodeNavigator::nextReference(bool fromUI)
void QtCodeNavigator::setModeList()
{
setMode(MODE_LIST);
m_single->clickedSnippetButton();
}
void QtCodeNavigator::setModeSingle()
{
setMode(MODE_SINGLE);
}
void QtCodeNavigator::setMode(Mode mode)
{
m_listButton->setChecked(mode == MODE_LIST);
m_fileButton->setChecked(mode == MODE_SINGLE);
if (m_mode == mode)
{
return;
}
m_mode = mode;
switch (mode)
{
case MODE_SINGLE:
m_list->hide();
m_single->show();
m_separatorLine->hide();
m_current = m_single;
break;
case MODE_LIST:
m_single->hide();
m_list->show();
m_separatorLine->show();
m_current = m_list;
break;
default:
LOG_ERROR("Wrong mode set in code navigator");
return;
}
ApplicationSettings::getInstance()->setCodeViewModeSingle(m_mode == MODE_SINGLE);
ApplicationSettings::getInstance()->save();
scrollToDefinition(false, false);
showContents();
m_list->maximizeFirstFile();
}
void QtCodeNavigator::showCurrentReference(bool fromUI)
@@ -903,16 +910,23 @@ void QtCodeNavigator::handleMessage(MessageFinishedParsing* message)
void QtCodeNavigator::handleMessage(MessageShowReference* message)
{
m_refIndex = message->refIndex;
size_t refIndex = message->refIndex;
bool replayed = message->isReplayed();
m_onQtThread(
[=]()
{
m_refIndex = refIndex;
if (m_refIndex > 0)
{
const Reference& ref = m_references[m_refIndex - 1];
setCurrentActiveLocationIds(std::vector<Id>(1, ref.locationId));
updateFiles();
if (!replayed)
{
updateFiles();
}
requestScroll(ref.filePath, 0, ref.locationId, true, QtCodeNavigateable::SCROLL_CENTER);
emit scrollRequest();
@@ -923,7 +937,10 @@ void QtCodeNavigator::handleMessage(MessageShowReference* message)
}
}
updateRefLabel();
if (!replayed)
{
updateRefLabel();
}
}
);
}
+11 -9
View File
@@ -31,6 +31,13 @@ class QtCodeNavigator
Q_OBJECT
public:
enum Mode
{
MODE_NONE,
MODE_LIST,
MODE_SINGLE
};
QtCodeNavigator(QWidget* parent = nullptr);
virtual ~QtCodeNavigator();
@@ -43,6 +50,9 @@ public:
void clearCodeSnippets();
void clearFile();
void clearCaches();
void clearSnippetReferences();
void setMode(Mode mode);
const std::set<Id>& getCurrentActiveTokenIds() const;
void setCurrentActiveTokenIds(const std::vector<Id>& currentActiveTokenIds);
@@ -114,15 +124,6 @@ private slots:
void setModeSingle();
private:
enum Mode
{
MODE_NONE,
MODE_LIST,
MODE_SINGLE
};
void setMode(Mode mode);
struct Reference
{
Reference()
@@ -172,6 +173,7 @@ private:
QtCodeFileSingle* m_single;
Mode m_mode;
Mode m_oldMode;
std::set<Id> m_currentActiveTokenIds;
std::set<Id> m_currentActiveLocationIds;
+2 -2
View File
@@ -200,10 +200,10 @@ void QtCodeSnippet::clickedTitle()
}
else
{
getFile()->clickedMaximizeButton();
getFile()->requestWholeFileContent();
}
m_navigator->requestScroll(getFile()->getFilePath(), getStartLineNumber(), 0, true, QtCodeNavigateable::SCROLL_CENTER);
m_navigator->requestScroll(getFile()->getFilePath(), getStartLineNumber(), 0, true, QtCodeNavigateable::SCROLL_VISIBLE);
}
void QtCodeSnippet::clickedFooter()
+15 -2
View File
@@ -146,10 +146,9 @@ void QtCodeView::showCodeSnippets(const std::vector<CodeSnippetParams>& snippets
m_widget->addedFiles();
}
m_widget->updateFiles();
if (params.showContents)
{
m_widget->updateFiles();
m_widget->showContents();
performScroll();
}
@@ -231,6 +230,7 @@ void QtCodeView::showContents()
m_onQtThread([=]()
{
TRACE("show contents");
m_widget->updateFiles();
m_widget->showContents();
performScroll();
});
@@ -241,6 +241,19 @@ bool QtCodeView::isInListMode() const
return m_widget->isInListMode();
}
void QtCodeView::setMode(bool listMode)
{
if (isInListMode() == listMode)
{
return;
}
m_onQtThread([=]()
{
m_widget->setMode(listMode ? QtCodeNavigator::MODE_LIST : QtCodeNavigator::MODE_SINGLE);
});
}
bool QtCodeView::hasSingleFileCached(const FilePath& filePath) const
{
return m_widget->hasSingleFileCached(filePath);
+2
View File
@@ -46,6 +46,8 @@ public:
virtual void showContents();
virtual bool isInListMode() const;
virtual void setMode(bool listMode);
virtual bool hasSingleFileCached(const FilePath& filePath) const;
private: