Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Big rock]: Feature - navigate on click/double click #200

Merged
merged 3 commits into from
Oct 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 15 additions & 9 deletions src/NppJsonViewer/JsonHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <rapidjson/error/en.h>

#include "Define.h"
#include "TrackingStream.h"

namespace rj = rapidjson;

Expand Down Expand Up @@ -42,7 +43,7 @@ class JsonHandler
auto ValidateJson(const std::string& jsonText) -> const Result;

template <unsigned format, typename Handler>
auto ParseJson(const std::string& jsonText, rj::StringBuffer& sb, Handler& handler) -> const Result;
auto ParseJson(const std::string& jsonText, rj::StringBuffer& sb, Handler& handler, TrackingStreamSharedPtr pTS = nullptr) -> const Result;

private:
void SortJsonObject(rj::Value& jsonObject, rj::Document::AllocatorType& allocator) const;
Expand All @@ -51,13 +52,18 @@ class JsonHandler
};

template <unsigned flgBase, typename Handler>
inline auto JsonHandler::ParseJson(const std::string& jsonText, rj::StringBuffer& sb, Handler& handler) -> const Result
inline auto JsonHandler::ParseJson(const std::string& jsonText, rj::StringBuffer& sb, Handler& handler, TrackingStreamSharedPtr pTS) -> const Result
{
Result retVal {};

bool success = false;
rj::Reader reader;
rj::StringStream ss(jsonText.c_str());
bool success = false;
rj::Reader reader;

std::shared_ptr<rj::StringStream> pSS = nullptr;
if (!pTS)
{
pSS = std::make_shared<rj::StringStream>(jsonText.c_str());
}

// TODO: Find some better way
constexpr auto flgBase_comment = flgBase | rj::kParseCommentsFlag;
Expand All @@ -66,22 +72,22 @@ inline auto JsonHandler::ParseJson(const std::string& jsonText, rj::StringBuffer

if (m_parseOptions.bIgnoreComment && m_parseOptions.bIgnoreTrailingComma)
{
success = reader.Parse<flgBase_Both>(ss, handler) && sb.GetString();
success = pTS ? reader.Parse<flgBase_Both>(*pTS, handler) && sb.GetString() : reader.Parse<flgBase_Both>(*pSS, handler) && sb.GetString();
}

else if (!m_parseOptions.bIgnoreComment && m_parseOptions.bIgnoreTrailingComma)
{
success = reader.Parse<flgBase_comma>(ss, handler) && sb.GetString();
success = pTS ? reader.Parse<flgBase_comma>(*pTS, handler) && sb.GetString() : reader.Parse<flgBase_comma>(*pSS, handler) && sb.GetString();
}

else if (m_parseOptions.bIgnoreComment && !m_parseOptions.bIgnoreTrailingComma)
{
success = reader.Parse<flgBase_comment>(ss, handler) && sb.GetString();
success = pTS ? reader.Parse<flgBase_comment>(*pTS, handler) && sb.GetString() : reader.Parse<flgBase_comment>(*pSS, handler) && sb.GetString();
}

else if (!m_parseOptions.bIgnoreComment && !m_parseOptions.bIgnoreTrailingComma)
{
success = reader.Parse<flgBase>(ss, handler) && sb.GetString();
success = pTS ? reader.Parse<flgBase>(*pTS, handler) && sb.GetString() : reader.Parse<flgBase>(*pSS, handler) && sb.GetString();
}

if (success)
Expand Down
25 changes: 24 additions & 1 deletion src/NppJsonViewer/JsonNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,32 @@ enum class JsonNodeType : short
OBJECT,
};

struct Position
{
size_t nLine {};
size_t nColumn {};

void clear()
{
nLine = nColumn = 0;
}
};

struct JsonKey
{
Position pos {};
std::string strKey;

void clear()
{
pos.clear();
strKey.clear();
}
};

struct JsonNode
{
std::string key;
JsonKey key;
std::string value;
JsonNodeType type = JsonNodeType::UNKNOWN;
};
76 changes: 63 additions & 13 deletions src/NppJsonViewer/JsonViewDlg.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
#include <format>
#include <regex>

#include "JsonViewDlg.h"
#include "Define.h"
#include "Utility.h"
#include "StringHelper.h"
#include "RapidJsonHandler.h"
#include "ScintillaEditor.h"
#include "Profile.h"
#include <format>
#include <regex>


constexpr int FILENAME_LEN_IN_TITLE = 16;

Expand Down Expand Up @@ -100,6 +102,8 @@ void JsonViewDlg::FormatJson()

ReportError(res);
}

ReDrawJsonTree();
}

void JsonViewDlg::CompressJson()
Expand Down Expand Up @@ -130,6 +134,8 @@ void JsonViewDlg::CompressJson()

ReportError(res);
}

ReDrawJsonTree();
}

void JsonViewDlg::SortJsonByKey()
Expand Down Expand Up @@ -162,6 +168,8 @@ void JsonViewDlg::SortJsonByKey()

ReportError(res);
}

ReDrawJsonTree();
}

bool JsonViewDlg::CheckForTokenUndefined(eMethod method, std::string selectedText, Result& res, HTREEITEM tree_root)
Expand All @@ -171,14 +179,8 @@ bool JsonViewDlg::CheckForTokenUndefined(eMethod method, std::string selectedTex
if (m_pSetting->parseOptions.bReplaceUndefined)
{
auto text = selectedText.substr(res.error_pos, 9);
std::transform(
text.begin(),
text.end(),
text.begin(),
[](unsigned char c)
{
return (unsigned char)std::tolower(c);
});
StringHelper::ToLower(text);

if (text == "undefined")
{
try
Expand Down Expand Up @@ -217,7 +219,7 @@ bool JsonViewDlg::CheckForTokenUndefined(eMethod method, std::string selectedTex
else
{
m_pEditor->ReplaceSelection(text);
m_pEditor->MakeSelection(m_pEditor->GetSelectionStart(), static_cast<int>(text.length()));
m_pEditor->MakeSelection(m_pEditor->GetSelectionStart(), text.length());
m_pEditor->RefreshSelectionPos();
}
}
Expand Down Expand Up @@ -326,6 +328,8 @@ void JsonViewDlg::ValidateJson()

ReportError(res);
}

DrawJsonTree();
}

void JsonViewDlg::DrawJsonTree()
Expand Down Expand Up @@ -379,6 +383,16 @@ void JsonViewDlg::DrawJsonTree()
EnableControls(ctrls, true);
}

void JsonViewDlg::ReDrawJsonTree(bool bForce)
{
const bool bIsVisible = isCreated() && isVisible();
const bool bReDraw = bForce || bIsVisible;
if (bReDraw)
{
DrawJsonTree();
}
}

