working save & save as
parent
02978f7565
commit
747ba7587f
28
src/file.cc
28
src/file.cc
|
@ -3,6 +3,7 @@
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
#ifdef LEGACY_CXX
|
#ifdef LEGACY_CXX
|
||||||
#include <experimental/filesystem>
|
#include <experimental/filesystem>
|
||||||
|
@ -15,6 +16,7 @@ namespace n_fs = ::std::filesystem;
|
||||||
/**
|
/**
|
||||||
* Get file from disk
|
* Get file from disk
|
||||||
* \param path File path
|
* \param path File path
|
||||||
|
* \throw std::runtime_error exception when file is not found (or not a regular file)
|
||||||
* \return AST model of markdown file (cmark_node)
|
* \return AST model of markdown file (cmark_node)
|
||||||
*/
|
*/
|
||||||
std::string const File::read(const std::string &path)
|
std::string const File::read(const std::string &path)
|
||||||
|
@ -35,6 +37,20 @@ std::string const File::read(const std::string &path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write file to disk
|
||||||
|
* \param path File path location for storing the file
|
||||||
|
* \param content Content that needs to be written to file
|
||||||
|
* \throw std::ifstream::failure or std::ios_base::failure when file can't be open or can't be read/written
|
||||||
|
*/
|
||||||
|
void File::write(const std::string &path, const std::string &content)
|
||||||
|
{
|
||||||
|
std::ofstream file;
|
||||||
|
file.open(path.c_str());
|
||||||
|
file << content;
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch file from IFPS network (create a new client connection for thread safety)
|
* Fetch file from IFPS network (create a new client connection for thread safety)
|
||||||
* \param path File path
|
* \param path File path
|
||||||
|
@ -48,3 +64,15 @@ std::string const File::fetch(const std::string &path)
|
||||||
client.FilesGet(path, &contents);
|
client.FilesGet(path, &contents);
|
||||||
return contents.str();
|
return contents.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Publish file to IPFS network (does *not* need to be thead-safe, but is thread-safe nevertheless now)
|
||||||
|
* \param filename Filename that gets stored in IPFS
|
||||||
|
* \param content Content that needs to be written to the IPFS network
|
||||||
|
* \return IPFS content-addressed identifier (CID)
|
||||||
|
*/
|
||||||
|
std::string const File::publish(const std::string &filename, const std::string &content)
|
||||||
|
{
|
||||||
|
// TODO: Publish file to IPFS
|
||||||
|
return "CID";
|
||||||
|
}
|
|
@ -10,7 +10,9 @@
|
||||||
class File
|
class File
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static std::string const read(const std::string &path); /*!< Read file from disk */
|
static std::string const read(const std::string &path);
|
||||||
static std::string const fetch(const std::string &path); /*!< Fetch file from IPFS network */
|
static void write(const std::string &path, const std::string &content);
|
||||||
|
static std::string const fetch(const std::string &path);
|
||||||
|
static std::string const publish(const std::string &filename, const std::string &content);
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
|
@ -10,18 +10,15 @@
|
||||||
#include <glibmm/fileutils.h>
|
#include <glibmm/fileutils.h>
|
||||||
#include <glibmm/miscutils.h>
|
#include <glibmm/miscutils.h>
|
||||||
#include <glibmm/main.h>
|
#include <glibmm/main.h>
|
||||||
|
#include <glibmm/convert.h>
|
||||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||||
#include <glibmm/miscutils.h>
|
#include <glibmm/miscutils.h>
|
||||||
#include <cmark-gfm.h>
|
#include <cmark-gfm.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
/**
|
|
||||||
* For info: NDEBUG variable be used for debugging purpose, example:
|
|
||||||
* #ifdef NDEBUG
|
|
||||||
* #endif
|
|
||||||
*/
|
|
||||||
MainWindow::MainWindow()
|
MainWindow::MainWindow()
|
||||||
: m_accelGroup(Gtk::AccelGroup::create()),
|
: m_accelGroup(Gtk::AccelGroup::create()),
|
||||||
m_settings(),
|
m_settings(),
|
||||||
|
@ -43,6 +40,7 @@ MainWindow::MainWindow()
|
||||||
requestPath(""),
|
requestPath(""),
|
||||||
finalRequestPath(""),
|
finalRequestPath(""),
|
||||||
currentContent(""),
|
currentContent(""),
|
||||||
|
currentFileSavedPath(""),
|
||||||
currentHistoryIndex(0),
|
currentHistoryIndex(0),
|
||||||
ipfs("localhost", 5001) // Connect to IPFS daemon
|
ipfs("localhost", 5001) // Connect to IPFS daemon
|
||||||
{
|
{
|
||||||
|
@ -307,7 +305,7 @@ MainWindow::MainWindow()
|
||||||
m_homeButton.set_tooltip_text("Home page (Alt+Home)");
|
m_homeButton.set_tooltip_text("Home page (Alt+Home)");
|
||||||
m_statusButton.set_tooltip_text("IPFS Network Status");
|
m_statusButton.set_tooltip_text("IPFS Network Status");
|
||||||
|
|
||||||
// Disable back/forward button on start-up
|
// Disable back/forward buttons on start-up
|
||||||
m_backButton.set_sensitive(false);
|
m_backButton.set_sensitive(false);
|
||||||
m_forwardButton.set_sensitive(false);
|
m_forwardButton.set_sensitive(false);
|
||||||
|
|
||||||
|
@ -396,14 +394,14 @@ MainWindow::MainWindow()
|
||||||
// timer will do the updates later
|
// timer will do the updates later
|
||||||
this->update_connection_status();
|
this->update_connection_status();
|
||||||
|
|
||||||
// Show homepage if debugging is disabled
|
// Show homepage if debugging is disabled
|
||||||
#ifdef NDEBUG
|
#ifdef NDEBUG
|
||||||
go_home();
|
go_home();
|
||||||
#else
|
#else
|
||||||
std::cout << "INFO: Running as Debug mode, opening test.md." << std::endl;
|
std::cout << "INFO: Running as Debug mode, opening test.md." << std::endl;
|
||||||
// Load test file when developing
|
// Load test file when developing
|
||||||
doRequest("file://../../test.md", true);
|
doRequest("file://../../test.md", true);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -647,17 +645,141 @@ void MainWindow::new_doc()
|
||||||
|
|
||||||
void MainWindow::open()
|
void MainWindow::open()
|
||||||
{
|
{
|
||||||
std::cout << "INFO: TODO" << std::endl;
|
auto dialog = new Gtk::FileChooserDialog("Open", Gtk::FILE_CHOOSER_ACTION_OPEN);
|
||||||
|
dialog->set_transient_for(*this);
|
||||||
|
dialog->set_modal(true);
|
||||||
|
dialog->signal_response().connect(sigc::bind(sigc::mem_fun(*this, &MainWindow::on_open_dialog_response), dialog));
|
||||||
|
dialog->add_button("_Cancel", Gtk::ResponseType::RESPONSE_CANCEL);
|
||||||
|
dialog->add_button("_Open", Gtk::ResponseType::RESPONSE_OK);
|
||||||
|
|
||||||
|
// Add filters, so that only certain file types can be selected:
|
||||||
|
auto filter_markdown = Gtk::FileFilter::create();
|
||||||
|
filter_markdown->set_name("Markdown files (.md)");
|
||||||
|
filter_markdown->add_mime_type("text/markdown");
|
||||||
|
dialog->add_filter(filter_markdown);
|
||||||
|
|
||||||
|
auto filter_any = Gtk::FileFilter::create();
|
||||||
|
filter_any->set_name("Any files");
|
||||||
|
filter_any->add_pattern("*");
|
||||||
|
dialog->add_filter(filter_any);
|
||||||
|
|
||||||
|
dialog->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_open_dialog_response(int response_id, Gtk::FileChooserDialog *dialog)
|
||||||
|
{
|
||||||
|
switch (response_id)
|
||||||
|
{
|
||||||
|
case Gtk::ResponseType::RESPONSE_OK:
|
||||||
|
{
|
||||||
|
auto filename = dialog->get_file()->get_path();
|
||||||
|
std::cout << "TODO. File selected: " << filename << std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Gtk::ResponseType::RESPONSE_CANCEL:
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
std::cerr << "ERROR: Unexpected button clicked." << std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete dialog;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::save()
|
void MainWindow::save()
|
||||||
{
|
{
|
||||||
std::cout << "INFO: TODO" << std::endl;
|
if (currentFileSavedPath.empty())
|
||||||
|
{
|
||||||
|
this->save_as();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (this->isEditorEnabled())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
File::write(currentFileSavedPath, this->currentContent);
|
||||||
|
}
|
||||||
|
catch (std::ios_base::failure &e)
|
||||||
|
{
|
||||||
|
std::cerr << "ERROR: Could not write file: " << currentFileSavedPath << ". Error: " << e.what() << ".\nError code: " << e.code() << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cerr << "ERROR: Saving while \"file saved path\" is filled and editor is disabled should not happen!?" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::save_as()
|
void MainWindow::save_as()
|
||||||
{
|
{
|
||||||
std::cout << "INFO: TODO" << std::endl;
|
auto dialog = new Gtk::FileChooserDialog("Save", Gtk::FILE_CHOOSER_ACTION_SAVE);
|
||||||
|
dialog->set_transient_for(*this);
|
||||||
|
dialog->set_modal(true);
|
||||||
|
dialog->set_do_overwrite_confirmation(true);
|
||||||
|
dialog->signal_response().connect(sigc::bind(sigc::mem_fun(*this, &MainWindow::on_save_as_dialog_response), dialog));
|
||||||
|
dialog->add_button("_Cancel", Gtk::ResponseType::RESPONSE_CANCEL);
|
||||||
|
dialog->add_button("_Save", Gtk::ResponseType::RESPONSE_OK);
|
||||||
|
|
||||||
|
// Add filters, so that only certain file types can be selected:
|
||||||
|
auto filter_markdown = Gtk::FileFilter::create();
|
||||||
|
filter_markdown->set_name("Markdown files (.md)");
|
||||||
|
filter_markdown->add_mime_type("text/markdown");
|
||||||
|
dialog->add_filter(filter_markdown);
|
||||||
|
|
||||||
|
auto filter_any = Gtk::FileFilter::create();
|
||||||
|
filter_any->set_name("Any files");
|
||||||
|
filter_any->add_pattern("*");
|
||||||
|
dialog->add_filter(filter_any);
|
||||||
|
|
||||||
|
// If user is saving as an existing file, set the current uri path
|
||||||
|
if (!this->currentFileSavedPath.empty())
|
||||||
|
{
|
||||||
|
dialog->set_uri(Glib::filename_to_uri(currentFileSavedPath));
|
||||||
|
}
|
||||||
|
dialog->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_save_as_dialog_response(int response_id, Gtk::FileChooserDialog *dialog)
|
||||||
|
{
|
||||||
|
switch (response_id)
|
||||||
|
{
|
||||||
|
case Gtk::ResponseType::RESPONSE_OK:
|
||||||
|
{
|
||||||
|
auto filePath = dialog->get_file()->get_path();
|
||||||
|
if (!filePath.ends_with(".md"))
|
||||||
|
filePath.append(".md");
|
||||||
|
|
||||||
|
// Save current content to file path
|
||||||
|
try
|
||||||
|
{
|
||||||
|
File::write(filePath, this->currentContent);
|
||||||
|
|
||||||
|
// Set/update the current file saved path variable (used for the 'save' feature)
|
||||||
|
if (this->isEditorEnabled())
|
||||||
|
this->currentFileSavedPath = filePath;
|
||||||
|
}
|
||||||
|
catch (std::ios_base::failure &e)
|
||||||
|
{
|
||||||
|
std::cerr << "ERROR: Could not write file: " << filePath << ". Error: " << e.what() << ".\nError code: " << e.code() << std::endl;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Gtk::ResponseType::RESPONSE_CANCEL:
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
std::cerr << "ERROR: Unexpected button clicked." << std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete dialog;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::publish()
|
void MainWindow::publish()
|
||||||
|
@ -880,13 +1002,15 @@ void MainWindow::enableEdit()
|
||||||
this->m_draw_main.setViewSourceMenuItem(false);
|
this->m_draw_main.setViewSourceMenuItem(false);
|
||||||
// Connect changed signal
|
// Connect changed signal
|
||||||
this->textChangedSignalHandler = m_draw_main.get_buffer().get()->signal_changed().connect(sigc::mem_fun(this, &MainWindow::editor_changed_text));
|
this->textChangedSignalHandler = m_draw_main.get_buffer().get()->signal_changed().connect(sigc::mem_fun(this, &MainWindow::editor_changed_text));
|
||||||
|
// Enable publish button in menu
|
||||||
|
m_menu.setPublishMenuSensitive(true);
|
||||||
// Set new title
|
// Set new title
|
||||||
set_title("Untitled * - " + m_appName);
|
set_title("Untitled * - " + m_appName);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::disableEdit()
|
void MainWindow::disableEdit()
|
||||||
{
|
{
|
||||||
if (m_hboxStandardEditorToolbar.is_visible())
|
if (this->isEditorEnabled())
|
||||||
{
|
{
|
||||||
this->m_hboxStandardEditorToolbar.hide();
|
this->m_hboxStandardEditorToolbar.hide();
|
||||||
this->m_hboxFormattingEditorToolbar.hide();
|
this->m_hboxFormattingEditorToolbar.hide();
|
||||||
|
@ -896,11 +1020,24 @@ void MainWindow::disableEdit()
|
||||||
// Show "view source" menu item again
|
// Show "view source" menu item again
|
||||||
this->m_draw_main.setViewSourceMenuItem(true);
|
this->m_draw_main.setViewSourceMenuItem(true);
|
||||||
this->m_draw_secondary.clearText();
|
this->m_draw_secondary.clearText();
|
||||||
|
// Disable publish button in menu
|
||||||
|
this->m_menu.setPublishMenuSensitive(false);
|
||||||
|
// Empty current file saved path
|
||||||
|
this->currentFileSavedPath = "";
|
||||||
// Restore title
|
// Restore title
|
||||||
set_title(m_appName);
|
set_title(m_appName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Check if editor is enabled
|
||||||
|
* \return true if enabled, otherwise false
|
||||||
|
*/
|
||||||
|
bool MainWindow::isEditorEnabled()
|
||||||
|
{
|
||||||
|
return m_hboxStandardEditorToolbar.is_visible();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the file from disk or IPFS network, from the provided path,
|
* Get the file from disk or IPFS network, from the provided path,
|
||||||
* parse the content, and display the document
|
* parse the content, and display the document
|
||||||
|
@ -997,6 +1134,10 @@ void MainWindow::openFromDisk()
|
||||||
m_draw_main.processDocument(doc);
|
m_draw_main.processDocument(doc);
|
||||||
cmark_node_free(doc);
|
cmark_node_free(doc);
|
||||||
}
|
}
|
||||||
|
catch (const std::ios_base::failure &e)
|
||||||
|
{
|
||||||
|
std::cerr << "ERROR: Could not read file: " << finalRequestPath << ". Error: " << e.what() << ".\nError code: " << e.code() << std::endl;
|
||||||
|
}
|
||||||
catch (const std::runtime_error &error)
|
catch (const std::runtime_error &error)
|
||||||
{
|
{
|
||||||
std::cerr << "Error: File request failed, with message: " << error.what() << std::endl;
|
std::cerr << "Error: File request failed, with message: " << error.what() << std::endl;
|
||||||
|
@ -1039,10 +1180,11 @@ std::string MainWindow::getIconImageFromTheme(const std::string &iconName, const
|
||||||
void MainWindow::editor_changed_text()
|
void MainWindow::editor_changed_text()
|
||||||
{
|
{
|
||||||
// Retrieve text from text editor
|
// Retrieve text from text editor
|
||||||
std::string text = m_draw_main.getText();
|
currentContent = m_draw_main.getText();
|
||||||
// Parse the markdown contents
|
// Parse the markdown contents
|
||||||
cmark_node *doc = Parser::parseContent(text);
|
cmark_node *doc = Parser::parseContent(currentContent);
|
||||||
/*std::string md = Parser::renderMarkdown(doc);
|
/* Can be enabled to show the markdown format in terminal:
|
||||||
|
std::string md = Parser::renderMarkdown(doc);
|
||||||
std::cout << "Markdown:\n" << md << std::endl;*/
|
std::cout << "Markdown:\n" << md << std::endl;*/
|
||||||
|
|
||||||
// Show the document as a preview on the right side text-view panel
|
// Show the document as a preview on the right side text-view panel
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include <gtkmm/togglebutton.h>
|
#include <gtkmm/togglebutton.h>
|
||||||
#include <gtkmm/comboboxtext.h>
|
#include <gtkmm/comboboxtext.h>
|
||||||
#include <gtkmm/popover.h>
|
#include <gtkmm/popover.h>
|
||||||
|
#include <gtkmm/filechooserdialog.h>
|
||||||
#include <gtkmm/entry.h>
|
#include <gtkmm/entry.h>
|
||||||
#include <gtkmm/searchbar.h>
|
#include <gtkmm/searchbar.h>
|
||||||
#include <gtkmm/searchentry.h>
|
#include <gtkmm/searchentry.h>
|
||||||
|
@ -43,8 +44,10 @@ protected:
|
||||||
void selectAll();
|
void selectAll();
|
||||||
void new_doc();
|
void new_doc();
|
||||||
void open();
|
void open();
|
||||||
|
void on_open_dialog_response(int response_id, Gtk::FileChooserDialog* dialog);
|
||||||
void save();
|
void save();
|
||||||
void save_as();
|
void save_as();
|
||||||
|
void on_save_as_dialog_response(int response_id, Gtk::FileChooserDialog* dialog);
|
||||||
void publish();
|
void publish();
|
||||||
void go_home();
|
void go_home();
|
||||||
void show_status();
|
void show_status();
|
||||||
|
@ -155,6 +158,7 @@ private:
|
||||||
std::string requestPath;
|
std::string requestPath;
|
||||||
std::string finalRequestPath;
|
std::string finalRequestPath;
|
||||||
std::string currentContent;
|
std::string currentContent;
|
||||||
|
std::string currentFileSavedPath;
|
||||||
std::size_t currentHistoryIndex;
|
std::size_t currentHistoryIndex;
|
||||||
std::vector<std::string> history;
|
std::vector<std::string> history;
|
||||||
sigc::connection textChangedSignalHandler;
|
sigc::connection textChangedSignalHandler;
|
||||||
|
@ -164,6 +168,7 @@ private:
|
||||||
bool isInstalled();
|
bool isInstalled();
|
||||||
void enableEdit();
|
void enableEdit();
|
||||||
void disableEdit();
|
void disableEdit();
|
||||||
|
bool isEditorEnabled();
|
||||||
void postDoRequest(const std::string &path, bool setAddressBar, bool isHistoryRequest);
|
void postDoRequest(const std::string &path, bool setAddressBar, bool isHistoryRequest);
|
||||||
void processRequest(const std::string &path);
|
void processRequest(const std::string &path);
|
||||||
void fetchFromIPFS();
|
void fetchFromIPFS();
|
||||||
|
|
|
@ -19,7 +19,8 @@ Menu::Menu(const Glib::RefPtr<Gtk::AccelGroup> &accelgroup)
|
||||||
auto saveAsMenuItem = createMenuItem("Save _As...");
|
auto saveAsMenuItem = createMenuItem("Save _As...");
|
||||||
saveAsMenuItem->add_accelerator("activate", accelgroup, GDK_KEY_S, Gdk::ModifierType::CONTROL_MASK | Gdk::ModifierType::SHIFT_MASK, Gtk::AccelFlags::ACCEL_VISIBLE);
|
saveAsMenuItem->add_accelerator("activate", accelgroup, GDK_KEY_S, Gdk::ModifierType::CONTROL_MASK | Gdk::ModifierType::SHIFT_MASK, Gtk::AccelFlags::ACCEL_VISIBLE);
|
||||||
saveAsMenuItem->signal_activate().connect(save_as);
|
saveAsMenuItem->signal_activate().connect(save_as);
|
||||||
auto publishMenuItem = createMenuItem("_Publish...");
|
publishMenuItem = createMenuItem("_Publish...");
|
||||||
|
publishMenuItem->set_sensitive(false); // disable
|
||||||
publishMenuItem->add_accelerator("activate", accelgroup, GDK_KEY_P, Gdk::ModifierType::CONTROL_MASK, Gtk::AccelFlags::ACCEL_VISIBLE);
|
publishMenuItem->add_accelerator("activate", accelgroup, GDK_KEY_P, Gdk::ModifierType::CONTROL_MASK, Gtk::AccelFlags::ACCEL_VISIBLE);
|
||||||
publishMenuItem->signal_activate().connect(publish);
|
publishMenuItem->signal_activate().connect(publish);
|
||||||
auto quitMenuItem = createMenuItem("_Quit");
|
auto quitMenuItem = createMenuItem("_Quit");
|
||||||
|
@ -132,6 +133,11 @@ void Menu::setForwardMenuSensitive(bool sensitive)
|
||||||
forwardMenuItem->set_sensitive(sensitive);
|
forwardMenuItem->set_sensitive(sensitive);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Menu::setPublishMenuSensitive(bool sensitive)
|
||||||
|
{
|
||||||
|
publishMenuItem->set_sensitive(sensitive);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Helper method for creating a menu with an image
|
* \brief Helper method for creating a menu with an image
|
||||||
* \return GTKWidget menu item pointer
|
* \return GTKWidget menu item pointer
|
||||||
|
|
|
@ -40,6 +40,7 @@ public:
|
||||||
virtual ~Menu();
|
virtual ~Menu();
|
||||||
void setBackMenuSensitive(bool sensitive);
|
void setBackMenuSensitive(bool sensitive);
|
||||||
void setForwardMenuSensitive(bool sensitive);
|
void setForwardMenuSensitive(bool sensitive);
|
||||||
|
void setPublishMenuSensitive(bool sensitive);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Child widgets
|
// Child widgets
|
||||||
|
@ -62,5 +63,6 @@ private:
|
||||||
Gtk::MenuItem *createMenuItem(const Glib::ustring &label_text);
|
Gtk::MenuItem *createMenuItem(const Glib::ustring &label_text);
|
||||||
Gtk::MenuItem *backMenuItem;
|
Gtk::MenuItem *backMenuItem;
|
||||||
Gtk::MenuItem *forwardMenuItem;
|
Gtk::MenuItem *forwardMenuItem;
|
||||||
|
Gtk::MenuItem *publishMenuItem;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
Loading…
Reference in New Issue