Introdcing source code viewer
parent
0a20185dc3
commit
f18a6b5b4d
|
@ -225,7 +225,7 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
|
|||
// this ensures that a following indented code block or list will be
|
||||
// inteprereted correctly.
|
||||
CR();
|
||||
LIT("<!-- end list -->");
|
||||
//LIT("<!-- end list -->");
|
||||
BLANKLINE();
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -40,6 +40,7 @@ set(HEADERS
|
|||
md-parser.h
|
||||
network.h
|
||||
render-area.h
|
||||
source-code-dialog.h
|
||||
)
|
||||
|
||||
set(SOURCES
|
||||
|
@ -52,6 +53,7 @@ set(SOURCES
|
|||
md-parser.cc
|
||||
network.cc
|
||||
render-area.cc
|
||||
source-code-dialog.cc
|
||||
${HEADERS}
|
||||
)
|
||||
|
||||
|
|
|
@ -29,6 +29,11 @@ cmark_node * File::fetch(const std::string& path)
|
|||
return parser.parseStream(contents);
|
||||
}
|
||||
|
||||
std::string const File::getSource(cmark_node *node)
|
||||
{
|
||||
return parser.getSource(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Free AST cmark_node memory, to avoid memory leaks
|
||||
*/
|
||||
|
|
|
@ -17,7 +17,8 @@ public:
|
|||
|
||||
cmark_node * read(const std::string& path); /*!< Read file from disk */
|
||||
cmark_node * fetch(const std::string& path); /*!< Fetch file from IPFS network */
|
||||
void free(cmark_node *node);
|
||||
std::string const getSource(cmark_node *node); /*!< Get source code from AST */
|
||||
void free(cmark_node *node); /*!< Free pointer */
|
||||
private:
|
||||
Parser parser;
|
||||
Network network;
|
||||
|
|
|
@ -15,7 +15,8 @@ MainWindow::MainWindow()
|
|||
: m_vbox(Gtk::ORIENTATION_VERTICAL, 0),
|
||||
m_hbox_bar(Gtk::ORIENTATION_HORIZONTAL, 0),
|
||||
requestPath(""),
|
||||
finalRequestPath("")
|
||||
finalRequestPath(""),
|
||||
currentSourceCode("")
|
||||
{
|
||||
set_title("DBrowser");
|
||||
set_default_size(1000, 800);
|
||||
|
@ -24,14 +25,19 @@ MainWindow::MainWindow()
|
|||
// Connect signals
|
||||
m_menu.quit.connect(sigc::mem_fun(this, &MainWindow::hide)); /*!< hide main window and therefor closes the app */
|
||||
m_menu.reload.connect(sigc::mem_fun(this, &MainWindow::refresh)); /*!< Menu item for reloading the page */
|
||||
m_menu.source_code.connect(sigc::mem_fun(this, &MainWindow::show_source_code_dialog)); /*!< Source code dialog */
|
||||
m_sourceCodeDialog.signal_response().connect(sigc::mem_fun(m_sourceCodeDialog, &SourceCodeDialog::hide_dialog)); /*!< Close source code dialog */
|
||||
m_menu.about.connect(sigc::mem_fun(m_about, &About::show_about)); /*!< Display about dialog */
|
||||
m_about.signal_response().connect(sigc::mem_fun(m_about, &About::hide_about)); /*!< Close about dialog */
|
||||
m_refreshButton.signal_clicked().connect(sigc::mem_fun(this, &MainWindow::refresh)); /*!< Button for reloading the page */
|
||||
m_homeButton.signal_clicked().connect(sigc::mem_fun(this, &MainWindow::go_home)); /*!< Button for home page */
|
||||
m_inputField.signal_activate().connect(sigc::mem_fun(this, &MainWindow::input_activate)); /*!< User pressed enter in the input */
|
||||
|
||||
m_vbox.pack_start(m_menu, false, false, 0);
|
||||
|
||||
|
||||
m_sourceCodeDialog.setText("Hallo!?");
|
||||
m_sourceCodeDialog.setText("123");
|
||||
|
||||
// Horizontal bar
|
||||
auto styleBack = m_backButton.get_style_context();
|
||||
styleBack->add_class("circular");
|
||||
|
@ -80,6 +86,7 @@ void MainWindow::go_home()
|
|||
{
|
||||
this->requestPath = "";
|
||||
this->finalRequestPath = "";
|
||||
this->currentSourceCode = "";
|
||||
this->m_inputField.set_text("");
|
||||
m_renderArea.showStartPage();
|
||||
}
|
||||
|
@ -92,6 +99,7 @@ void MainWindow::input_activate()
|
|||
|
||||
void MainWindow::doRequest(const std::string &path)
|
||||
{
|
||||
currentSourceCode = "";
|
||||
if (!path.empty()) {
|
||||
requestPath = path;
|
||||
}
|
||||
|
@ -137,6 +145,7 @@ void MainWindow::fetchFromIPFS()
|
|||
try {
|
||||
cmark_node *fetchDoc = m_file.fetch(finalRequestPath);
|
||||
m_renderArea.processDocument(fetchDoc);
|
||||
currentSourceCode = m_file.getSource(fetchDoc);
|
||||
m_file.free(fetchDoc);
|
||||
} catch (const std::runtime_error &error) {
|
||||
std::cerr << "IPFS Deamon is most likely down: " << error.what() << std::endl;
|
||||
|
@ -155,8 +164,15 @@ void MainWindow::openFromDisk()
|
|||
try {
|
||||
cmark_node *readDoc = m_file.read(finalRequestPath);
|
||||
m_renderArea.processDocument(readDoc);
|
||||
currentSourceCode = m_file.getSource(readDoc);
|
||||
m_file.free(readDoc);
|
||||
} catch (const std::runtime_error &error) {
|
||||
m_renderArea.showMessage("Page not found!", "Detailed error message: " + std::string(error.what()));
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::show_source_code_dialog()
|
||||
{
|
||||
m_sourceCodeDialog.setText(currentSourceCode);
|
||||
m_sourceCodeDialog.run();
|
||||
}
|
|
@ -11,6 +11,7 @@
|
|||
#include "menu.h"
|
||||
#include "file.h"
|
||||
#include "about.h"
|
||||
#include "source-code-dialog.h"
|
||||
|
||||
class MainWindow : public Gtk::Window
|
||||
{
|
||||
|
@ -25,6 +26,7 @@ protected:
|
|||
void on_button_clicked(Glib::ustring data);
|
||||
void show_about();
|
||||
void hide_about(int response);
|
||||
void show_source_code_dialog();
|
||||
|
||||
// Child widgets
|
||||
Menu m_menu;
|
||||
|
@ -41,11 +43,13 @@ protected:
|
|||
Gtk::Image homeIcon;
|
||||
Gtk::ScrolledWindow m_scrolledWindow;
|
||||
RenderArea m_renderArea;
|
||||
SourceCodeDialog m_sourceCodeDialog;
|
||||
About m_about;
|
||||
private:
|
||||
File m_file;
|
||||
std::string requestPath;
|
||||
std::string finalRequestPath;
|
||||
std::string currentSourceCode;
|
||||
|
||||
void doRequest(const std::string &path = "");
|
||||
void refresh();
|
||||
|
|
|
@ -64,6 +64,17 @@ std::string const Parser::renderHTML(cmark_node *node)
|
|||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get just the plain text
|
||||
*/
|
||||
std::string const Parser::getSource(cmark_node *node)
|
||||
{
|
||||
char *tmp = cmark_render_commonmark(node, options, 0);
|
||||
std::string output = std::string(tmp);
|
||||
free(tmp);
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a function that will make enabling extensions easier
|
||||
*/
|
||||
|
|
|
@ -15,6 +15,7 @@ public:
|
|||
cmark_node * parseFile(const std::string &filePath);
|
||||
cmark_node * parseStream(const std::stringstream &stream);
|
||||
std::string const renderHTML(cmark_node *node);
|
||||
std::string const getSource(cmark_node *node);
|
||||
|
||||
private:
|
||||
int options;
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
#include "source-code-dialog.h"
|
||||
#include <gtkmm/textbuffer.h>
|
||||
|
||||
SourceCodeDialog::SourceCodeDialog()
|
||||
{
|
||||
set_title("View source code");
|
||||
set_default_size(700, 750);
|
||||
|
||||
m_scrolledWindow.add(m_sourceCode);
|
||||
m_scrolledWindow.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
|
||||
|
||||
auto vbox = get_content_area();
|
||||
vbox->pack_start(m_scrolledWindow, true, true, 0);
|
||||
|
||||
show_all_children();
|
||||
}
|
||||
SourceCodeDialog::~SourceCodeDialog() {}
|
||||
|
||||
/**
|
||||
* Set multi-line code source
|
||||
* \param[in] text Source code text
|
||||
*/
|
||||
void SourceCodeDialog::setText(const std::string& text)
|
||||
{
|
||||
Glib::RefPtr<Gtk::TextBuffer> buffer = m_sourceCode.get_buffer();
|
||||
buffer->set_text(text);
|
||||
}
|
||||
|
||||
void SourceCodeDialog::hide_dialog(__attribute__((unused)) int response)
|
||||
{
|
||||
hide();
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
#ifndef SOURCE_CODE_WINDOW_H
|
||||
#define SOURCE_CODE_WINDOW_H
|
||||
|
||||
#include <gtkmm/dialog.h>
|
||||
#include <gtkmm/textview.h>
|
||||
#include <gtkmm/scrolledwindow.h>
|
||||
#include <string>
|
||||
|
||||
class SourceCodeDialog : public Gtk::Dialog
|
||||
{
|
||||
public:
|
||||
SourceCodeDialog();
|
||||
virtual ~SourceCodeDialog();
|
||||
|
||||
void setText(const std::string& text);
|
||||
|
||||
void hide_dialog(int response);
|
||||
protected:
|
||||
// Child widgets
|
||||
Gtk::ScrolledWindow m_scrolledWindow;
|
||||
Gtk::TextView m_sourceCode;
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue