Browse Source

Merge pull request #10 from cppit/master

pull from cppit
merge-requests/365/head
Ole Christian Eidheim 10 years ago
parent
commit
5a3bcea3e6
  1. 64
      src/config.cc
  2. 6
      src/config.h
  3. 16
      src/juci.cc
  4. 7
      src/juci.h
  5. 7
      src/singletons.cc
  6. 10
      src/singletons.h
  7. 53
      src/source.cc
  8. 9
      src/source.h
  9. 14
      src/theme.h
  10. 1
      src/tooltips.cc
  11. 30
      src/window.cc
  12. 9
      src/window.h

64
src/config.cc

@ -5,17 +5,25 @@
#include "files.h"
#include "sourcefile.h"
//TODO: add try-catch to json-get and get_child
MainConfig::MainConfig(Menu &menu) : menu(menu) {
MainConfig::MainConfig() {
find_or_create_config_files();
boost::property_tree::json_parser::read_json(Singleton::config_dir() + "config.json", cfg);
Singleton::Config::window()->keybindings = cfg.get_child("keybindings");
GenerateSource();
GenerateKeybindings();
GenerateTheme();
GenerateDirectoryFilter();
Singleton::Config::terminal()->make_command=cfg.get<std::string>("project.make_command");
}
void MainConfig::GenerateTheme() {
auto config = Singleton::Config::theme();
auto props = cfg.get_child("theme");
for (auto &prop : props) {
if (prop.first == "theme") config->theme = prop.second.get_value<std::string>();
if (prop.first == "main") config->main = prop.second.get_value<std::string>();
}
}
void MainConfig::find_or_create_config_files() {
std::vector<std::string> files = {"config.json", "menu.xml", "plugins.py"};
boost::filesystem::create_directories(boost::filesystem::path(Singleton::config_dir()));
@ -31,49 +39,17 @@ void MainConfig::find_or_create_config_files() {
void MainConfig::GenerateSource() {
auto source_cfg = Singleton::Config::source();
DEBUG("Fetching source cfg");
// boost::property_tree::ptree
auto source_json = cfg.get_child("source");
auto syntax_json = source_json.get_child("syntax");
auto colors_json = source_json.get_child("colors");
auto visual_json = source_json.get_child("visual");
for (auto &i : visual_json) {
if (i.first == "background")
source_cfg->background = i.second.get_value<std::string>();
else if (i.first == "background_selected")
source_cfg->background_selected = i.second.get_value<std::string>();
else if (i.first == "background_tooltips")
source_cfg->background_tooltips = i.second.get_value<std::string>();
else if (i.first == "show_line_numbers")
source_cfg->show_line_numbers = i.second.get_value<std::string>() == "1" ? true : false;
else if (i.first == "highlight_current_line")
source_cfg->highlight_current_line = i.second.get_value<std::string>() == "1" ? true : false;
else if (i.first == "font")
source_cfg->font = i.second.get_value<std::string>();
}
source_cfg->tab_size = source_json.get<unsigned>("tab_size");
for (unsigned c = 0; c < source_cfg->tab_size; c++)
source_cfg->tab+=" ";
for (auto &i : colors_json)
auto clang_types_json = source_json.get_child("clang_types");
auto style_json = source_json.get_child("style");
auto gsv_json = source_json.get_child("sourceview");
for (auto &i : gsv_json)
source_cfg->gsv[i.first] = i.second.get_value<std::string>();
for (auto &i : style_json)
source_cfg->tags[i.first] = i.second.get_value<std::string>();
for (auto &i : syntax_json)
for (auto &i : clang_types_json)
source_cfg->types[i.first] = i.second.get_value<std::string>();
DEBUG("Source cfg fetched");
}
void MainConfig::GenerateKeybindings() {
boost::filesystem::path path(Singleton::config_dir() + "menu.xml");
if (!boost::filesystem::is_regular_file(path)) {
std::cerr << "menu.xml not found" << std::endl;
throw;
}
menu.ui = juci::filesystem::read(path);
boost::property_tree::ptree keys_json = cfg.get_child("keybindings");
for (auto &i : keys_json) {
auto key=i.second.get_value<std::string>();
menu.key_map[i.first] = key;
}
DEBUG("Keybindings fetched");
}
void MainConfig::GenerateDirectoryFilter() {

6
src/config.h

@ -6,15 +6,13 @@
class MainConfig {
public:
MainConfig(Menu &menu);
MainConfig();
void find_or_create_config_files();
void PrintMenu();
void GenerateSource();
void GenerateKeybindings();
void GenerateDirectoryFilter();
void GenerateTheme();
private:
boost::property_tree::ptree cfg;
boost::property_tree::ptree key_tree;
Menu &menu;
};
#endif

16
src/juci.cc

@ -1,5 +1,6 @@
#include "juci.h"
#include "singletons.h"
#include "config.h"
#include <iostream>
void init_logging() {
@ -9,7 +10,7 @@ void init_logging() {
INFO("Logging initalized");
}
int Juci::on_command_line(const Glib::RefPtr<Gio::ApplicationCommandLine> &cmd) {
int app::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));
@ -35,7 +36,7 @@ int Juci::on_command_line(const Glib::RefPtr<Gio::ApplicationCommandLine> &cmd)
return 0;
}
void Juci::on_activate() {
void app::on_activate() {
window = std::unique_ptr<Window>(new Window());
add_window(*window);
window->show();
@ -46,7 +47,16 @@ void Juci::on_activate() {
window->notebook.open(f);
}
app::app() : Gtk::Application("no.sout.juci", Gio::APPLICATION_NON_UNIQUE | Gio::APPLICATION_HANDLES_COMMAND_LINE) {
MainConfig(); // Read the configs here
auto css_provider = Gtk::CssProvider::get_default();
auto style_context = Gtk::StyleContext::create();
auto screen = Gdk::Screen::get_default();
style_context->add_provider_for_screen(screen, css_provider, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
css_provider->load_from_path(Singleton::theme_dir() + Singleton::Config::theme()->current_theme());
}
int main(int argc, char *argv[]) {
init_logging();
return Juci().run(argc, argv);
return app().run(argc, argv);
}

7
src/juci.h

@ -3,11 +3,9 @@
#include "window.h"
#include "logging.h"
class Juci : public Gtk::Application {
class app : public Gtk::Application {
public:
Juci(): Gtk::Application("no.sout.juci", Gio::APPLICATION_NON_UNIQUE | Gio::APPLICATION_HANDLES_COMMAND_LINE) {}
app();
int on_command_line(const Glib::RefPtr<Gio::ApplicationCommandLine> &cmd);
void on_activate();
@ -18,3 +16,4 @@ private:
};
#endif // JUCI_JUCI_H_

7
src/singletons.cc

@ -1,10 +1,11 @@
#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<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<Theme::Config> Singleton::Config::theme_ = std::unique_ptr<Theme::Config>(new Theme::Config());
std::unique_ptr<Window::Config> Singleton::Config::window_ = std::unique_ptr<Window::Config>(new Window::Config());
std::unique_ptr<Terminal> Singleton::terminal_=std::unique_ptr<Terminal>();
Terminal *Singleton::terminal() {
if(!terminal_)
terminal_=std::unique_ptr<Terminal>(new Terminal());

10
src/singletons.h

@ -1,10 +1,13 @@
#ifndef JUCI_SINGLETONS_H_
#define JUCI_SINGLETONS_H_
#include "source.h"
#include "window.h"
#include "directories.h"
#include "terminal.h"
#include "notebook.h"
#include "theme.h"
#include "menu.h"
#include <gtkmm.h>
#include <string>
@ -15,14 +18,21 @@ public:
public:
static Source::Config *source() {return source_.get();}
static Directories::Config *directories() {return directories_.get();}
static Theme::Config *theme() { return theme_.get(); }
static Window::Config *window() { return window_.get(); }
static Terminal::Config *terminal() {return terminal_.get();}
private:
static std::unique_ptr<Source::Config> source_;
static std::unique_ptr<Theme::Config> theme_;
static std::unique_ptr<Window::Config> window_;
static std::unique_ptr<Directories::Config> directories_;
static std::unique_ptr<Terminal::Config> terminal_;
};
static std::string config_dir() { return std::string(getenv("HOME")) + "/.juci/config/"; }
static std::string theme_dir() { return std::string(getenv("HOME")) + "/.juci/gtk-themes/"; }
static std::string log_dir() { return std::string(getenv("HOME")) + "/.juci/log/"; }
static std::string style_dir() { return std::string(getenv("HOME")) + "/.juci/styles/"; }
static Terminal *terminal();
static Gtk::Label *status();
private:

53
src/source.cc

@ -7,6 +7,7 @@
#include <regex>
#include "singletons.h"
#include <gtksourceview/gtksource.h>
#include <boost/lexical_cast.hpp>
#include <iostream> //TODO: remove
using namespace std; //TODO: remove
@ -37,13 +38,9 @@ Glib::RefPtr<Gsv::Language> Source::guess_language(const boost::filesystem::path
//////////////
Source::View::View(const boost::filesystem::path &file_path): file_path(file_path) {
set_smart_home_end(Gsv::SMART_HOME_END_BEFORE);
set_show_line_numbers(Singleton::Config::source()->show_line_numbers);
set_highlight_current_line(Singleton::Config::source()->highlight_current_line);
get_source_buffer()->begin_not_undoable_action();
juci::filesystem::read(file_path, get_buffer());
get_source_buffer()->end_not_undoable_action();
get_buffer()->place_cursor(get_buffer()->get_iter_at_offset(0));
search_settings = gtk_source_search_settings_new();
gtk_source_search_settings_set_wrap_around(search_settings, true);
@ -58,6 +55,19 @@ Source::View::View(const boost::filesystem::path &file_path): file_path(file_pat
//TODO: either use lambda if possible or create a gtkmm wrapper around search_context (including search_settings):
//TODO: (gtkmm's Gtk::Object has connect_property_changed, so subclassing this might be an idea)
g_signal_connect(search_context, "notify::occurrences-count", G_CALLBACK(search_occurrences_updated), this);
// style
auto style_scheme_manager=Gsv::StyleSchemeManager::get_default();
style_scheme_manager->prepend_search_path(Singleton::style_dir());
auto scheme = style_scheme_manager->get_scheme(Singleton::Config::theme()->theme);
if(scheme) {
get_source_buffer()->set_style_scheme(scheme);
}
property_highlight_current_line() = Singleton::Config::source()->gsv["highlight_current_line"] == "true";
property_show_line_numbers() = Singleton::Config::source()->gsv["show_line_numbers"] == "true";
}
void Source::View::search_occurrences_updated(GtkWidget* widget, GParamSpec* property, gpointer data) {
@ -358,16 +368,6 @@ bool Source::View::on_key_press_event(GdkEventKey* key) {
//// GenericView ////
/////////////////////
Source::GenericView::GenericView(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language) : View(file_path) {
auto style_scheme_manager=Gsv::StyleSchemeManager::get_default();
//TODO: add?: style_scheme_manager->prepend_search_path("~/.juci/");
auto scheme=style_scheme_manager->get_scheme("classic");
if(scheme) {
get_source_buffer()->set_style_scheme(scheme);
auto style=scheme->get_style("def:comment");
if(style)
cout << "TODO, in progress: def:comment in scheme " << scheme->get_name() << " has color " << style->property_foreground() << endl;
}
if(language) {
get_source_buffer()->set_language(language);
Singleton::terminal()->print("Language for file "+file_path.string()+" set to "+language->get_name()+".\n");
@ -388,12 +388,28 @@ clang::Index Source::ClangViewParse::clang_index(0, 0);
Source::ClangViewParse::ClangViewParse(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path):
Source::View(file_path), project_path(project_path) {
override_font(Pango::FontDescription(Singleton::Config::source()->font));
override_background_color(Gdk::RGBA(Singleton::Config::source()->background));
override_background_color(Gdk::RGBA(Singleton::Config::source()->background_selected), Gtk::StateFlags::STATE_FLAG_SELECTED);
for (auto &item : Singleton::Config::source()->tags) {
auto scheme = get_source_buffer()->get_style_scheme();
auto style = scheme->get_style(item.second);
if (style) {
DEBUG("Style " + item.second + " found in style " + scheme->get_name());
auto tag = get_source_buffer()->create_tag(item.first);
if (style->property_foreground_set())
tag->property_foreground() = style->property_foreground();
if (style->property_background_set())
tag->property_background() = style->property_background();
if (style->property_strikethrough_set())
tag->property_strikethrough() = style->property_strikethrough();
// // if (style->property_bold_set()) tag->property_weight() = style->property_bold();
// // if (style->property_italic_set()) tag->property_italic() = style->property_italic();
// // if (style->property_line_background_set()) tag->property_line_background() = style->property_line_background();
// // if (style->property_underline_set()) tag->property_underline() = style->property_underline();
} else {
DEBUG("Style " + item.second + " not found in " + scheme->get_name());
get_source_buffer()->create_tag(item.first)->property_foreground() = item.second;
}
}
INFO("Tagtable filled");
//Create underline color tags for diagnostic warnings and errors:
auto diagnostic_tag=get_buffer()->get_tag_table()->lookup("diagnostic_warning");
@ -586,7 +602,7 @@ void Source::ClangViewParse::update_syntax() {
buffer->remove_tag_by_name(tag, buffer->begin(), buffer->end());
last_syntax_tags.clear();
for (auto &range : ranges) {
std::string type = std::to_string(range.kind);
auto type = boost::lexical_cast<std::string>(range.kind);
try {
last_syntax_tags.emplace(Singleton::Config::source()->types.at(type));
} catch (std::exception) {
@ -597,6 +613,7 @@ void Source::ClangViewParse::update_syntax() {
Gtk::TextIter end_iter = buffer->get_iter_at_offset(range.end_offset);
buffer->apply_tag_by_name(Singleton::Config::source()->types.at(type),
begin_iter, end_iter);
}
}

9
src/source.h

@ -20,12 +20,11 @@ namespace Source {
class Config {
public:
unsigned tab_size;
bool show_line_numbers, highlight_current_line;
std::string tab, background, background_selected, background_tooltips, font;
unsigned tab_size = 2;
char tab_char = ' ';
std::unordered_map<std::string, std::string> tags, types;
}; // class Config
std::string tab = " ";
std::unordered_map<std::string, std::string> tags, types, gsv;
};
class Range {
public:

14
src/theme.h

@ -0,0 +1,14 @@
#ifndef JUCI_THEME_H_
#define JUCI_THEME_H_
#include <string>
namespace Theme {
class Config {
public:
std::string current_theme() { return theme + "/" + main; }
std::string theme, main;
};
}
#endif // JUCI_THEME_H_

1
src/tooltips.cc

@ -54,7 +54,6 @@ void Tooltip::adjust(bool disregard_drawn) {
tooltip_widget=std::unique_ptr<Gtk::TextView>(new Gtk::TextView(create_tooltip_buffer()));
wrap_lines(tooltip_widget->get_buffer());
tooltip_widget->set_editable(false);
tooltip_widget->override_background_color(Gdk::RGBA(Singleton::Config::source()->background_tooltips));
window->add(*tooltip_widget);
auto layout=Pango::Layout::create(tooltip_widget->get_pango_context());

30
src/window.cc

@ -4,6 +4,7 @@
#include "sourcefile.h"
#include "config.h"
#include "api.h"
#include <boost/lexical_cast.hpp>
#include <iostream> //TODO: remove
using namespace std; //TODO: remove
@ -12,6 +13,15 @@ namespace sigc {
SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE
}
void Window::generate_keybindings() {
boost::filesystem::path path(Singleton::config_dir() + "menu.xml");
menu.ui = juci::filesystem::read(path);
for (auto &i : Singleton::Config::window()->keybindings) {
auto key = i.second.get_value<std::string>();
menu.key_map[i.first] = key;
}
}
Window::Window() : box(Gtk::ORIENTATION_VERTICAL), notebook(directories), compiling(false) {
INFO("Create Window");
set_title("juCi++");
@ -19,8 +29,8 @@ Window::Window() : box(Gtk::ORIENTATION_VERTICAL), notebook(directories), compil
set_events(Gdk::POINTER_MOTION_MASK|Gdk::FOCUS_CHANGE_MASK|Gdk::SCROLL_MASK);
add(box);
MainConfig(this->menu); //Read the configs here
PluginApi(&this->notebook, &this->menu); //Initialise plugins
generate_keybindings();
PluginApi(&this->notebook, &this->menu);
create_menu();
box.pack_start(menu.get_widget(), Gtk::PACK_SHRINK);
@ -67,7 +77,7 @@ Window::Window() : box(Gtk::ORIENTATION_VERTICAL), notebook(directories), compil
if(notebook.get_current_page()!=-1) {
if(search_entry_shown && entry_box.labels.size()>0) {
notebook.get_current_view()->update_search_occurrences=[this](int number){
entry_box.labels.begin()->update(0, std::to_string(number));
entry_box.labels.begin()->update(0, boost::lexical_cast<std::string>(number));
};
notebook.get_current_view()->search_highlight(last_search, case_sensitive_search, regex_search);
}
@ -226,7 +236,7 @@ void Window::create_menu() {
compile_success();
//TODO: Windows...
Singleton::terminal()->async_execute(executable_path.string(), 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_print(executable_path.string()+" returned: "+boost::lexical_cast<std::string>(exit_code)+'\n');
});
}
});
@ -261,7 +271,7 @@ void Window::create_menu() {
last_run_command=content;
Singleton::terminal()->async_print("Running: "+content+'\n');
Singleton::terminal()->async_execute(content, directories.current_path, [this, content](int exit_code){
Singleton::terminal()->async_print(content+" returned: "+std::to_string(exit_code)+'\n');
Singleton::terminal()->async_print(content+" returned: "+boost::lexical_cast<std::string>(exit_code)+'\n');
});
}
entry_box.hide();
@ -500,13 +510,13 @@ void Window::search_and_replace_entry() {
auto label_it=entry_box.labels.begin();
label_it->update=[label_it](int state, const std::string& message){
if(state==0) {
int number=stoi(message);
auto number = boost::lexical_cast<int>(message);
if(number==0)
label_it->set_text("");
else if(number==1)
label_it->set_text("1 result found");
else if(number>1)
label_it->set_text(std::to_string(number)+" results found");
label_it->set_text(boost::lexical_cast<std::string>(number)+" results found");
}
};
entry_box.entries.emplace_back(last_search, [this](const std::string& content){
@ -517,7 +527,7 @@ void Window::search_and_replace_entry() {
search_entry_it->set_placeholder_text("Find");
if(notebook.get_current_page()!=-1) {
notebook.get_current_view()->update_search_occurrences=[label_it](int number){
label_it->update(0, std::to_string(number));
label_it->update(0, boost::lexical_cast<std::string>(number));
};
notebook.get_current_view()->search_highlight(search_entry_it->get_text(), case_sensitive_search, regex_search);
}
@ -588,7 +598,7 @@ void Window::goto_line_entry() {
if(notebook.get_current_page()!=-1) {
auto buffer=notebook.get_current_view()->get_buffer();
try {
auto line=stoul(content);
auto line = boost::lexical_cast<unsigned>(content);
if(line>0 && line<=(unsigned long)buffer->get_line_count()) {
line--;
buffer->place_cursor(buffer->get_iter_at_line(line));
@ -633,7 +643,7 @@ void Window::rename_token_entry() {
if(notebook.get_view(c)->rename_similar_tokens) {
auto number=notebook.get_view(c)->rename_similar_tokens(*token, content);
if(number>0) {
Singleton::terminal()->print("Replaced "+std::to_string(number)+" occurrences in file "+notebook.get_view(c)->file_path.string()+"\n");
Singleton::terminal()->print("Replaced "+boost::lexical_cast<std::string>(number)+" occurrences in file "+notebook.get_view(c)->file_path.string()+"\n");
notebook.save(c);
}
}

9
src/window.h

@ -6,6 +6,7 @@
#include "entrybox.h"
#include "notebook.h"
#include "menu.h"
#include <boost/property_tree/json_parser.hpp>
#include <atomic>
class Window : public Gtk::Window {
@ -13,9 +14,15 @@ public:
Window();
Directories directories;
Notebook notebook;
class Config {
public:
boost::property_tree::ptree keybindings;
};
protected:
bool on_key_press_event(GdkEventKey *event);
bool on_delete_event (GdkEventAny *event);
private:
Gtk::Box box;
Gtk::VPaned vpaned;
@ -36,10 +43,10 @@ private:
void open_folder_dialog();
void open_file_dialog();
void save_file_dialog();
void search_and_replace_entry();
void goto_line_entry();
void rename_token_entry();
void generate_keybindings();
std::string last_search;
std::string last_replace;
std::string last_run_command;

Loading…
Cancel
Save