Browse Source

Merge pull request #80 from eidheim/master

Singleton and config cleanup, also some minor fixes
merge-requests/365/head
Jørgen Lien Sellæg 10 years ago
parent
commit
45b3864d7a
  1. 16
      src/CMakeLists.txt
  2. 11
      src/cmake.cc
  3. 130
      src/config.cc
  4. 77
      src/config.h
  5. 33
      src/dialogs.cc
  6. 49
      src/dialogs.h
  7. 208
      src/dialogs_win.cc
  8. 7
      src/directories.cc
  9. 6
      src/directories.h
  10. 6
      src/files.h
  11. 40
      src/juci.cc
  12. 13
      src/juci.h
  13. 16
      src/menu.cc
  14. 6
      src/menu.h
  15. 26
      src/notebook.cc
  16. 1
      src/notebook.h
  17. 66
      src/singletons.cc
  18. 43
      src/singletons.h
  19. 49
      src/source.cc
  20. 28
      src/source.h
  21. 24
      src/source_clang.cc
  22. 1
      src/source_clang.h
  23. 12
      src/terminal.cc
  24. 8
      src/terminal.h
  25. 12
      src/terminal_win.cc
  26. 1
      src/tooltips.cc
  27. 134
      src/window.cc
  28. 8
      src/window.h

16
src/CMakeLists.txt

@ -16,11 +16,15 @@ if(UNIX) #Checking if compiling on Ubuntu that has a buggy menu system
execute_process(COMMAND ${LSB_RELEASE_BIN} -is
OUTPUT_VARIABLE DISTRIBUTION OUTPUT_STRIP_TRAILING_WHITESPACE)
if((DISTRIBUTION STREQUAL Ubuntu) OR (DISTRIBUTION STREQUAL LinuxMint))
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DUBUNTU_BUGGED_MENU")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DJUCI_UBUNTU_BUGGED_MENU")
endif()
endif()
endif()
if(MSYS)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DJUCI_CMAKE_INSTALL_PREFIX=\\\"${CMAKE_INSTALL_PREFIX}\\\"")
endif()
INCLUDE(FindPkgConfig)
find_package(LibClang REQUIRED)
@ -28,15 +32,7 @@ find_package(LibClang REQUIRED)
#find_package(PythonLibs 2.7)
#find_package(Boost 1.55 COMPONENTS python thread log system filesystem REQUIRED)
set(BOOST_DEP thread log system filesystem)
if(MSYS)
list(APPEND BOOST_DEP locale)
endif()
find_package(Boost 1.55 COMPONENTS ${BOOST_DEP} REQUIRED)
find_package(Boost 1.55 COMPONENTS thread log system filesystem REQUIRED)
pkg_check_modules(GTKMM gtkmm-3.0 REQUIRED) # The name GTKMM is set here for the variables abouve

11
src/cmake.cc

@ -1,5 +1,6 @@
#include "cmake.h"
#include "singletons.h"
#include "filesystem.h"
#include <regex>
#include <iostream> //TODO: remove
@ -19,7 +20,7 @@ CMake::CMake(const boost::filesystem::path &path) {
auto search_path=path;
auto search_cmake_path=search_path;
search_cmake_path/="CMakeLists.txt";
search_cmake_path+="/CMakeLists.txt";
if(boost::filesystem::exists(search_cmake_path))
paths.emplace(paths.begin(), search_cmake_path);
if(find_cmake_project(search_cmake_path))
@ -28,7 +29,7 @@ CMake::CMake(const boost::filesystem::path &path) {
do {
search_path=search_path.parent_path();
search_cmake_path=search_path;
search_cmake_path/="CMakeLists.txt";
search_cmake_path+="/CMakeLists.txt";
if(boost::filesystem::exists(search_cmake_path))
paths.emplace(paths.begin(), search_cmake_path);
if(find_cmake_project(search_cmake_path)) {
@ -44,11 +45,11 @@ CMake::CMake(const boost::filesystem::path &path) {
}
bool CMake::create_compile_commands(const boost::filesystem::path &path) {
Singleton::terminal()->print("Creating "+path.string()+"/compile_commands.json\n");
if(Singleton::terminal()->execute(Singleton::Config::terminal()->cmake_command+" . -DCMAKE_EXPORT_COMPILE_COMMANDS=ON", path)==EXIT_SUCCESS) {
Singleton::terminal->print("Creating "+path.string()+"/compile_commands.json\n");
if(Singleton::terminal->execute(Singleton::config->terminal.cmake_command+" . -DCMAKE_EXPORT_COMPILE_COMMANDS=ON", path)==EXIT_SUCCESS) {
#ifdef _WIN32 //Temporary fix to MSYS2's libclang
auto compile_commands_path=path;
compile_commands_path/="compile_commands.json";
compile_commands_path+="/compile_commands.json";
auto compile_commands_file=filesystem::read(compile_commands_path);
size_t pos=0;
while((pos=compile_commands_file.find("-I/", pos))!=std::string::npos) {

130
src/config.cc

@ -4,14 +4,32 @@
#include <exception>
#include "files.h"
#include <iostream>
#include "filesystem.h"
using namespace std; //TODO: remove
MainConfig::MainConfig() {
init_home_path();
Config::Config() {
std::vector<std::string> environment_variables = {"JUCI_HOME", "HOME", "AppData"};
char *ptr = nullptr;
for (auto &variable : environment_variables) {
ptr=std::getenv(variable.c_str());
if (ptr!=nullptr && boost::filesystem::exists(ptr)) {
home /= ptr;
home /= ".juci";
break;
}
}
if(home.empty()) {
std::string searched_envs = "[";
for(auto &variable : environment_variables)
searched_envs+=variable+", ";
searched_envs.erase(searched_envs.end()-2, searched_envs.end());
searched_envs+="]";
throw std::runtime_error("One of these environment variables needs to point to a writable directory to save configuration: " + searched_envs);
}
}
void MainConfig::read() {
void Config::load() {
auto config_json = (home/"config"/"config.json").string(); // This causes some redundant copies, but assures windows support
try {
find_or_create_config_files();
@ -20,7 +38,7 @@ void MainConfig::read() {
retrieve_config();
}
catch(const std::exception &e) {
Singleton::terminal()->print("Error reading "+config_json+": "+e.what()+"\n");
Singleton::terminal->print("Error reading "+config_json+": "+e.what()+"\n");
std::stringstream ss;
ss << configjson;
boost::property_tree::read_json(ss, cfg);
@ -29,7 +47,7 @@ void MainConfig::read() {
cfg.clear();
}
void MainConfig::find_or_create_config_files() {
void Config::find_or_create_config_files() {
auto config_dir = home/"config";
auto config_json = config_dir/"config.json";
auto plugins_py = config_dir/"plugins.py";
@ -57,25 +75,25 @@ void MainConfig::find_or_create_config_files() {
filesystem::write(juci_style_path, juci_dark_blue_style);
}
void MainConfig::retrieve_config() {
void Config::retrieve_config() {
auto keybindings_pt = cfg.get_child("keybindings");
for (auto &i : keybindings_pt) {
Singleton::Config::menu()->keys[i.first] = i.second.get_value<std::string>();
}
GenerateSource();
GenerateDirectoryFilter();
Singleton::Config::window()->theme_name=cfg.get<std::string>("gtk_theme.name");
Singleton::Config::window()->theme_variant=cfg.get<std::string>("gtk_theme.variant");
Singleton::Config::window()->version = cfg.get<std::string>("version");
Singleton::Config::window()->default_size = {cfg.get<int>("default_window_size.width"), cfg.get<int>("default_window_size.height")};
Singleton::Config::terminal()->make_command=cfg.get<std::string>("project.make_command");
Singleton::Config::terminal()->cmake_command=cfg.get<std::string>("project.cmake_command");
Singleton::Config::terminal()->clang_format_command=cfg.get<std::string>("project.clang_format_command", "clang-format");
Singleton::Config::terminal()->history_size=cfg.get<int>("terminal_history_size");
menu.keys[i.first] = i.second.get_value<std::string>();
}
get_source();
get_directory_filter();
window.theme_name=cfg.get<std::string>("gtk_theme.name");
window.theme_variant=cfg.get<std::string>("gtk_theme.variant");
window.version = cfg.get<std::string>("version");
window.default_size = {cfg.get<int>("default_window_size.width"), cfg.get<int>("default_window_size.height")};
terminal.make_command=cfg.get<std::string>("project.make_command");
terminal.cmake_command=cfg.get<std::string>("project.cmake_command");
terminal.clang_format_command=cfg.get<std::string>("project.clang_format_command", "clang-format");
terminal.history_size=cfg.get<int>("terminal_history_size");
}
bool MainConfig::check_config_file(const boost::property_tree::ptree &default_cfg, std::string parent_path) {
bool Config::check_config_file(const boost::property_tree::ptree &default_cfg, std::string parent_path) {
if(parent_path.size()>0)
parent_path+=".";
bool exists=true;
@ -97,7 +115,7 @@ bool MainConfig::check_config_file(const boost::property_tree::ptree &default_cf
return exists;
}
void MainConfig::update_config_file() {
void Config::update_config_file() {
boost::property_tree::ptree default_cfg;
bool cfg_ok=true;
try {
@ -122,77 +140,49 @@ void MainConfig::update_config_file() {
}
}
void MainConfig::GenerateSource() {
auto source_cfg = Singleton::Config::source();
void Config::get_source() {
auto source_json = cfg.get_child("source");
Singleton::Config::source()->style=source_json.get<std::string>("style");
source_cfg->font=source_json.get<std::string>("font");
source.style=source_json.get<std::string>("style");
source.font=source_json.get<std::string>("font");
source_cfg->show_map = source_json.get<bool>("show_map");
source_cfg->map_font_size = source_json.get<std::string>("map_font_size");
source.show_map = source_json.get<bool>("show_map");
source.map_font_size = source_json.get<std::string>("map_font_size");
source_cfg->spellcheck_language = source_json.get<std::string>("spellcheck_language");
source.spellcheck_language = source_json.get<std::string>("spellcheck_language");
source_cfg->default_tab_char = source_json.get<char>("default_tab_char");
source_cfg->default_tab_size = source_json.get<unsigned>("default_tab_size");
source_cfg->auto_tab_char_and_size = source_json.get<bool>("auto_tab_char_and_size");
source.default_tab_char = source_json.get<char>("default_tab_char");
source.default_tab_size = source_json.get<unsigned>("default_tab_size");
source.auto_tab_char_and_size = source_json.get<bool>("auto_tab_char_and_size");
source_cfg->wrap_lines = source_json.get<bool>("wrap_lines");
source.wrap_lines = source_json.get<bool>("wrap_lines");
source_cfg->highlight_current_line = source_json.get<bool>("highlight_current_line");
source_cfg->show_line_numbers = source_json.get<bool>("show_line_numbers");
source.highlight_current_line = source_json.get<bool>("highlight_current_line");
source.show_line_numbers = source_json.get<bool>("show_line_numbers");
for (auto &i : source_json.get_child("clang_types"))
source_cfg->clang_types[i.first] = i.second.get_value<std::string>();
source.clang_types[i.first] = i.second.get_value<std::string>();
source_cfg->clang_format_style = source_json.get<std::string>("clang_format_style");
source.clang_format_style = source_json.get<std::string>("clang_format_style");
auto pt_doc_search=cfg.get_child("documentation_searches");
for(auto &pt_doc_search_lang: pt_doc_search) {
source_cfg->documentation_searches[pt_doc_search_lang.first].separator=pt_doc_search_lang.second.get<std::string>("separator");
auto &queries=source_cfg->documentation_searches.find(pt_doc_search_lang.first)->second.queries;
source.documentation_searches[pt_doc_search_lang.first].separator=pt_doc_search_lang.second.get<std::string>("separator");
auto &queries=source.documentation_searches.find(pt_doc_search_lang.first)->second.queries;
for(auto &i: pt_doc_search_lang.second.get_child("queries")) {
queries[i.first]=i.second.get_value<std::string>();
}
}
}
void MainConfig::GenerateDirectoryFilter() {
auto dir_cfg=Singleton::Config::directories();
void Config::get_directory_filter() {
boost::property_tree::ptree dir_json = cfg.get_child("directoryfilter");
boost::property_tree::ptree ignore_json = dir_json.get_child("ignore");
boost::property_tree::ptree except_json = dir_json.get_child("exceptions");
dir_cfg->exceptions.clear();
dir_cfg->ignored.clear();
directories.exceptions.clear();
directories.ignored.clear();
for ( auto &i : except_json )
dir_cfg->exceptions.emplace_back(i.second.get_value<std::string>());
directories.exceptions.emplace_back(i.second.get_value<std::string>());
for ( auto &i : ignore_json )
dir_cfg->ignored.emplace_back(i.second.get_value<std::string>());
}
void MainConfig::init_home_path(){
std::vector<std::string> locations = JUCI_ENV_SEARCH_LOCATIONS;
char *ptr = nullptr;
for (auto &env : locations) {
ptr=std::getenv(env.c_str());
if (ptr==nullptr)
continue;
else
if (boost::filesystem::exists(ptr)) {
home /= ptr;
home /= ".juci";
break;
}
}
if(home.empty()) {
std::string searched_envs = "[";
for(auto &env : locations)
searched_envs+=env+", ";
searched_envs.erase(searched_envs.end()-2, searched_envs.end());
searched_envs+="]";
throw std::runtime_error("One of these environment variables needs to point to a writable directory to save configuration: " + searched_envs);
}
return;
directories.ignored.emplace_back(i.second.get_value<std::string>());
}

77
src/config.h

@ -3,11 +3,76 @@
#include <boost/property_tree/json_parser.hpp>
#include <boost/filesystem.hpp>
#include "menu.h"
#include <unordered_map>
#include <string>
#include <utility>
#include <vector>
class MainConfig {
class Config {
public:
MainConfig();
void read();
class Menu {
public:
std::unordered_map<std::string, std::string> keys;
};
class Window {
public:
std::string theme_name;
std::string theme_variant;
std::string version;
std::pair<int, int> default_size;
};
class Terminal {
public:
std::string cmake_command;
std::string make_command;
std::string clang_format_command;
int history_size;
};
class Directories {
public:
std::vector<std::string> ignored;
std::vector<std::string> exceptions;
};
class Source {
public:
class DocumentationSearch {
public:
std::string separator;
std::unordered_map<std::string, std::string> queries;
};
std::string style;
std::string font;
std::string spellcheck_language;
bool show_map;
std::string map_font_size;
bool auto_tab_char_and_size;
char default_tab_char;
unsigned default_tab_size;
bool wrap_lines;
bool highlight_current_line;
bool show_line_numbers;
std::unordered_map<std::string, std::string> clang_types;
std::string clang_format_style;
std::unordered_map<std::string, DocumentationSearch> documentation_searches;
};
Config();
void load();
Menu menu;
Window window;
Terminal terminal;
Directories directories;
Source source;
const boost::filesystem::path& juci_home_path() const { return home; }
private:
@ -15,11 +80,9 @@ private:
void retrieve_config();
bool check_config_file(const boost::property_tree::ptree &default_cfg, std::string parent_path="");
void update_config_file();
void PrintMenu();
void GenerateSource();
void GenerateDirectoryFilter();
void get_source();
void get_directory_filter();
void init_home_path();
boost::property_tree::ptree cfg;
boost::filesystem::path home;
};

33
src/dialogs.cc

@ -2,53 +2,58 @@
#include "singletons.h"
#include <gtkmm.h>
#include <vector>
#include "juci.h"
std::string open_dialog(const std::string &title,
const std::vector<std::pair<std::string, Gtk::ResponseType>> &buttons,
Gtk::FileChooserAction gtk_options,
const std::string &file_name = "") {
Gtk::FileChooserDialog dialog(title, gtk_options);
if(!Singleton::directories()->current_path.empty())
gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), Singleton::directories()->current_path.c_str());
if(!Singleton::directories->current_path.empty())
gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), Singleton::directories->current_path.string().c_str());
else
gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), boost::filesystem::current_path().c_str());
gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), boost::filesystem::current_path().string().c_str());
if (!file_name.empty())
gtk_file_chooser_set_filename((GtkFileChooser*)dialog.gobj(), file_name.c_str());
dialog.set_position(Gtk::WindowPosition::WIN_POS_CENTER_ALWAYS);
dialog.set_transient_for(*Singleton::window());
auto g_application=g_application_get_default(); //TODO: Post issue that Gio::Application::get_default should return pointer and not Glib::RefPtr
auto gio_application=Glib::wrap(g_application, true);
auto application=Glib::RefPtr<Application>::cast_static(gio_application);
dialog.set_transient_for(*application->window);
for (auto &button : buttons)
dialog.add_button(button.first, button.second);
return dialog.run() == Gtk::RESPONSE_OK ? dialog.get_filename() : "";
}
std::string Dialog::select_folder() {
return open_dialog("Please choose a folder",
std::string Dialog::open_folder() {
return open_dialog("Open Folder",
{std::make_pair("Cancel", Gtk::RESPONSE_CANCEL),std::make_pair("Open", Gtk::RESPONSE_OK)},
Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER);
}
std::string Dialog::new_file() {
return open_dialog("Please create a new file",
return open_dialog("New File",
{std::make_pair("Cancel", Gtk::RESPONSE_CANCEL), std::make_pair("Save", Gtk::RESPONSE_OK)},
Gtk::FILE_CHOOSER_ACTION_SAVE);
}
std::string Dialog::new_folder() {
return open_dialog("Please create a new folder",
return open_dialog("New Folder",
{std::make_pair("Cancel", Gtk::RESPONSE_CANCEL),std::make_pair("Create", Gtk::RESPONSE_OK)},
Gtk::FILE_CHOOSER_ACTION_CREATE_FOLDER);
}
std::string Dialog::select_file() {
return open_dialog("Please choose a file",
std::string Dialog::open_file() {
return open_dialog("Open File",
{std::make_pair("Cancel", Gtk::RESPONSE_CANCEL),std::make_pair("Select", Gtk::RESPONSE_OK)},
Gtk::FILE_CHOOSER_ACTION_OPEN);
}
std::string Dialog::save_file() {
return open_dialog("Please choose a file",
std::string Dialog::save_file_as(const boost::filesystem::path &file_path) {
return open_dialog("Save File As",
{std::make_pair("Cancel", Gtk::RESPONSE_CANCEL),std::make_pair("Save", Gtk::RESPONSE_OK)},
Gtk::FILE_CHOOSER_ACTION_SAVE,
Singleton::window()->notebook.get_current_view()->file_path.string());
Gtk::FILE_CHOOSER_ACTION_SAVE, file_path.string());
}

49
src/dialogs.h

@ -1,52 +1,15 @@
#ifndef JUCI_DIALOG_H_
#define JUCI_DIALOG_H_
#include <string>
#include <boost/filesystem.hpp>
class Dialog {
public:
static std::string select_folder();
static std::string select_file();
public:
static std::string open_folder();
static std::string open_file();
static std::string new_file();
static std::string new_folder();
static std::string save_file();
}; // Dialog
#ifdef _WIN32
#define NTDDI_VERSION NTDDI_VISTA
#define _WIN32_WINNT _WIN32_WINNT_VISTA
#include <windows.h>
#include <shobjidl.h>
#include <vector>
class CommonDialog {
public:
CommonDialog(CLSID type);
/** available options are listed https://msdn.microsoft.com/en-gb/library/windows/desktop/dn457282(v=vs.85).aspx */
void add_option(unsigned option);
void set_title(std::string &&title);
/** Sets the extensions the browser can find */
void set_default_file_extension(std::string &&file_extension);
/** Sets the directory to start browsing */
void set_default_folder(const std::string &directory_path);
/** Returns the selected item's path as a string */
std::string show();
protected:
IFileDialog * dialog;
DWORD options;
};
class OpenDialog : public CommonDialog {
public:
OpenDialog(std::string &&title, unsigned option);
};
class SaveDialog : public CommonDialog {
public:
SaveDialog(std::string &&title, unsigned option);
private:
std::vector<COMDLG_FILTERSPEC> extensions;
static std::string save_file_as(const boost::filesystem::path &file_path);
};
#endif // __WIN32
#endif // JUCI_DIALOG_H_
#endif //JUCI_DIALOG_H_

208
src/dialogs_win.cc

@ -1,94 +1,154 @@
#ifdef _WIN32
#include "dialogs.h"
#include "singletons.h"
#include <boost/locale.hpp>
#ifndef check
HRESULT __hr__;
#define check(__fun__, error_message) \
__hr__ = __fun__; \
if (FAILED(__hr__)) { \
Singleton::terminal()->print(error_message); \
throw std::runtime_error(error_message); \
}
#endif // CHECK
// { COMMON_DIALOG
CommonDialog::CommonDialog(CLSID type) : dialog(nullptr) {
check(CoCreateInstance(type, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&dialog)), "Failed to create instance");
check(dialog->GetOptions(&options), "Failed to get options from instance");
}
void CommonDialog::set_title(std::string &&title) {
auto ptr = boost::locale::conv::utf_to_utf<wchar_t>(title).data();
check(dialog->SetTitle(ptr), "Failed to set dialog title");
}
void CommonDialog::add_option(unsigned option) {
check(dialog->SetOptions(options | option), "Failed to set options");
}
void CommonDialog::set_default_file_extension(std::string &&file_extension) {
auto ptr = boost::locale::conv::utf_to_utf<wchar_t>(file_extension).data();
check(dialog->SetDefaultExtension(ptr), "Failed to set file extension");
}
void CommonDialog::set_default_folder(const std::string &directory_path) {
IShellItem * folder = nullptr;
auto ptr = boost::locale::conv::utf_to_utf<wchar_t>(directory_path).data();
check(SHCreateItemFromParsingName(ptr, nullptr, IID_PPV_ARGS(&folder)), "Failed to create string");
check(dialog->SetDefaultFolder(folder), "Failed to set default folder");
#undef NTDDI_VERSION
#define NTDDI_VERSION NTDDI_VISTA
#undef _WIN32_WINNT
#define _WIN32_WINNT _WIN32_WINNT_VISTA
#include <windows.h>
#include <shobjidl.h>
#include <vector>
#include <iostream> //TODO: remove
using namespace std; //TODO: remove
class Win32Dialog {
public:
Win32Dialog() {};
~Win32Dialog() {
if(dialog!=nullptr)
dialog->Release();
}
/** Returns the selected item's path as a string */
std::string open(const std::wstring &title, unsigned option=0) {
if(!init(CLSID_FileOpenDialog))
return "";
if(!set_title(title) || !add_option(option))
return "";
auto dirs = Singleton::directories->current_path;
if(!set_folder(dirs.empty() ? boost::filesystem::current_path().native() : dirs.native()))
return "";
return show();
}
std::string save(const std::wstring &title, const boost::filesystem::path &file_path="", unsigned option=0) {
if(!init(CLSID_FileSaveDialog))
return "";
if(!set_title(title) || !add_option(option))
return "";
std::vector<COMDLG_FILTERSPEC> extensions;
if(!file_path.empty()) {
if(!set_folder(file_path.parent_path().native()))
return "";
if(file_path.has_extension() && file_path.filename()!=file_path.extension()) {
auto extension=(L"*"+file_path.extension().native()).c_str();
extensions.emplace_back(COMDLG_FILTERSPEC{extension, extension});
if(!set_default_file_extension(extension))
return "";
}
}
else {
auto dirs = Singleton::directories->current_path;
if(!set_folder(dirs.empty() ? boost::filesystem::current_path().native() : dirs.native()))
return "";
}
extensions.emplace_back(COMDLG_FILTERSPEC{L"All files", L"*.*"});
if(dialog->SetFileTypes(extensions.size(), extensions.data())!=S_OK)
return "";
return show();
}
private:
IFileDialog *dialog=nullptr;
DWORD options;
bool init(CLSID type) {
if(CoCreateInstance(type, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&dialog))!=S_OK)
return false;
if(dialog->GetOptions(&options)!=S_OK)
return false;
return true;
}
/** available options are listed at https://msdn.microsoft.com/en-gb/library/windows/desktop/dn457282(v=vs.85).aspx */
bool add_option(unsigned option) {
if(dialog->SetOptions(options | option)!=S_OK)
return false;
return true;
}
bool set_title(const std::wstring &title) {
if(dialog->SetTitle(title.c_str())!=S_OK)
return false;
return true;
}
/** Sets the extensions the browser can find */
bool set_default_file_extension(const std::wstring &file_extension) {
if(dialog->SetDefaultExtension(file_extension.c_str())!=S_OK)
return false;
return true;
}
/** Sets the directory to start browsing */
bool set_folder(const std::wstring &directory_path) {
std::wstring path=directory_path;
size_t pos=0;
while((pos=path.find(L'/', pos))!=std::wstring::npos) {//TODO: issue bug report on boost::filesystem::path::native on MSYS2
path.replace(pos, 1, L"\\");
pos++;
}
IShellItem *folder = nullptr;
if(SHCreateItemFromParsingName(path.c_str(), nullptr, IID_PPV_ARGS(&folder))!=S_OK)
return false;
if(dialog->SetFolder(folder)!=S_OK)
return false;
folder->Release();
}
std::string CommonDialog::show() {
try {
check(dialog->Show(nullptr), "Failed to show dialog");
return true;
}
std::string show() {
if(dialog->Show(nullptr)!=S_OK)
return "";
IShellItem *result = nullptr;
check(dialog->GetResult(&result), "Failed to get result from dialog");
LPWSTR str = nullptr;
check(result->GetDisplayName(SIGDN_FILESYSPATH, &str), "Failed to get display name from dialog");
if(dialog->GetResult(&result)!=S_OK)
return "";
LPWSTR file_path = nullptr;
auto hresult=result->GetDisplayName(SIGDN_FILESYSPATH, &file_path);
result->Release();
auto res = boost::locale::conv::utf_to_utf<char>(str);
CoTaskMemFree(str);
return res;
} catch (std::exception e) {
if(hresult!=S_OK)
return "";
std::wstring file_path_wstring(file_path);
std::string file_path_string(file_path_wstring.begin(), file_path_wstring.end());
CoTaskMemFree(file_path);
return file_path_string;
}
}
OpenDialog::OpenDialog(std::string &&title, unsigned option) : CommonDialog(CLSID_FileOpenDialog) {
set_title(std::move(title));
add_option(option);
auto dirs = Singleton::directories()->current_path;
set_default_folder(dirs.empty() ? boost::filesystem::current_path().string() : dirs.string());
}
SaveDialog::SaveDialog(std::string &&title, unsigned option) : CommonDialog(CLSID_FileSaveDialog) {
set_title(std::move(title));
add_option(option);
auto dirs = Singleton::directories()->current_path;
set_default_folder(dirs.empty() ? boost::filesystem::current_path().string() : dirs.string());
extensions.emplace_back(COMDLG_FILTERSPEC{L"Default", L"*.h;*.cpp"});
extensions.emplace_back(COMDLG_FILTERSPEC{L"GoogleStyle", L"*.cc;*.h"});
extensions.emplace_back(COMDLG_FILTERSPEC{L"BoostStyle", L"*.hpp;*.cpp"});
extensions.emplace_back(COMDLG_FILTERSPEC{L"Other", L"*.cxx;*.c"});
check(dialog->SetFileTypes(extensions.size(), extensions.data()), "Failed to set extensions");
set_default_file_extension("Default");
}
};
// DIALOGS }}
std::string Dialog::select_folder() {
return (OpenDialog("Select folder", FOS_PICKFOLDERS)).show();
std::string Dialog::open_folder() {
return Win32Dialog().open(L"Open Folder", FOS_PICKFOLDERS);
}
std::string Dialog::new_file() {
return (SaveDialog("Please choose your destination", 0)).show();
return Win32Dialog().save(L"New File");
}
std::string Dialog::new_folder() {
return Dialog::select_folder();
return Win32Dialog().open(L"New Folder", FOS_PICKFOLDERS); //TODO: this is not working correctly yet
}
std::string Dialog::select_file() {
return (OpenDialog("Open file", 0)).show();
std::string Dialog::open_file() {
return Win32Dialog().open(L"Open File");
}
std::string Dialog::save_file() {
return (SaveDialog("Please choose your destination", 0)).show();
std::string Dialog::save_file_as(const boost::filesystem::path &file_path) {
return Win32Dialog().save(L"Save File As", file_path);
}
#endif

7
src/directories.cc

@ -1,8 +1,8 @@
#include "singletons.h"
#include "directories.h"
#include "logging.h"
#include <algorithm>
#include <unordered_set>
#include "source.h"
#include <iostream> //TODO: remove
using namespace std; //TODO: remove
@ -22,7 +22,6 @@ namespace sigc {
}
Directories::Directories() : stop_update_thread(false) {
JDEBUG("start");
add(tree_view);
set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
tree_store = Gtk::TreeStore::create(column_record);
@ -201,11 +200,11 @@ void Directories::select(const boost::filesystem::path &path) {
bool Directories::ignored(std::string path) {
std::transform(path.begin(), path.end(), path.begin(), ::tolower);
for(std::string &i : Singleton::Config::directories()->exceptions) {
for(std::string &i : Singleton::config->directories.exceptions) {
if(i == path)
return false;
}
for(auto &i : Singleton::Config::directories()->ignored) {
for(auto &i : Singleton::config->directories.ignored) {
if(path.find(i, 0) != std::string::npos)
return true;
}

6
src/directories.h

@ -12,12 +12,6 @@
class Directories : public Gtk::ScrolledWindow {
public:
class Config {
public:
std::vector<std::string> ignored;
std::vector<std::string> exceptions;
};
class ColumnRecord : public Gtk::TreeModel::ColumnRecord {
public:
ColumnRecord() {

6
src/files.h

@ -2,8 +2,6 @@
#define JUCI_VERSION "0.9.4"
#define JUCI_ENV_SEARCH_LOCATIONS {"AppData", "HOME", "JUCI_HOME"}
const std::string configjson =
"{\n"
" \"version\": \""+std::string(JUCI_VERSION)+"\",\n"
@ -58,7 +56,7 @@ const std::string configjson =
" \"705\": \"def:comment\"\n"
" },\n"
" \"clang_format_style_comment\": \"IndentWidth, AccessModifierOffset and UseTab are set automatically. See http://clang.llvm.org/docs/ClangFormatStyleOptions.html\",\n"
" \"clang_format_style\": \"ColumnLimit: 0\"\n"
" \"clang_format_style\": \"ColumnLimit: 0, MaxEmptyLinesToKeep: 2\"\n"
" },\n"
" \"keybindings\": {\n"
" \"preferences\": \"<primary>comma\",\n"
@ -100,7 +98,7 @@ const std::string configjson =
" },\n"
" \"project\": {\n"
#ifdef _WIN32
" \"cmake_command\": \"cmake -G\\\"MSYS Makefiles\\\"\",\n"
" \"cmake_command\": \"cmake -G\\\"MSYS Makefiles\\\" -DCMAKE_INSTALL_PREFIX="+JUCI_CMAKE_INSTALL_PREFIX+"\",\n"
#else
" \"cmake_command\": \"cmake\",\n"
#endif

40
src/juci.cc

@ -3,15 +3,15 @@
using namespace std; //TODO: remove
void app::init_logging() {
void Application::init_logging() {
boost::log::add_common_attributes();
auto log_dir = Singleton::Config::main()->juci_home_path()/"log"/"juci.log";
auto log_dir = Singleton::config->juci_home_path()/"log"/"juci.log";
boost::log::add_file_log(boost::log::keywords::file_name = log_dir,
boost::log::keywords::auto_flush = true);
JINFO("Logging initalized");
}
int app::on_command_line(const Glib::RefPtr<Gio::ApplicationCommandLine> &cmd) {
int Application::on_command_line(const Glib::RefPtr<Gio::ApplicationCommandLine> &cmd) {
Glib::set_prgname("juci");
Glib::OptionContext ctx("[PATH ...]");
Glib::OptionGroup gtk_group(gtk_get_option_group(true));
@ -37,13 +37,13 @@ int app::on_command_line(const Glib::RefPtr<Gio::ApplicationCommandLine> &cmd) {
return 0;
}
void app::on_activate() {
add_window(*Singleton::window());
Singleton::window()->show();
void Application::on_activate() {
add_window(*window);
window->show();
bool first_directory=true;
for(auto &directory: directories) {
if(first_directory) {
Singleton::directories()->open(directory);
Singleton::directories->open(directory);
first_directory=false;
}
else {
@ -57,25 +57,25 @@ void app::on_activate() {
it++;
}
std::thread another_juci_app([this, directory, files_in_directory](){
Singleton::terminal()->async_print("Executing: juci "+directory.string()+files_in_directory);
Singleton::terminal()->execute("juci "+directory.string()+files_in_directory, "", false);
Singleton::terminal->async_print("Executing: juci "+directory.string()+files_in_directory);
Singleton::terminal->execute("juci "+directory.string()+files_in_directory, "", false);
});
another_juci_app.detach();
}
}
for(auto &file: files)
Singleton::window()->notebook.open(file);
window->notebook.open(file);
}
void app::on_startup() {
void Application::on_startup() {
Gtk::Application::on_startup();
Singleton::menu()->init();
Singleton::menu()->build();
Singleton::menu->init();
Singleton::menu->build();
auto object = Singleton::menu()->builder->get_object("juci-menu");
auto object = Singleton::menu->builder->get_object("juci-menu");
auto juci_menu = Glib::RefPtr<Gio::Menu>::cast_dynamic(object);
object = Singleton::menu()->builder->get_object("window-menu");
object = Singleton::menu->builder->get_object("window-menu");
auto window_menu = Glib::RefPtr<Gio::Menu>::cast_dynamic(object);
if (!juci_menu || !window_menu) {
std::cerr << "Menu not found." << std::endl;
@ -86,13 +86,15 @@ void app::on_startup() {
}
}
app::app() : Gtk::Application("no.sout.juci", Gio::APPLICATION_NON_UNIQUE | Gio::APPLICATION_HANDLES_COMMAND_LINE) {
Application::Application() : Gtk::Application("no.sout.juci", Gio::APPLICATION_NON_UNIQUE | Gio::APPLICATION_HANDLES_COMMAND_LINE) {
Singleton::init();
init_logging();
Glib::set_application_name("juCi++");
Singleton::menu()->application=static_cast<Gtk::Application*>(this); //For Ubuntu 14...
Singleton::window();
window=std::unique_ptr<Window>(new Window());
}
int main(int argc, char *argv[]) {
return app().run(argc, argv);
return Application().run(argc, argv);
}

13
src/juci.h

@ -1,17 +1,18 @@
#ifndef JUCI_JUCI_H_
#define JUCI_JUCI_H_
#include "window.h"
#include <gtkmm.h>
#include "logging.h"
#include "window.h"
class app : public Gtk::Application {
public:
app();
class Application : public Gtk::Application {
public:
Application();
int on_command_line(const Glib::RefPtr<Gio::ApplicationCommandLine> &cmd);
void on_activate();
void on_startup();
private:
std::unique_ptr<Window> window;
private:
std::vector<boost::filesystem::path> directories;
std::vector<boost::filesystem::path> files;
void init_logging();

16
src/menu.cc

@ -10,9 +10,9 @@ Menu::Menu() {
//TODO: if Ubuntu ever gets fixed, move to constructor, also cleanup the rest of the Ubuntu specific code
void Menu::init() {
auto accels=Singleton::Config::menu()->keys;
auto accels=Singleton::config->menu.keys;
for(auto &accel: accels) {
#ifdef UBUNTU_BUGGED_MENU
#ifdef JUCI_UBUNTU_BUGGED_MENU
size_t pos=0;
std::string second=accel.second;
while((pos=second.find('<', pos))!=std::string::npos) {
@ -69,7 +69,7 @@ void Menu::init() {
+accels["new_file"]+ //For Ubuntu...
" </item>"
" <item>"
" <attribute name='label' translatable='yes'>_New _Directory</attribute>"
" <attribute name='label' translatable='yes'>_New _Folder</attribute>"
" <attribute name='action'>app.new_folder</attribute>"
+accels["new_folder"]+ //For Ubuntu...
" </item>"
@ -295,11 +295,19 @@ void Menu::init() {
}
void Menu::add_action(const std::string &name, std::function<void()> action) {
auto g_application=g_application_get_default();
auto gio_application=Glib::wrap(g_application, true);
auto application=Glib::RefPtr<Gtk::Application>::cast_static(gio_application);
actions[name]=application->add_action(name, action);
}
void Menu::set_keys() {
for(auto &key: Singleton::Config::menu()->keys) {
auto g_application=g_application_get_default();
auto gio_application=Glib::wrap(g_application, true);
auto application=Glib::RefPtr<Gtk::Application>::cast_static(gio_application);
for(auto &key: Singleton::config->menu.keys) {
if(key.second.size()>0 && actions.find(key.first)!=actions.end()) {
#if GTK_VERSION_GE(3, 12)
application->set_accel_for_action("app."+key.first, key.second);

6
src/menu.h

@ -7,14 +7,8 @@
class Menu {
public:
class Config {
public:
std::unordered_map<std::string, std::string> keys;
};
Menu();
void init(); //For Ubuntu 14...
Gtk::Application* application; //For Ubuntu 14...
void add_action(const std::string &name, std::function<void()> action);
std::unordered_map<std::string, Glib::RefPtr<Gio::SimpleAction> > actions;

26
src/notebook.cc

@ -4,6 +4,7 @@
#include <fstream>
#include <regex>
#include "cmake.h"
#include "filesystem.h"
#if GTKSOURCEVIEWMM_MAJOR_VERSION > 2 & GTKSOURCEVIEWMM_MINOR_VERSION > 17
#include "gtksourceview-3.0/gtksourceview/gtksourcemap.h"
@ -66,14 +67,14 @@ void Notebook::open(const boost::filesystem::path &file_path) {
std::ifstream can_read(file_path.string());
if(!can_read) {
Singleton::terminal()->print("Error: could not open "+file_path.string()+"\n");
Singleton::terminal->print("Error: could not open "+file_path.string()+"\n");
return;
}
can_read.close();
auto language=Source::guess_language(file_path);
boost::filesystem::path project_path;
auto directories=Singleton::directories();
auto &directories=Singleton::directories;
if(directories->cmake && directories->cmake->project_path!="" && file_path.generic_string().substr(0, directories->cmake->project_path.generic_string().size()+1)==directories->cmake->project_path.generic_string()+'/')
project_path=directories->cmake->project_path;
else {
@ -81,7 +82,7 @@ void Notebook::open(const boost::filesystem::path &file_path) {
CMake cmake(project_path);
if(cmake.project_path!="") {
project_path=cmake.project_path;
Singleton::terminal()->print("Project path for "+file_path.string()+" set to "+project_path.string()+"\n");
Singleton::terminal->print("Project path for "+file_path.string()+" set to "+project_path.string()+"\n");
}
}
if(language && (language->get_id()=="chdr" || language->get_id()=="cpphdr" || language->get_id()=="c" || language->get_id()=="cpp" || language->get_id()=="objc")) {
@ -94,11 +95,11 @@ void Notebook::open(const boost::filesystem::path &file_path) {
source_views.back()->on_update_status=[this](Source::View* view, const std::string &status) {
if(get_current_page()!=-1 && get_current_view()==view)
Singleton::status()->set_text(status+" ");
Singleton::status->set_text(status+" ");
};
source_views.back()->on_update_info=[this](Source::View* view, const std::string &info) {
if(get_current_page()!=-1 && get_current_view()==view)
Singleton::info()->set_text(" "+info);
Singleton::info->set_text(" "+info);
};
scrolled_windows.emplace_back(new Gtk::ScrolledWindow());
@ -149,10 +150,10 @@ void Notebook::open(const boost::filesystem::path &file_path) {
void Notebook::configure(int view_nr) {
#if GTKSOURCEVIEWMM_MAJOR_VERSION > 2 & GTKSOURCEVIEWMM_MINOR_VERSION > 17
auto source_font_description=Pango::FontDescription(Singleton::Config::source()->font);
auto source_map_font_desc=Pango::FontDescription(static_cast<std::string>(source_font_description.get_family())+" "+Singleton::Config::source()->map_font_size);
auto source_font_description=Pango::FontDescription(Singleton::config->source.font);
auto source_map_font_desc=Pango::FontDescription(static_cast<std::string>(source_font_description.get_family())+" "+Singleton::config->source.map_font_size);
source_maps.at(view_nr)->override_font(source_map_font_desc);
if(Singleton::Config::source()->show_map) {
if(Singleton::config->source.show_map) {
if(hboxes.at(view_nr)->get_children().size()==1)
hboxes.at(view_nr)->pack_end(*source_maps.at(view_nr), Gtk::PACK_SHRINK);
}
@ -184,12 +185,11 @@ bool Notebook::save(int page, bool reparse_needed) {
}
view->get_buffer()->set_modified(false);
Singleton::terminal()->print("File saved to: " +view->file_path.string()+"\n");
//If CMakeLists.txt have been modified:
boost::filesystem::path project_path;
if(view->file_path.filename()=="CMakeLists.txt") {
auto directories=Singleton::directories();
auto &directories=Singleton::directories;
if(directories->cmake && directories->cmake->project_path!="" && view->file_path.generic_string().substr(0, directories->cmake->project_path.generic_string().size()+1)==directories->cmake->project_path.generic_string()+'/' && CMake::create_compile_commands(directories->cmake->project_path)) {
project_path=directories->cmake->project_path;
}
@ -204,9 +204,9 @@ bool Notebook::save(int page, bool reparse_needed) {
if(auto source_clang_view=dynamic_cast<Source::ClangView*>(source_view)) {
if(project_path==source_clang_view->project_path) {
if(source_clang_view->restart_parse())
Singleton::terminal()->async_print("Reparsing "+source_clang_view->file_path.string()+"\n");
Singleton::terminal->async_print("Reparsing "+source_clang_view->file_path.string()+"\n");
else
Singleton::terminal()->async_print("Error: failed to reparse "+source_clang_view->file_path.string()+". Please reopen the file manually.\n");
Singleton::terminal->async_print("Error: failed to reparse "+source_clang_view->file_path.string()+". Please reopen the file manually.\n");
}
}
}
@ -215,7 +215,7 @@ bool Notebook::save(int page, bool reparse_needed) {
JDEBUG("end true");
return true;
}
Singleton::terminal()->print("Error: could not save file " +view->file_path.string()+"\n");
Singleton::terminal->print("Error: could not save file " +view->file_path.string()+"\n");
}
JDEBUG("end false");
return false;

1
src/notebook.h

@ -8,7 +8,6 @@
#include <type_traits>
#include <map>
#include <sigc++/sigc++.h>
#include "directories.h"
class Notebook : public Gtk::Notebook {
public:

66
src/singletons.cc

@ -1,52 +1,20 @@
#include "singletons.h"
std::unique_ptr<Source::Config> Singleton::Config::source_=std::unique_ptr<Source::Config>(new Source::Config());
std::unique_ptr<Directories::Config> Singleton::Config::directories_=std::unique_ptr<Directories::Config>(new Directories::Config());
std::unique_ptr<Terminal::Config> Singleton::Config::terminal_=std::unique_ptr<Terminal::Config>(new Terminal::Config());
std::unique_ptr<Window::Config> Singleton::Config::window_ = std::unique_ptr<Window::Config>(new Window::Config());
std::unique_ptr<MainConfig> Singleton::Config::main_=std::unique_ptr<MainConfig>(new MainConfig());
std::unique_ptr<Menu::Config> Singleton::Config::menu_ = std::unique_ptr<Menu::Config>(new Menu::Config());
std::unique_ptr<Terminal> Singleton::terminal_=std::unique_ptr<Terminal>();
Terminal *Singleton::terminal() {
if(!terminal_)
terminal_=std::unique_ptr<Terminal>(new Terminal());
return terminal_.get();
}
std::unique_ptr<Directories> Singleton::directories_=std::unique_ptr<Directories>();
Directories *Singleton::directories() {
if(!directories_)
directories_=std::unique_ptr<Directories>(new Directories());
return directories_.get();
}
std::unique_ptr<Window> Singleton::window_=std::unique_ptr<Window>();
Window *Singleton::window() {
if(!window_)
window_=std::unique_ptr<Window>(new Window());
return window_.get();
}
std::unique_ptr<Gtk::Label> Singleton::status_=std::unique_ptr<Gtk::Label>();
Gtk::Label *Singleton::status() {
if(!status_)
status_=std::unique_ptr<Gtk::Label>(new Gtk::Label());
return status_.get();
}
std::unique_ptr<Gtk::Label> Singleton::info_=std::unique_ptr<Gtk::Label>();
Gtk::Label *Singleton::info() {
if(!info_)
info_=std::unique_ptr<Gtk::Label>(new Gtk::Label());
return info_.get();
}
std::unique_ptr<Menu> Singleton::menu_=std::unique_ptr<Menu>();
Menu *Singleton::menu() {
if(!menu_)
menu_=std::unique_ptr<Menu>(new Menu());
return menu_.get();
#include <iostream> //TODO: remove
using namespace std; //TODO: remove
std::unique_ptr<Config> Singleton::config;
std::unique_ptr<Menu> Singleton::menu;
std::unique_ptr<Terminal> Singleton::terminal;
std::unique_ptr<Directories> Singleton::directories;
std::unique_ptr<Gtk::Label> Singleton::info;
std::unique_ptr<Gtk::Label> Singleton::status;
void Singleton::init() {
config=std::unique_ptr<Config>(new Config());
menu=std::unique_ptr<Menu>(new Menu());
terminal=std::unique_ptr<Terminal>(new Terminal());
directories=std::unique_ptr<Directories>(new Directories());
info=std::unique_ptr<Gtk::Label>(new Gtk::Label());
status=std::unique_ptr<Gtk::Label>(new Gtk::Label());
}

43
src/singletons.h

@ -2,50 +2,21 @@
#define JUCI_SINGLETONS_H_
#include <gtkmm.h>
#include "filesystem.h"
#include "source.h"
#include "window.h"
#include "directories.h"
#include "terminal.h"
#include "notebook.h"
#include "menu.h"
#include "window.h"
#include "config.h"
class Singleton {
public:
class Config {
public:
static Source::Config *source() {return source_.get();}
static Directories::Config *directories() {return directories_.get();}
static Window::Config *window() { return window_.get(); }
static Terminal::Config *terminal() {return terminal_.get();}
static Menu::Config *menu() {return menu_.get();}
static MainConfig *main() { return main_.get(); }
private:
static std::unique_ptr<Source::Config> source_;
static std::unique_ptr<Window::Config> window_;
static std::unique_ptr<Directories::Config> directories_;
static std::unique_ptr<Terminal::Config> terminal_;
static std::unique_ptr<Menu::Config> menu_;
static std::unique_ptr<MainConfig> main_;
};
static Terminal *terminal();
static Directories *directories();
static Gtk::Label *status();
static Gtk::Label *info();
static Menu *menu();
static Window *window();
static std::unique_ptr<Config> config;
static std::unique_ptr<Menu> menu;
static std::unique_ptr<Terminal> terminal;
static std::unique_ptr<Directories> directories;
static std::unique_ptr<Gtk::Label> info;
static std::unique_ptr<Gtk::Label> status;
private:
static std::unique_ptr<Terminal> terminal_;
static std::unique_ptr<Gtk::Label> status_;
static std::unique_ptr<Gtk::Label> info_;
static std::unique_ptr<Directories> directories_;
static std::unique_ptr<Menu> menu_;
static std::unique_ptr<Window> window_;
static void init();
};
#endif // JUCI_SINGLETONS_H_

49
src/source.cc

@ -5,6 +5,7 @@
#include <algorithm>
#include <gtksourceview/gtksource.h>
#include <iostream>
#include "filesystem.h"
using namespace std; //TODO: remove
@ -86,11 +87,11 @@ Source::View::View(const boost::filesystem::path &file_path, const boost::filesy
get_source_buffer()->begin_not_undoable_action();
if(language) {
if(filesystem::read_non_utf8(file_path, get_buffer())==-1)
Singleton::terminal()->print("Warning: "+file_path.string()+" is not a valid UTF-8 file. Saving might corrupt the file.\n");
Singleton::terminal->print("Warning: "+file_path.string()+" is not a valid UTF-8 file. Saving might corrupt the file.\n");
}
else {
if(filesystem::read(file_path, get_buffer())==-1)
Singleton::terminal()->print("Error: "+file_path.string()+" is not a valid UTF-8 file.\n");
Singleton::terminal->print("Error: "+file_path.string()+" is not a valid UTF-8 file.\n");
}
get_source_buffer()->end_not_undoable_action();
@ -262,9 +263,9 @@ Source::View::View(const boost::filesystem::path &file_path, const boost::filesy
set_tooltip_events();
tab_char=Singleton::Config::source()->default_tab_char;
tab_size=Singleton::Config::source()->default_tab_size;
if(Singleton::Config::source()->auto_tab_char_and_size) {
tab_char=Singleton::config->source.default_tab_char;
tab_size=Singleton::config->source.default_tab_size;
if(Singleton::config->source.auto_tab_char_and_size) {
auto tab_char_and_size=find_tab_char_and_size();
if(tab_char_and_size.first!=0) {
if(tab_char!=tab_char_and_size.first || tab_size!=tab_char_and_size.second) {
@ -273,7 +274,7 @@ Source::View::View(const boost::filesystem::path &file_path, const boost::filesy
tab_str="<space>";
else
tab_str="<tab>";
Singleton::terminal()->print("Tab char and size for file "+file_path.string()+" set to: "+tab_str+", "+std::to_string(tab_char_and_size.second)+".\n");
Singleton::terminal->print("Tab char and size for file "+file_path.string()+" set to: "+tab_str+", "+std::to_string(tab_char_and_size.second)+".\n");
}
tab_char=tab_char_and_size.first;
@ -295,25 +296,25 @@ void Source::View::set_tab_char_and_size(char tab_char, unsigned tab_size) {
void Source::View::configure() {
//TODO: Move this to notebook? Might take up too much memory doing this for every tab.
auto style_scheme_manager=Gsv::StyleSchemeManager::get_default();
style_scheme_manager->prepend_search_path((Singleton::Config::main()->juci_home_path()/"styles").string());
style_scheme_manager->prepend_search_path((Singleton::config->juci_home_path()/"styles").string());
if(Singleton::Config::source()->style.size()>0) {
auto scheme = style_scheme_manager->get_scheme(Singleton::Config::source()->style);
if(Singleton::config->source.style.size()>0) {
auto scheme = style_scheme_manager->get_scheme(Singleton::config->source.style);
if(scheme)
get_source_buffer()->set_style_scheme(scheme);
else
Singleton::terminal()->print("Error: Could not find gtksourceview style: "+Singleton::Config::source()->style+'\n');
Singleton::terminal->print("Error: Could not find gtksourceview style: "+Singleton::config->source.style+'\n');
}
if(Singleton::Config::source()->wrap_lines)
if(Singleton::config->source.wrap_lines)
set_wrap_mode(Gtk::WrapMode::WRAP_CHAR);
else
set_wrap_mode(Gtk::WrapMode::WRAP_NONE);
property_highlight_current_line() = Singleton::Config::source()->highlight_current_line;
property_show_line_numbers() = Singleton::Config::source()->show_line_numbers;
if(Singleton::Config::source()->font.size()>0)
override_font(Pango::FontDescription(Singleton::Config::source()->font));
property_highlight_current_line() = Singleton::config->source.highlight_current_line;
property_show_line_numbers() = Singleton::config->source.show_line_numbers;
if(Singleton::config->source.font.size()>0)
override_font(Pango::FontDescription(Singleton::config->source.font));
#if GTKSOURCEVIEWMM_MAJOR_VERSION > 2 & GTKSOURCEVIEWMM_MINOR_VERSION > 15
gtk_source_view_set_background_pattern(this->gobj(), GTK_SOURCE_BACKGROUND_PATTERN_TYPE_GRID);
#endif
@ -370,8 +371,8 @@ void Source::View::configure() {
note_tag->property_foreground()=style->property_foreground();
}
if(Singleton::Config::source()->spellcheck_language.size()>0)
aspell_config_replace(spellcheck_config, "lang", Singleton::Config::source()->spellcheck_language.c_str());
if(Singleton::config->source.spellcheck_language.size()>0)
aspell_config_replace(spellcheck_config, "lang", Singleton::config->source.spellcheck_language.c_str());
spellcheck_possible_err=new_aspell_speller(spellcheck_config);
if(spellcheck_checker!=NULL)
delete_aspell_speller(spellcheck_checker);
@ -530,7 +531,7 @@ void Source::View::replace_all(const std::string &replacement) {
}
void Source::View::paste() {
auto text=Gtk::Clipboard::get()->wait_for_text();
std::string text=Gtk::Clipboard::get()->wait_for_text();
//remove carriage returns (which leads to crash)
for(auto it=text.begin();it!=text.end();it++) {
@ -545,13 +546,13 @@ void Source::View::paste() {
if(!get_buffer()->get_has_selection() && tabs_end_iter.ends_line()) {
prefix_tabs=get_line_before(tabs_end_iter);
Glib::ustring::size_type start_line=0;
Glib::ustring::size_type end_line=0;
size_t start_line=0;
size_t end_line=0;
bool paste_line=false;
bool first_paste_line=true;
size_t paste_line_tabs=-1;
bool first_paste_line_has_tabs=false;
for(Glib::ustring::size_type c=0;c<text.size();c++) {;
for(size_t c=0;c<text.size();c++) {;
if(text[c]=='\n') {
end_line=c;
paste_line=true;
@ -593,7 +594,7 @@ void Source::View::paste() {
paste_line=false;
first_paste_line=true;
get_source_buffer()->begin_user_action();
for(Glib::ustring::size_type c=0;c<text.size();c++) {
for(size_t c=0;c<text.size();c++) {
if(text[c]=='\n') {
end_line=c;
paste_line=true;
@ -1273,7 +1274,7 @@ Source::GenericView::GenericView(const boost::filesystem::path &file_path, const
if(language) {
get_source_buffer()->set_language(language);
Singleton::terminal()->print("Language for file "+file_path.string()+" set to "+language->get_name()+".\n");
Singleton::terminal->print("Language for file "+file_path.string()+" set to "+language->get_name()+".\n");
}
auto completion=get_completion();
@ -1305,7 +1306,7 @@ Source::GenericView::GenericView(const boost::filesystem::path &file_path, const
boost::property_tree::xml_parser::read_xml(language_file.string(), pt);
}
catch(const std::exception &e) {
Singleton::terminal()->print("Error: error parsing language file "+language_file.string()+": "+e.what()+'\n');
Singleton::terminal->print("Error: error parsing language file "+language_file.string()+": "+e.what()+'\n');
}
bool has_context_class=false;
parse_language_file(completion_buffer_keywords, has_context_class, pt);

28
src/source.h

@ -8,39 +8,11 @@
#include <vector>
#include "selectiondialog.h"
#include "terminal.h"
#include "tooltips.h"
namespace Source {
Glib::RefPtr<Gsv::Language> guess_language(const boost::filesystem::path &file_path);
class Config {
public:
class DocumentationSearch {
public:
std::string separator;
std::unordered_map<std::string, std::string> queries;
};
std::string style;
std::string font;
std::string spellcheck_language;
bool show_map;
std::string map_font_size;
bool auto_tab_char_and_size;
char default_tab_char;
unsigned default_tab_size;
bool wrap_lines;
bool highlight_current_line;
bool show_line_numbers;
std::unordered_map<std::string, std::string> clang_types;
std::string clang_format_style;
std::unordered_map<std::string, DocumentationSearch> documentation_searches;
};
class Token {
public:
Token(): type(-1) {}

24
src/source_clang.cc

@ -25,14 +25,14 @@ Source::View(file_path, project_path, language), parse_error(false) {
JDEBUG("start");
auto tag_table=get_buffer()->get_tag_table();
for (auto &item : Singleton::Config::source()->clang_types) {
for (auto &item : Singleton::config->source.clang_types) {
if(!tag_table->lookup(item.second)) {
get_buffer()->create_tag(item.second);
}
}
configure();
parsing_in_progress=Singleton::terminal()->print_in_progress("Parsing "+file_path.string());
parsing_in_progress=Singleton::terminal->print_in_progress("Parsing "+file_path.string());
//GTK-calls must happen in main thread, so the parse_thread
//sends signals to the main thread that it is to call the following functions:
parse_start_connection=parse_start.connect([this]{
@ -59,7 +59,7 @@ Source::View(file_path, project_path, language), parse_error(false) {
}
});
parse_fail_connection=parse_fail.connect([this](){
Singleton::terminal()->print("Error: failed to reparse "+this->file_path.string()+".\n");
Singleton::terminal->print("Error: failed to reparse "+this->file_path.string()+".\n");
set_status("");
set_info("");
parsing_in_progress->cancel("failed");
@ -80,7 +80,7 @@ void Source::ClangViewParse::configure() {
auto scheme = get_source_buffer()->get_style_scheme();
auto tag_table=get_buffer()->get_tag_table();
for (auto &item : Singleton::Config::source()->clang_types) {
for (auto &item : Singleton::config->source.clang_types) {
auto tag = get_buffer()->get_tag_table()->lookup(item.second);
if(tag) {
auto style = scheme->get_style(item.second);
@ -240,8 +240,8 @@ void Source::ClangViewParse::update_syntax() {
buffer->remove_tag_by_name(tag, buffer->begin(), buffer->end());
last_syntax_tags.clear();
for (auto &range : ranges) {
auto type_it=Singleton::Config::source()->clang_types.find(std::to_string(range.kind));
if(type_it!=Singleton::Config::source()->clang_types.end()) {
auto type_it=Singleton::config->source.clang_types.find(std::to_string(range.kind));
if(type_it!=Singleton::config->source.clang_types.end()) {
last_syntax_tags.emplace(type_it->second);
Gtk::TextIter begin_iter = buffer->get_iter_at_line_index(range.offsets.first.line-1, range.offsets.first.index-1);
Gtk::TextIter end_iter = buffer->get_iter_at_line_index(range.offsets.second.line-1, range.offsets.second.index-1);
@ -649,7 +649,7 @@ Source::ClangViewParse(file_path, project_path, language), autocomplete_cancel_s
});
autocomplete_fail_connection=autocomplete_fail.connect([this]() {
Singleton::terminal()->print("Error: autocomplete failed, reparsing "+this->file_path.string()+"\n");
Singleton::terminal->print("Error: autocomplete failed, reparsing "+this->file_path.string()+"\n");
restart_parse();
autocomplete_starting=false;
autocomplete_cancel_starting=false;
@ -924,7 +924,7 @@ Source::ClangViewAutocomplete(file_path, project_path, language) {
});
auto_indent=[this]() {
auto command=Singleton::Config::terminal()->clang_format_command;
auto command=Singleton::config->terminal.clang_format_command;
unsigned indent_width;
std::string tab_style;
if(tab_char=='\t') {
@ -938,13 +938,13 @@ Source::ClangViewAutocomplete(file_path, project_path, language) {
command+=" -style=\"{IndentWidth: "+std::to_string(indent_width);
command+=", "+tab_style;
command+=", "+std::string("AccessModifierOffset: -")+std::to_string(indent_width);
if(Singleton::Config::source()->clang_format_style!="")
command+=", "+Singleton::Config::source()->clang_format_style;
if(Singleton::config->source.clang_format_style!="")
command+=", "+Singleton::config->source.clang_format_style;
command+="}\"";
std::stringstream stdin_stream(get_buffer()->get_text()), stdout_stream;
auto exit_code=Singleton::terminal()->execute(stdin_stream, stdout_stream, command);
auto exit_code=Singleton::terminal->execute(stdin_stream, stdout_stream, command);
if(exit_code==0) {
get_source_buffer()->begin_user_action();
auto iter=get_buffer()->get_insert()->get_iter();
@ -1107,7 +1107,7 @@ Source::ClangViewAutocomplete(file_path, project_path, language) {
auto usr=referenced.get_usr();
boost::filesystem::path referenced_path=referenced.get_source_location().get_path();
//Singleton::terminal()->print(usr+'\n', true); //TODO: remove
//Singleton::terminal->print(usr+'\n', true); //TODO: remove
//Return empty if referenced is within project
if(referenced_path.generic_string().substr(0, this->project_path.generic_string().size()+1)==this->project_path.generic_string()+'/')

1
src/source_clang.h

@ -8,6 +8,7 @@
#include <regex>
#include "clangmm.h"
#include "source.h"
#include "terminal.h"
namespace Source {
class ClangViewParse : public View {

12
src/terminal.cc

@ -84,7 +84,7 @@ pid_t popen3(const std::string &command, const std::string &path, int *stdin_fd,
Terminal::InProgress::InProgress(const std::string& start_msg): stop(false) {
waiting_print.connect([this](){
Singleton::terminal()->async_print(line_nr-1, ".");
Singleton::terminal->async_print(line_nr-1, ".");
});
start(start_msg);
}
@ -96,7 +96,7 @@ Terminal::InProgress::~InProgress() {
}
void Terminal::InProgress::start(const std::string& msg) {
line_nr=Singleton::terminal()->print(msg+"...\n");
line_nr=Singleton::terminal->print(msg+"...\n");
wait_thread=std::thread([this](){
size_t c=0;
while(!stop) {
@ -111,14 +111,14 @@ void Terminal::InProgress::start(const std::string& msg) {
void Terminal::InProgress::done(const std::string& msg) {
if(!stop) {
stop=true;
Singleton::terminal()->async_print(line_nr-1, msg);
Singleton::terminal->async_print(line_nr-1, msg);
}
}
void Terminal::InProgress::cancel(const std::string& msg) {
if(!stop) {
stop=true;
Singleton::terminal()->async_print(line_nr-1, msg);
Singleton::terminal->async_print(line_nr-1, msg);
}
}
@ -357,8 +357,8 @@ size_t Terminal::print(const std::string &message, bool bold){
else
get_buffer()->insert(get_buffer()->end(), umessage);
if(get_buffer()->get_line_count()>Singleton::Config::terminal()->history_size) {
int lines=get_buffer()->get_line_count()-Singleton::Config::terminal()->history_size;
if(get_buffer()->get_line_count()>Singleton::config->terminal.history_size) {
int lines=get_buffer()->get_line_count()-Singleton::config->terminal.history_size;
get_buffer()->erase(get_buffer()->begin(), get_buffer()->get_iter_at_line(lines));
deleted_lines+=static_cast<size_t>(lines);
}

8
src/terminal.h

@ -12,14 +12,6 @@
class Terminal : public Gtk::TextView {
public:
class Config {
public:
std::string cmake_command;
std::string make_command;
std::string clang_format_command;
int history_size;
};
class InProgress {
public:
InProgress(const std::string& start_msg);

12
src/terminal_win.cc

@ -129,7 +129,7 @@ HANDLE popen3(const std::string &command, const std::string &path, HANDLE *stdin
Terminal::InProgress::InProgress(const std::string& start_msg): stop(false) {
waiting_print.connect([this](){
Singleton::terminal()->async_print(line_nr-1, ".");
Singleton::terminal->async_print(line_nr-1, ".");
});
start(start_msg);
}
@ -141,7 +141,7 @@ Terminal::InProgress::~InProgress() {
}
void Terminal::InProgress::start(const std::string& msg) {
line_nr=Singleton::terminal()->print(msg+"...\n");
line_nr=Singleton::terminal->print(msg+"...\n");
wait_thread=std::thread([this](){
size_t c=0;
while(!stop) {
@ -156,14 +156,14 @@ void Terminal::InProgress::start(const std::string& msg) {
void Terminal::InProgress::done(const std::string& msg) {
if(!stop) {
stop=true;
Singleton::terminal()->async_print(line_nr-1, msg);
Singleton::terminal->async_print(line_nr-1, msg);
}
}
void Terminal::InProgress::cancel(const std::string& msg) {
if(!stop) {
stop=true;
Singleton::terminal()->async_print(line_nr-1, msg);
Singleton::terminal->async_print(line_nr-1, msg);
}
}
@ -427,8 +427,8 @@ size_t Terminal::print(const std::string &message, bool bold){
else
get_buffer()->insert(get_buffer()->end(), umessage);
if(get_buffer()->get_line_count()>Singleton::Config::terminal()->history_size) {
int lines=get_buffer()->get_line_count()-Singleton::Config::terminal()->history_size;
if(get_buffer()->get_line_count()>Singleton::config->terminal.history_size) {
int lines=get_buffer()->get_line_count()-Singleton::config->terminal.history_size;
get_buffer()->erase(get_buffer()->begin(), get_buffer()->get_iter_at_line(lines));
deleted_lines+=static_cast<size_t>(lines);
}

1
src/tooltips.cc

@ -1,5 +1,4 @@
#include "tooltips.h"
#include "singletons.h"
#include <iostream> //TODO: remove
using namespace std; //TODO: remove

134
src/window.cc

@ -1,9 +1,9 @@
#include "window.h"
#include "logging.h"
#include "singletons.h"
#include "config.h"
//#include "api.h"
#include "dialogs.h"
#include "filesystem.h"
#include <iostream> //TODO: remove
using namespace std; //TODO: remove
@ -28,39 +28,39 @@ Window::Window() : compiling(false) {
set_events(Gdk::POINTER_MOTION_MASK|Gdk::FOCUS_CHANGE_MASK|Gdk::SCROLL_MASK);
set_menu_actions();
configure();
set_default_size(Singleton::Config::window()->default_size.first, Singleton::Config::window()->default_size.second);
set_default_size(Singleton::config->window.default_size.first, Singleton::config->window.default_size.second);
//PluginApi(&this->notebook, &this->menu);
add(vpaned);
directory_and_notebook_panes.pack1(*Singleton::directories(), Gtk::SHRINK);
directory_and_notebook_panes.pack1(*Singleton::directories, Gtk::SHRINK);
notebook_vbox.pack_start(notebook);
notebook_vbox.pack_end(entry_box, Gtk::PACK_SHRINK);
directory_and_notebook_panes.pack2(notebook_vbox, Gtk::SHRINK);
directory_and_notebook_panes.set_position(static_cast<int>(0.2*Singleton::Config::window()->default_size.first));
vpaned.set_position(static_cast<int>(0.75*Singleton::Config::window()->default_size.second));
directory_and_notebook_panes.set_position(static_cast<int>(0.2*Singleton::config->window.default_size.first));
vpaned.set_position(static_cast<int>(0.75*Singleton::config->window.default_size.second));
vpaned.pack1(directory_and_notebook_panes, true, false);
terminal_scrolled_window.add(*Singleton::terminal());
terminal_scrolled_window.add(*Singleton::terminal);
terminal_vbox.pack_start(terminal_scrolled_window);
info_and_status_hbox.pack_start(*Singleton::info(), Gtk::PACK_SHRINK);
info_and_status_hbox.pack_end(*Singleton::status(), Gtk::PACK_SHRINK);
info_and_status_hbox.pack_start(*Singleton::info, Gtk::PACK_SHRINK);
info_and_status_hbox.pack_end(*Singleton::status, Gtk::PACK_SHRINK);
terminal_vbox.pack_end(info_and_status_hbox, Gtk::PACK_SHRINK);
vpaned.pack2(terminal_vbox, true, true);
show_all_children();
Singleton::directories()->on_row_activated=[this](const std::string &file) {
Singleton::directories->on_row_activated=[this](const std::string &file) {
notebook.open(file);
};
//Scroll to end of terminal whenever info is printed
Singleton::terminal()->signal_size_allocate().connect([this](Gtk::Allocation& allocation){
Singleton::terminal->signal_size_allocate().connect([this](Gtk::Allocation& allocation){
auto adjustment=terminal_scrolled_window.get_vadjustment();
adjustment->set_value(adjustment->get_upper()-adjustment->get_page_size());
Singleton::terminal()->queue_draw();
Singleton::terminal->queue_draw();
});
entry_box.signal_show().connect([this](){
@ -90,7 +90,7 @@ Window::Window() : compiling(false) {
activate_menu_items();
Singleton::directories()->select(notebook.get_current_view()->file_path);
Singleton::directories->select(notebook.get_current_view()->file_path);
if(auto source_view=dynamic_cast<Source::ClangView*>(notebook.get_current_view())) {
if(source_view->reparse_needed) {
@ -111,7 +111,7 @@ Window::Window() : compiling(false) {
about.hide();
});
about.set_version(Singleton::Config::window()->version);
about.set_version(Singleton::config->window.version);
about.set_authors({"(in order of appearance)",
"Ted Johan Kristoffersen",
"Jørgen Lien Sellæg",
@ -126,27 +126,25 @@ Window::Window() : compiling(false) {
} // Window constructor
void Window::configure() {
Singleton::Config::main()->read();
Singleton::config->load();
auto style_context = Gtk::StyleContext::create();
auto screen = Gdk::Screen::get_default();
auto css_provider = Gtk::CssProvider::get_named(Singleton::Config::window()->theme_name, Singleton::Config::window()->theme_variant);
//TODO: add check if theme exists, or else write error to Singleton::terminal()
auto css_provider = Gtk::CssProvider::get_named(Singleton::config->window.theme_name, Singleton::config->window.theme_variant);
//TODO: add check if theme exists, or else write error to Singleton::terminal
style_context->add_provider_for_screen(screen, css_provider, GTK_STYLE_PROVIDER_PRIORITY_SETTINGS);
if(Singleton::directories() != nullptr) {
Singleton::directories()->update();
}
Singleton::menu()->set_keys();
Singleton::directories->update();
Singleton::menu->set_keys();
}
void Window::set_menu_actions() {
auto menu = Singleton::menu();
auto &menu = Singleton::menu;
menu->add_action("about", [this]() {
about.show();
about.present();
});
menu->add_action("preferences", [this]() {
notebook.open(Singleton::Config::main()->juci_home_path()/"config"/"config.json");
notebook.open(Singleton::config->juci_home_path()/"config"/"config.json");
});
menu->add_action("quit", [this]() {
hide();
@ -156,17 +154,17 @@ void Window::set_menu_actions() {
boost::filesystem::path path = Dialog::new_file();
if(path!="") {
if(boost::filesystem::exists(path)) {
Singleton::terminal()->print("Error: "+path.string()+" already exists.\n");
Singleton::terminal->print("Error: "+path.string()+" already exists.\n");
}
else {
if(filesystem::write(path)) {
if(Singleton::directories()->current_path!="")
Singleton::directories()->update();
if(Singleton::directories->current_path!="")
Singleton::directories->update();
notebook.open(path.string());
Singleton::terminal()->print("New file "+path.string()+" created.\n");
Singleton::terminal->print("New file "+path.string()+" created.\n");
}
else
Singleton::terminal()->print("Error: could not create new file "+path.string()+".\n");
Singleton::terminal->print("Error: could not create new file "+path.string()+".\n");
}
}
});
@ -175,13 +173,13 @@ void Window::set_menu_actions() {
boost::filesystem::path path = Dialog::new_folder();
if(path!="" && boost::filesystem::exists(path)) {
if(boost::filesystem::last_write_time(path)>=time_now) {
if(Singleton::directories()->current_path!="")
Singleton::directories()->update();
Singleton::terminal()->print("New folder "+path.string()+" created.\n");
if(Singleton::directories->current_path!="")
Singleton::directories->update();
Singleton::terminal->print("New folder "+path.string()+" created.\n");
}
else
Singleton::terminal()->print("Error: "+path.string()+" already exists.\n");
Singleton::directories()->select(path);
Singleton::terminal->print("Error: "+path.string()+" already exists.\n");
Singleton::directories->select(path);
}
});
menu->add_action("new_project_cpp", [this]() {
@ -197,41 +195,41 @@ void Window::set_menu_actions() {
auto cpp_main_path=project_path;
cpp_main_path+="/main.cpp";
if(boost::filesystem::exists(cmakelists_path)) {
Singleton::terminal()->print("Error: "+cmakelists_path.string()+" already exists.\n");
Singleton::terminal->print("Error: "+cmakelists_path.string()+" already exists.\n");
return;
}
if(boost::filesystem::exists(cpp_main_path)) {
Singleton::terminal()->print("Error: "+cpp_main_path.string()+" already exists.\n");
Singleton::terminal->print("Error: "+cpp_main_path.string()+" already exists.\n");
return;
}
std::string cmakelists="cmake_minimum_required(VERSION 2.8)\n\nproject("+project_name+")\n\nset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -std=c++1y -Wall\")\n\nadd_executable("+project_name+" main.cpp)\n";
std::string cpp_main="#include <iostream>\n\nusing namespace std;\n\nint main() {\n cout << \"Hello World!\" << endl;\n\n return 0;\n}\n";
if(filesystem::write(cmakelists_path, cmakelists) && filesystem::write(cpp_main_path, cpp_main)) {
Singleton::directories()->open(project_path);
Singleton::directories->open(project_path);
notebook.open(cpp_main_path);
Singleton::terminal()->print("C++ project "+project_name+" created.\n");
Singleton::terminal->print("C++ project "+project_name+" created.\n");
}
else
Singleton::terminal()->print("Error: Could not create project "+project_path.string()+"\n");
Singleton::terminal->print("Error: Could not create project "+project_path.string()+"\n");
}
});
menu->add_action("open_file", [this]() {
auto path=Dialog::select_file();
auto path=Dialog::open_file();
if(path!="")
notebook.open(path);
});
menu->add_action("open_folder", [this]() {
auto path = Dialog::select_folder();
auto path = Dialog::open_folder();
if (path!="" && boost::filesystem::exists(path))
Singleton::directories()->open(path);
Singleton::directories->open(path);
});
menu->add_action("save", [this]() {
if(notebook.get_current_page()!=-1) {
if(notebook.save_current()) {
if(notebook.get_current_page()!=-1) {
if(notebook.get_current_view()->file_path==Singleton::Config::main()->juci_home_path()/"config"/"config.json") {
if(notebook.get_current_view()->file_path==Singleton::config->juci_home_path()/"config"/"config.json") {
configure();
for(int c=0;c<notebook.size();c++) {
notebook.get_view(c)->configure();
@ -244,19 +242,19 @@ void Window::set_menu_actions() {
});
menu->add_action("save_as", [this]() {
if(notebook.get_current_page()!=-1) {
auto path = Dialog::save_file();
auto path = Dialog::save_file_as(notebook.get_current_view()->file_path);
if(path!="") {
std::ofstream file(path);
if(file) {
file << notebook.get_current_view()->get_buffer()->get_text();
file.close();
if(Singleton::directories()->current_path!="")
Singleton::directories()->update();
if(Singleton::directories->current_path!="")
Singleton::directories->update();
notebook.open(path);
Singleton::terminal()->print("File saved to: " + notebook.get_current_view()->file_path.string()+"\n");
Singleton::terminal->print("File saved to: " + notebook.get_current_view()->file_path.string()+"\n");
}
else
Singleton::terminal()->print("Error saving file\n");
Singleton::terminal->print("Error saving file\n");
}
}
});
@ -344,8 +342,8 @@ void Window::set_menu_actions() {
if(notebook.get_current_view()->get_token_data) {
auto data=notebook.get_current_view()->get_token_data();
if(data.size()>0) {
auto documentation_search=Singleton::Config::source()->documentation_searches.find(data[0]);
if(documentation_search!=Singleton::Config::source()->documentation_searches.end()) {
auto documentation_search=Singleton::config->source.documentation_searches.find(data[0]);
if(documentation_search!=Singleton::config->source.documentation_searches.end()) {
std::string token_query;
for(size_t c=1;c<data.size();c++) {
if(data[c].size()>0) {
@ -366,7 +364,7 @@ void Window::set_menu_actions() {
if(query!=documentation_search->second.queries.end()) {
std::string uri=query->second+token_query;
#ifdef __APPLE__
Singleton::terminal()->execute("open \""+uri+"\"");
Singleton::terminal->execute("open \""+uri+"\"");
#else
GError* error=NULL;
gtk_show_uri(NULL, uri.c_str(), GDK_CURRENT_TIME, &error);
@ -446,9 +444,9 @@ void Window::set_menu_actions() {
if(cmake.project_path!="") {
if(executable_path!="") {
compiling=true;
Singleton::terminal()->print("Compiling and running "+executable_path.string()+"\n");
Singleton::terminal->print("Compiling and running "+executable_path.string()+"\n");
auto project_path=cmake.project_path;
Singleton::terminal()->async_execute(Singleton::Config::terminal()->make_command, cmake.project_path, [this, executable_path, project_path](int exit_code){
Singleton::terminal->async_execute(Singleton::config->terminal.make_command, cmake.project_path, [this, executable_path, project_path](int exit_code){
compiling=false;
if(exit_code==EXIT_SUCCESS) {
auto executable_path_spaces_fixed=executable_path.string();
@ -460,16 +458,16 @@ void Window::set_menu_actions() {
}
last_char=executable_path_spaces_fixed[c];
}
Singleton::terminal()->async_execute(executable_path_spaces_fixed, project_path, [this, executable_path](int exit_code){
Singleton::terminal()->async_print(executable_path.string()+" returned: "+std::to_string(exit_code)+'\n');
Singleton::terminal->async_execute(executable_path_spaces_fixed, project_path, [this, executable_path](int exit_code){
Singleton::terminal->async_print(executable_path.string()+" returned: "+std::to_string(exit_code)+'\n');
});
}
});
}
else {
Singleton::terminal()->print("Could not find add_executable in the following paths:\n");
Singleton::terminal->print("Could not find add_executable in the following paths:\n");
for(auto &path: cmake.paths)
Singleton::terminal()->print(" "+path.string()+"\n");
Singleton::terminal->print(" "+path.string()+"\n");
}
}
});
@ -479,8 +477,8 @@ void Window::set_menu_actions() {
CMake cmake(notebook.get_current_view()->file_path);
if(cmake.project_path!="") {
compiling=true;
Singleton::terminal()->print("Compiling project "+cmake.project_path.string()+"\n");
Singleton::terminal()->async_execute(Singleton::Config::terminal()->make_command, cmake.project_path, [this](int exit_code){
Singleton::terminal->print("Compiling project "+cmake.project_path.string()+"\n");
Singleton::terminal->async_execute(Singleton::config->terminal.make_command, cmake.project_path, [this](int exit_code){
compiling=false;
});
}
@ -505,11 +503,11 @@ void Window::set_menu_actions() {
run_path=notebook.get_current_view()->file_path.parent_path();
}
else
run_path=Singleton::directories()->current_path;
Singleton::terminal()->async_print("Running: "+content+'\n');
run_path=Singleton::directories->current_path;
Singleton::terminal->async_print("Running: "+content+'\n');
Singleton::terminal()->async_execute(content, run_path, [this, content](int exit_code){
Singleton::terminal()->async_print(content+" returned: "+std::to_string(exit_code)+'\n');
Singleton::terminal->async_execute(content, run_path, [this, content](int exit_code){
Singleton::terminal->async_print(content+" returned: "+std::to_string(exit_code)+'\n');
});
}
entry_box.hide();
@ -523,10 +521,10 @@ void Window::set_menu_actions() {
});
menu->add_action("kill_last_running", [this]() {
Singleton::terminal()->kill_last_async_execute();
Singleton::terminal->kill_last_async_execute();
});
menu->add_action("force_kill_last_running", [this]() {
Singleton::terminal()->kill_last_async_execute(true);
Singleton::terminal->kill_last_async_execute(true);
});
menu->add_action("next_tab", [this]() {
@ -549,8 +547,8 @@ void Window::set_menu_actions() {
notebook.get_current_view()->set_info(notebook.get_current_view()->info);
}
else {
Singleton::status()->set_text("");
Singleton::info()->set_text("");
Singleton::status->set_text("");
Singleton::info->set_text("");
activate_menu_items(false);
}
@ -559,7 +557,7 @@ void Window::set_menu_actions() {
}
void Window::activate_menu_items(bool activate) {
auto menu = Singleton::menu();
auto &menu = Singleton::menu;
menu->actions["source_indentation_auto_indent_buffer"]->set_enabled(activate ? static_cast<bool>(notebook.get_current_view()->auto_indent) : false);
menu->actions["source_find_documentation"]->set_enabled(activate ? static_cast<bool>(notebook.get_current_view()->get_token_data) : false);
menu->actions["source_goto_declaration"]->set_enabled(activate ? static_cast<bool>(notebook.get_current_view()->get_declaration_location) : false);
@ -614,7 +612,7 @@ void Window::hide() {
if(!notebook.close_current_page())
return;
}
Singleton::terminal()->kill_async_executes();
Singleton::terminal->kill_async_executes();
Gtk::Window::hide();
}
@ -816,7 +814,7 @@ void Window::rename_token_entry() {
if(view->rename_similar_tokens) {
auto number=view->rename_similar_tokens(*token, content);
if(number>0) {
Singleton::terminal()->print("Replaced "+std::to_string(number)+" occurrences in file "+view->file_path.string()+"\n");
Singleton::terminal->print("Replaced "+std::to_string(number)+" occurrences in file "+view->file_path.string()+"\n");
notebook.save(c);
}
}

8
src/window.h

@ -2,7 +2,6 @@
#define JUCI_WINDOW_H_
#include "gtkmm.h"
#include "directories.h"
#include "entrybox.h"
#include "notebook.h"
#include <atomic>
@ -11,13 +10,6 @@ class Window : public Gtk::ApplicationWindow {
public:
Window();
Notebook notebook;
class Config {
public:
std::string theme_name;
std::string theme_variant;
std::string version;
std::pair<int, int> default_size;
};
protected:
bool on_key_press_event(GdkEventKey *event);

Loading…
Cancel
Save