void JsonViewDlg::HighlightAsJson(bool bForcefully) const
{
bool setJsonLang = bForcefully || m_pSetting->bUseJsonHighlight;
Expand All @@ -390,10 +404,11 @@ auto JsonViewDlg::PopulateTreeUsingSax(HTREEITEM tree_root, const std::string& j
{
std::optional<std::wstring> retVal = std::nullopt;

RapidJsonHandler handler(this, tree_root);
auto pTS = std::make_shared<TrackingStream>(jsonText);
RapidJsonHandler handler(this, tree_root, pTS);
rapidjson::StringBuffer sb;

Result res = JsonHandler(m_pSetting->parseOptions).ParseJson<flgBaseReader>(jsonText, sb, handler);
Result res = JsonHandler(m_pSetting->parseOptions).ParseJson<flgBaseReader>(jsonText, sb, handler, pTS);
if (!res.success)
{
if (CheckForTokenUndefined(JsonViewDlg::eMethod::ParseJson, jsonText, res, tree_root))
Expand Down Expand Up @@ -429,6 +444,13 @@ HTREEITEM JsonViewDlg::InsertToTree(HTREEITEM parent, const std::string& text)
return m_hTreeView->InsertNode(wText, NULL, parent);
}

HTREEITEM JsonViewDlg::InsertToTree(HTREEITEM parent, const std::string& text, const Position& pos)
{
auto wText = StringHelper::ToWstring(text, CP_UTF8);
auto lparam = new Position(pos);
return m_hTreeView->InsertNode(wText, reinterpret_cast<LPARAM>(lparam), parent);
}

void JsonViewDlg::AppendNodeCount(HTREEITEM node, unsigned elementCount, bool bArray)
{
if (!node)
Expand All @@ -450,6 +472,16 @@ void JsonViewDlg::UpdateNodePath(HTREEITEM htiNode)
CUtility::SetEditCtrlText(::GetDlgItem(_hSelf, IDC_EDT_NODEPATH), nodePath);
}

void JsonViewDlg::GoToLine(size_t nLineToGo)
{
m_pEditor->GoToLine(nLineToGo);
}

void JsonViewDlg::GoToPosition(size_t nLineToGo, size_t nPos)
{
m_pEditor->GoToPosition(nLineToGo, nPos);
}

void JsonViewDlg::SearchInTree()
{
std::wstring itemToSearch = CUtility::GetEditCtrlText(::GetDlgItem(_hSelf, IDC_EDT_SEARCH));
Expand Down Expand Up @@ -878,6 +910,24 @@ void JsonViewDlg::HandleTreeEvents(LPARAM lParam)
if (hItem && (pnmtv->action == TVC_BYMOUSE || pnmtv->action == TVC_BYKEYBOARD))
{
UpdateNodePath(hItem);

auto pPosition = m_hTreeView->GetNodePosition(hItem);
if (pPosition != nullptr)
{
GoToLine(pPosition->nLine);
}
}
}
break;

case NM_DBLCLK:
{
HTREEITEM hItem = m_hTreeView->GetSelection();

auto pPosition = m_hTreeView->GetNodePosition(hItem);
if (pPosition != nullptr)
{
GoToPosition(pPosition->nLine, pPosition->nColumn);
}
}
break;
Expand Down
5 changes: 5 additions & 0 deletions src/NppJsonViewer/JsonViewDlg.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "TreeViewCtrl.h"
#include "ScintillaEditor.h"
#include "JsonHandler.h"
#include "JsonNode.h"


class JsonViewDlg : public DockingDlgInterface
Expand Down Expand Up @@ -44,16 +45,20 @@ class JsonViewDlg : public DockingDlgInterface
void UpdateTitle();

HTREEITEM InsertToTree(HTREEITEM parent, const std::string& text);
HTREEITEM InsertToTree(HTREEITEM parent, const std::string& text, const Position& pos);
void AppendNodeCount(HTREEITEM node, unsigned elementCount, bool bArray);

private:
void DrawJsonTree();
void ReDrawJsonTree(bool bForce = false);
void HighlightAsJson(bool bForcefully = false) const;
auto PopulateTreeUsingSax(HTREEITEM tree_root, const std::string& jsonText) -> std::optional<std::wstring>;

void ValidateJson();

void UpdateNodePath(HTREEITEM htiNode);
void GoToLine(size_t nLineToGo);
void GoToPosition(size_t nLineToGo, size_t nPos);

void SearchInTree();

Expand Down
1 change: 1 addition & 0 deletions src/NppJsonViewer/NPPJSONViewer.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@
<ClInclude Include="SettingsDlg.h" />
<ClInclude Include="ShortcutCommand.h" />
<ClInclude Include="StopWatch.h" />
<ClInclude Include="TrackingStream.h" />
<ClInclude Include="TreeViewCtrl.h" />
</ItemGroup>
<ItemGroup>
Expand Down
3 changes: 3 additions & 0 deletions src/NppJsonViewer/NPPJSONViewer.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,9 @@
<ClInclude Include="..\..\external\npp\Window.h">
<Filter>ThirdParty\npp</Filter>
</ClInclude>
<ClInclude Include="TrackingStream.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="resource.rc">
Expand Down
28 changes: 15 additions & 13 deletions src/NppJsonViewer/RapidJsonHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,9 @@ bool RapidJsonHandler::String(const Ch* str, unsigned /*length*/, bool /*copy*/)

bool RapidJsonHandler::Key(const Ch* str, unsigned /*length*/, bool /*copy*/)
{
m_strLastKey = str;
m_jsonLastKey.strKey = str;
m_jsonLastKey.pos.nLine = m_pTS->getLine();
m_jsonLastKey.pos.nColumn = m_pTS->getColumn();
return true;
}

Expand All @@ -101,13 +103,13 @@ bool RapidJsonHandler::StartObject()
parent = m_NodeStack.top();
}

if (!m_strLastKey.empty() || parent->node.type == JsonNodeType::ARRAY)
if (!m_jsonLastKey.strKey.empty() || parent->node.type == JsonNodeType::ARRAY)
{
HTREEITEM newNode = nullptr;
if (parent->node.type != JsonNodeType::ARRAY)
{
newNode = m_dlg->InsertToTree(parent->subRoot, m_strLastKey);
m_strLastKey.clear();
newNode = m_dlg->InsertToTree(parent->subRoot, m_jsonLastKey.strKey, m_jsonLastKey.pos);
m_jsonLastKey.clear();
}
else
{
Expand Down Expand Up @@ -150,13 +152,13 @@ bool RapidJsonHandler::StartArray()
parent = m_NodeStack.top();
}

if (!m_strLastKey.empty() || parent->node.type == JsonNodeType::ARRAY)
if (!m_jsonLastKey.strKey.empty() || parent->node.type == JsonNodeType::ARRAY)
{
HTREEITEM newNode;
if (parent->node.type != JsonNodeType::ARRAY)
{
newNode = m_dlg->InsertToTree(parent->subRoot, m_strLastKey);
m_strLastKey.clear();
newNode = m_dlg->InsertToTree(parent->subRoot, m_jsonLastKey.strKey, m_jsonLastKey.pos);
m_jsonLastKey.clear();
}
else
{
Expand Down Expand Up @@ -188,22 +190,22 @@ void RapidJsonHandler::InsertToTree(TreeNode* node, const char* const str, bool

if (node->node.type != JsonNodeType::ARRAY)
{
node->node.key = m_strLastKey;
node->node.key = m_jsonLastKey;
node->node.value = str;
m_strLastKey.clear();
m_jsonLastKey.clear();
}
else
{
node->node.key = "[" + std::to_string(node->counter) + "]";
node->node.value = str;
node->node.key.strKey = "[" + std::to_string(node->counter) + "]";
node->node.value = str;
node->counter++;
}

// Insert item to tree
if (bQuote)
m_dlg->InsertToTree(node->subRoot, node->node.key + " : \"" + node->node.value + "\"");
m_dlg->InsertToTree(node->subRoot, node->node.key.strKey + " : \"" + node->node.value + "\"", node->node.key.pos);
else
m_dlg->InsertToTree(node->subRoot, node->node.key + " : " + node->node.value);
m_dlg->InsertToTree(node->subRoot, node->node.key.strKey + " : " + node->node.value, node->node.key.pos);
}

void RapidJsonHandler::AppendNodeCount(unsigned elementCount, bool bArray)
Expand Down
Loading
Loading