Revision c393c256
Added by david.sorber 8 months ago
| src/Catalog.cc | ||
|---|---|---|
|
#include <fstream>
|
||
|
#include <iostream>
|
||
|
#include <sstream>
|
||
|
#include <stdexcept>
|
||
|
|
||
|
#include <sodium.h>
|
||
|
|
||
| ... | ... | |
|
{
|
||
|
if (sodium_init() != 0)
|
||
|
{
|
||
|
// TODO: throw exception here
|
||
|
// return 1;
|
||
|
throw std::runtime_error("libsodium init error!");
|
||
|
}
|
||
|
}
|
||
|
|
||
| src/Catalog.h | ||
|---|---|---|
|
{
|
||
|
public:
|
||
|
|
||
|
static inline CatalogItem INVALID_ITEM{"INVALID", "INVALID"};
|
||
|
|
||
|
Catalog();
|
||
|
|
||
|
~Catalog();
|
||
| ... | ... | |
|
return m_catalog.end();
|
||
|
}
|
||
|
|
||
|
inline CatalogItem& getItemById(int id)
|
||
|
{
|
||
|
for (auto& iter : m_catalog)
|
||
|
{
|
||
|
if (iter.getId() == id)
|
||
|
{
|
||
|
return iter;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return INVALID_ITEM;
|
||
|
}
|
||
|
|
||
|
void setAllVisible();
|
||
|
|
||
|
void filter(const std::string& criteria);
|
||
| src/CatalogItem.cc | ||
|---|---|---|
|
|
||
|
#include "CatalogItem.h"
|
||
|
|
||
|
// Initialize static member
|
||
|
int CatalogItem::NEXT_ID(-1);
|
||
|
|
||
|
CatalogItem::CatalogItem(const std::string& key, const std::string& value)
|
||
|
: m_key(key),
|
||
|
: m_id(NEXT_ID++),
|
||
|
m_key(key),
|
||
|
m_keyLower(key),
|
||
|
m_value(value),
|
||
|
m_visible(true)
|
||
| src/CatalogItem.h | ||
|---|---|---|
|
|
||
|
~CatalogItem();
|
||
|
|
||
|
inline int getId() const
|
||
|
{
|
||
|
return m_id;
|
||
|
}
|
||
|
|
||
|
inline const std::string& getKey() const
|
||
|
{
|
||
|
return m_key;
|
||
| ... | ... | |
|
m_visible = vis;
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Return true if the specified criteria matches the key
|
||
|
* @param criteria
|
||
| ... | ... | |
|
|
||
|
private:
|
||
|
|
||
|
static int NEXT_ID;
|
||
|
|
||
|
int m_id;
|
||
|
std::string m_key;
|
||
|
std::string m_keyLower;
|
||
|
std::string m_value;
|
||
| ... | ... | |
|
char m_valueBuffer[VALUE_BUFFER_SIZE];
|
||
|
|
||
|
bool m_visible;
|
||
|
|
||
|
|
||
|
|
||
|
};
|
||
|
|
||
|
|
||
| src/main.cc | ||
|---|---|---|
|
#endif
|
||
|
|
||
|
const std::string APP_NAME("pwmgr");
|
||
|
const std::string VERSION("v0.1.5");
|
||
|
const std::string VERSION("v0.2.0");
|
||
|
const std::string DEFAULT_FILEPATH("/home/dsorber/Documents/chicken_soup/chicken_soup.txt.enc");
|
||
|
|
||
|
const std::string BOLD{"\033[1m"};
|
||
| ... | ... | |
|
// Main loop
|
||
|
bool done = false;
|
||
|
bool dataLoaded = false;
|
||
|
|
||
|
bool loading = false;
|
||
|
char filterBuffer[128]{};
|
||
|
char filePathBuffer[BUFFER_SIZE]{};
|
||
| ... | ... | |
|
std::memcpy(filePathBuffer, DEFAULT_FILEPATH.data(),
|
||
|
DEFAULT_FILEPATH.size());
|
||
|
}
|
||
|
char passwdBuffer[BUFFER_SIZE]{};
|
||
|
const char* statusText = STR_PWD;
|
||
|
|
||
|
char passwdBuffer[BUFFER_SIZE]{};
|
||
|
int selected_entry_idx = -1;
|
||
|
bool entry_highlight = false;
|
||
|
int entry_highlighted_idx = -1;
|
||
|
int selected = 0;
|
||
|
bool firstTime = true;
|
||
|
|
||
|
while (! done)
|
||
|
{
|
||
|
// Poll and handle events (inputs, window resize, etc.)
|
||
| ... | ... | |
|
|
||
|
//---[Left side]----------------------------------------------------
|
||
|
ImGui::SetNextWindowPos(ImVec2(0.0f, 46.0f));
|
||
|
static int selected = 0;
|
||
|
static bool firstTime = true;
|
||
|
{
|
||
|
ImGui::BeginChild("left_pane", ImVec2(150, 0),
|
||
|
ImGuiChildFlags_Borders |
|
||
|
ImGuiChildFlags_ResizeX);
|
||
|
ImGuiChildFlags_ResizeX,
|
||
|
ImGuiWindowFlags_NoScrollbar);
|
||
|
|
||
|
for (auto &iter: catalog)
|
||
|
ImVec2 contentRegionAvailable = ImGui::GetContentRegionAvail();
|
||
|
float parentHeight = contentRegionAvailable.y;
|
||
|
|
||
|
if (ImGui::BeginListBox("##entries_listbox",
|
||
|
ImVec2(-FLT_MIN, parentHeight)))
|
||
|
{
|
||
|
// ImGuiInputTextFlags_ReadOnly
|
||
|
if (iter.visible() &&
|
||
|
ImGui::CollapsingHeader(iter.getKey().c_str()))
|
||
|
for (auto &iter: catalog)
|
||
|
{
|
||
|
ImGui::InputTextMultiline(
|
||
|
iter.getLcKey().c_str(),
|
||
|
iter.getValueBuffer(),
|
||
|
iter.getValueBufferSize(),
|
||
|
ImVec2(-FLT_MIN,
|
||
|
ImGui::GetTextLineHeight() * 5),
|
||
|
MULTILINE_TEXT_FLAGS);
|
||
|
const bool is_selected = (selected_entry_idx == iter.getId());
|
||
|
|
||
|
if (iter.visible())
|
||
|
{
|
||
|
if (ImGui::Selectable(iter.getKey().c_str(), is_selected))
|
||
|
{
|
||
|
selected_entry_idx = iter.getId();
|
||
|
}
|
||
|
|
||
|
if (entry_highlight && ImGui::IsItemHovered())
|
||
|
{
|
||
|
entry_highlighted_idx = iter.getId();
|
||
|
}
|
||
|
|
||
|
if (is_selected)
|
||
|
{
|
||
|
ImGui::SetItemDefaultFocus();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
ImGui::EndListBox();
|
||
|
}
|
||
|
|
||
|
ImGui::EndChild();
|
||
| ... | ... | |
|
}
|
||
|
|
||
|
ImGui::Separator();
|
||
|
if (ImGui::BeginTabBar("##Tabs", ImGuiTabBarFlags_None))
|
||
|
{
|
||
|
if (ImGui::BeginTabItem("Options"))
|
||
|
{
|
||
|
ImGui::TextWrapped(
|
||
|
"Lorem ipsum dolor sit amet, consectetur adipiscing "
|
||
|
"elit, sed do eiusmod tempor incididunt ut labore et"
|
||
|
" dolore magna aliqua. ");
|
||
|
ImGui::EndTabItem();
|
||
|
}
|
||
|
ImGui::Text("Entry:");
|
||
|
static char text[1024 * 16] = "foobarbizzle";
|
||
|
|
||
|
if (ImGui::BeginTabItem("About"))
|
||
|
{
|
||
|
ImGui::Text("%s version: %s", APP_NAME.c_str(),
|
||
|
VERSION.c_str());
|
||
|
ImGui::Text("Compiled on: %s ", __TIMESTAMP__);
|
||
|
ImGui::Text("Created by: dsorber");
|
||
|
ImGui::EndTabItem();
|
||
|
}
|
||
|
ImGui::EndTabBar();
|
||
|
// Get the selected entry from the listbox on the left this will return
|
||
|
// the INVALID_ITEM if the selected index is invalid
|
||
|
CatalogItem& entry = catalog.getItemById(selected_entry_idx);
|
||
|
if (entry.getId() == -1 || (! entry.visible()))
|
||
|
{
|
||
|
ImGui::InputTextMultiline("##entry_value",
|
||
|
text,
|
||
|
IM_ARRAYSIZE(text),
|
||
|
ImVec2(-FLT_MIN, ImGui::GetTextLineHeight() * 16),
|
||
|
ImGuiInputTextFlags_AllowTabInput);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Display the selected entry's value
|
||
|
ImGui::InputTextMultiline("##entry_value",
|
||
|
entry.getValueBuffer(),
|
||
|
entry.getValueBufferSize(),
|
||
|
ImVec2(-FLT_MIN, ImGui::GetTextLineHeight() * 16),
|
||
|
ImGuiInputTextFlags_AllowTabInput |
|
||
|
ImGuiInputTextFlags_ReadOnly);
|
||
|
}
|
||
|
ImGui::EndChild();
|
||
|
|
||
|
if (ImGui::Button("Save"))
|
||
|
{
|
||
|
// I'll make this do something someday
|
||
|
ImGui::OpenPopup("save_popup");
|
||
|
}
|
||
|
|
||
|
if (ImGui::BeginPopup("save_popup"))
|
||
|
{
|
||
|
ImGui::SeparatorText("Save Popup");
|
||
|
ImGui::Text("Someday this button will do something...");
|
||
|
ImGui::Text("but today is not that day");
|
||
|
ImGui::PushFont(tinyfont);
|
||
|
ImGui::Text("(click anywhere outside to close)");
|
||
|
ImGui::PopFont();
|
||
|
ImGui::EndPopup();
|
||
|
}
|
||
|
|
||
|
ImGui::EndChild();
|
||
|
ImGui::EndGroup();
|
||
|
}
|
||
|
|
||
Revamp display widgets. Use a listbox on the left panel and a multiline
text box in the main right panel. Bump version to 0.2.0.