From fe2cf9bea4955098a618edd99e920f8de7c3c64e Mon Sep 17 00:00:00 2001 From: eidheim Date: Sat, 7 Nov 2015 10:52:03 +0100 Subject: [PATCH 01/28] Now uses gtk dialog on Windows when creating folder, since Windows does not support this... --- src/dialogs.cc | 39 ++++++--------------------------------- src/dialogs.h | 28 ++++++++++++++++++++++++++++ src/dialogs_win.cc | 5 ++++- 3 files changed, 38 insertions(+), 34 deletions(-) diff --git a/src/dialogs.cc b/src/dialogs.cc index 8248443..04aff01 100644 --- a/src/dialogs.cc +++ b/src/dialogs.cc @@ -1,59 +1,32 @@ #include "dialogs.h" -#include "singletons.h" -#include -#include -#include "juci.h" - -std::string open_dialog(const std::string &title, - const std::vector> &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.string().c_str()); - else - 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); - - 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::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::open_folder() { - return open_dialog("Open Folder", + return gtk_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("New File", + return gtk_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("New Folder", + return gtk_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::open_file() { - return open_dialog("Open File", + return gtk_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_as(const boost::filesystem::path &file_path) { - return open_dialog("Save File As", + return gtk_dialog("Save File As", {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL),std::make_pair("Save", Gtk::RESPONSE_OK)}, - Gtk::FILE_CHOOSER_ACTION_SAVE, file_path.string()); + Gtk::FILE_CHOOSER_ACTION_SAVE, file_path.string()); } diff --git a/src/dialogs.h b/src/dialogs.h index 4977ce6..f5e4b0c 100644 --- a/src/dialogs.h +++ b/src/dialogs.h @@ -2,6 +2,10 @@ #define JUCI_DIALOG_H_ #include #include +#include +#include +#include "singletons.h" +#include "juci.h" class Dialog { public: @@ -10,6 +14,30 @@ public: static std::string new_file(); static std::string new_folder(); static std::string save_file_as(const boost::filesystem::path &file_path); + +private: + static std::string gtk_dialog(const std::string &title, + const std::vector> &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.string().c_str()); + else + 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); + + 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::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() : ""; + } }; #endif //JUCI_DIALOG_H_ diff --git a/src/dialogs_win.cc b/src/dialogs_win.cc index 967ba67..2c0a19b 100644 --- a/src/dialogs_win.cc +++ b/src/dialogs_win.cc @@ -142,7 +142,10 @@ std::string Dialog::new_file() { } std::string Dialog::new_folder() { - return Win32Dialog().open(L"New Folder", FOS_PICKFOLDERS); //TODO: this is not working correctly yet + //Win32 (IFileDialog) does not support create folder... + return gtk_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::open_file() { From 8617e5894d8aa22913cef7759e3da909caf317b2 Mon Sep 17 00:00:00 2001 From: eidheim Date: Sun, 8 Nov 2015 10:45:24 +0100 Subject: [PATCH 02/28] Can now create files from command line arguments (juci . new_file.py), and error messages in terminal are set to bold. --- src/juci.cc | 14 ++++++++++++-- src/notebook.cc | 16 +++++++++------- src/source.cc | 6 +++--- src/source_clang.cc | 4 ++-- src/terminal.cc | 6 +++--- src/terminal_win.cc | 6 +++--- src/window.cc | 12 ++++++------ 7 files changed, 38 insertions(+), 26 deletions(-) diff --git a/src/juci.cc b/src/juci.cc index 5dd0509..6c8a339 100644 --- a/src/juci.cc +++ b/src/juci.cc @@ -29,8 +29,18 @@ int Application::on_command_line(const Glib::RefPtr else if(boost::filesystem::is_directory(p)) directories.emplace_back(p); } - else - std::cerr << "Path " << p << " does not exist." << std::endl; + else { //Open new file if parent path exists + auto parent_p=p.parent_path(); + boost::system::error_code ec; + auto new_p=boost::filesystem::canonical(parent_p, ec); + if(!ec && boost::filesystem::is_directory(new_p)) { + new_p+="/"; + new_p+=p.filename(); + files.emplace_back(new_p); + } + else + Singleton::terminal->print("Error: folder path "+parent_p.string()+" does not exist.\n", true); + } } } activate(); diff --git a/src/notebook.cc b/src/notebook.cc index 6119cfe..74d9107 100644 --- a/src/notebook.cc +++ b/src/notebook.cc @@ -65,12 +65,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"); - return; + if(boost::filesystem::exists(file_path)) { + std::ifstream can_read(file_path.string()); + if(!can_read) { + Singleton::terminal->print("Error: could not open "+file_path.string()+"\n", true); + return; + } + can_read.close(); } - can_read.close(); auto language=Source::guess_language(file_path); boost::filesystem::path project_path; @@ -206,7 +208,7 @@ bool Notebook::save(int page, bool reparse_needed) { if(source_clang_view->restart_parse()) 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", true); } } } @@ -215,7 +217,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", true); } JDEBUG("end false"); return false; diff --git a/src/source.cc b/src/source.cc index 2f196d8..2688854 100644 --- a/src/source.cc +++ b/src/source.cc @@ -91,7 +91,7 @@ Source::View::View(const boost::filesystem::path &file_path, const boost::filesy } 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", true); } get_source_buffer()->end_not_undoable_action(); @@ -304,7 +304,7 @@ void Source::View::configure() { 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', true); } if(Singleton::config->source.wrap_lines) @@ -1306,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', true); } bool has_context_class=false; parse_language_file(completion_buffer_keywords, has_context_class, pt); diff --git a/src/source_clang.cc b/src/source_clang.cc index 4fe441d..ebad9e6 100644 --- a/src/source_clang.cc +++ b/src/source_clang.cc @@ -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", true); set_status(""); set_info(""); parsing_in_progress->cancel("failed"); @@ -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", true); restart_parse(); autocomplete_starting=false; autocomplete_cancel_starting=false; diff --git a/src/terminal.cc b/src/terminal.cc index 772f8ef..2a1ee90 100644 --- a/src/terminal.cc +++ b/src/terminal.cc @@ -155,7 +155,7 @@ int Terminal::execute(const std::string &command, const boost::filesystem::path pid=popen3(command, path.string(), nullptr, nullptr, nullptr); if (pid<=0) { - async_print("Error: Failed to run command: " + command + "\n"); + async_print("Error: Failed to run command: " + command + "\n", true); return -1; } else { @@ -203,7 +203,7 @@ int Terminal::execute(std::istream &stdin_stream, std::ostream &stdout_stream, c auto pid=popen3(command, path.string(), &stdin_fd, &stdout_fd, &stderr_fd); if (pid<=0) { - async_print("Error: Failed to run command: " + command + "\n"); + async_print("Error: Failed to run command: " + command + "\n", true); return -1; } else { @@ -269,7 +269,7 @@ void Terminal::async_execute(const std::string &command, const boost::filesystem async_executes_mutex.unlock(); if (pid<=0) { - async_print("Error: Failed to run command: " + command + "\n"); + async_print("Error: Failed to run command: " + command + "\n", true); if(callback) callback(-1); } diff --git a/src/terminal_win.cc b/src/terminal_win.cc index b3c57ec..962a55d 100644 --- a/src/terminal_win.cc +++ b/src/terminal_win.cc @@ -200,7 +200,7 @@ int Terminal::execute(const std::string &command, const boost::filesystem::path else process=popen3(command, path.string(), nullptr, nullptr, nullptr); if(process==NULL) { - async_print("Error: Failed to run command: " + command + "\n"); + async_print("Error: Failed to run command: " + command + "\n", true); return -1; } if(use_pipes) { @@ -257,7 +257,7 @@ int Terminal::execute(std::istream &stdin_stream, std::ostream &stdout_stream, c auto process=popen3(command, path.string(), &stdin_h, &stdout_h, &stderr_h); if(process==NULL) { - async_print("Error: Failed to run command: " + command + "\n"); + async_print("Error: Failed to run command: " + command + "\n", true); return -1; } std::thread stderr_thread([this, stderr_h](){ @@ -331,7 +331,7 @@ void Terminal::async_execute(const std::string &command, const boost::filesystem auto process=popen3(command, path.string(), &stdin_h, &stdout_h, &stderr_h); if(process==NULL) { async_executes_mutex.unlock(); - async_print("Error: Failed to run command: " + command + "\n"); + async_print("Error: Failed to run command: " + command + "\n", true); if(callback) callback(-1); return; diff --git a/src/window.cc b/src/window.cc index 388c94d..1ad2711 100644 --- a/src/window.cc +++ b/src/window.cc @@ -154,7 +154,7 @@ 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", true); } else { if(filesystem::write(path)) { @@ -164,7 +164,7 @@ void Window::set_menu_actions() { 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", true); } } }); @@ -178,7 +178,7 @@ void Window::set_menu_actions() { Singleton::terminal->print("New folder "+path.string()+" created.\n"); } else - Singleton::terminal->print("Error: "+path.string()+" already exists.\n"); + Singleton::terminal->print("Error: "+path.string()+" already exists.\n", true); Singleton::directories->select(path); } }); @@ -195,11 +195,11 @@ 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", true); 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", true); 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"; @@ -210,7 +210,7 @@ void Window::set_menu_actions() { 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", true); } }); From a288ce37cbb198db0365d30a7523f616af51f391 Mon Sep 17 00:00:00 2001 From: eidheim Date: Sun, 8 Nov 2015 18:10:04 +0100 Subject: [PATCH 03/28] Improved and consistant default directory handling for run command and dialogs. --- src/dialogs.h | 16 +++++++++------- src/dialogs_win.cc | 24 +++++++++++++----------- src/notebook.cc | 11 +++++++++++ src/notebook.h | 1 + src/window.cc | 12 ++---------- 5 files changed, 36 insertions(+), 28 deletions(-) diff --git a/src/dialogs.h b/src/dialogs.h index f5e4b0c..02fa700 100644 --- a/src/dialogs.h +++ b/src/dialogs.h @@ -21,19 +21,21 @@ private: 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.string().c_str()); - else - 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); 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::cast_static(gio_application); dialog.set_transient_for(*application->window); + auto current_path=application->window->notebook.get_current_path(); + if(current_path.empty()) + current_path=boost::filesystem::current_path(); + gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), 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); + for (auto &button : buttons) dialog.add_button(button.first, button.second); return dialog.run() == Gtk::RESPONSE_OK ? dialog.get_filename() : ""; diff --git a/src/dialogs_win.cc b/src/dialogs_win.cc index 2c0a19b..b2f3ba1 100644 --- a/src/dialogs_win.cc +++ b/src/dialogs_win.cc @@ -29,8 +29,7 @@ public: 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())) + if(!set_folder()) return ""; return show(); @@ -42,10 +41,10 @@ public: if(!set_title(title) || !add_option(option)) return ""; + if(!set_folder()) + return ""; std::vector 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}); @@ -53,11 +52,6 @@ public: 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 ""; @@ -98,8 +92,16 @@ private: } /** Sets the directory to start browsing */ - bool set_folder(const std::wstring &directory_path) { - std::wstring path=directory_path; + bool set_folder() { + 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::cast_static(gio_application); + + auto current_path=application->window->notebook.get_current_path(); + if(current_path.empty()) + current_path=boost::filesystem::current_path(); + + std::wstring path=current_path.native(); 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"\\"); diff --git a/src/notebook.cc b/src/notebook.cc index 74d9107..441f9e0 100644 --- a/src/notebook.cc +++ b/src/notebook.cc @@ -262,6 +262,17 @@ bool Notebook::close_current_page() { return true; } +boost::filesystem::path Notebook::get_current_path() { + boost::filesystem::path current_path; + + if(get_current_page()!=-1) + current_path=get_current_view()->project_path; + else + current_path=Singleton::directories->current_path; + + return current_path; +} + bool Notebook::save_modified_dialog() { Gtk::MessageDialog dialog((Gtk::Window&)(*get_toplevel()), "Save file!", false, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO); dialog.set_default_response(Gtk::RESPONSE_YES); diff --git a/src/notebook.h b/src/notebook.h index abb70c7..91840b6 100644 --- a/src/notebook.h +++ b/src/notebook.h @@ -21,6 +21,7 @@ public: bool save(int page, bool reparse_needed=false); bool save_current(); void configure(int view_nr); + boost::filesystem::path get_current_path(); private: bool save_modified_dialog(); diff --git a/src/window.cc b/src/window.cc index 1ad2711..4a9446f 100644 --- a/src/window.cc +++ b/src/window.cc @@ -489,21 +489,13 @@ void Window::set_menu_actions() { entry_box.labels.emplace_back(); auto label_it=entry_box.labels.begin(); label_it->update=[label_it](int state, const std::string& message){ - label_it->set_text("Run Command directory order: file project path, file directory, opened directory, current directory"); + label_it->set_text("Run Command directory order: file project path, opened directory, current directory"); }; label_it->update(0, ""); entry_box.entries.emplace_back(last_run_command, [this](const std::string& content){ if(content!="") { last_run_command=content; - boost::filesystem::path run_path; - if(notebook.get_current_page()!=-1) { - if(notebook.get_current_view()->project_path!="") - run_path=notebook.get_current_view()->project_path; - else - run_path=notebook.get_current_view()->file_path.parent_path(); - } - else - run_path=Singleton::directories->current_path; + auto run_path=notebook.get_current_path(); Singleton::terminal->async_print("Running: "+content+'\n'); Singleton::terminal->async_execute(content, run_path, [this, content](int exit_code){ From 17732a3e825eac1782c391e348c4d692ca135a7a Mon Sep 17 00:00:00 2001 From: eidheim Date: Sun, 8 Nov 2015 18:53:40 +0100 Subject: [PATCH 04/28] Added option to strip trailing whitespaces on save, and add trailing newline if missing. --- src/config.cc | 2 ++ src/config.h | 2 ++ src/files.h | 4 +++- src/notebook.cc | 24 ++++++++++++++++++++++++ 4 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/config.cc b/src/config.cc index 94f9552..19077ad 100644 --- a/src/config.cc +++ b/src/config.cc @@ -146,6 +146,8 @@ void Config::get_source() { source.style=source_json.get("style"); source.font=source_json.get("font"); + source.strip_trailing_whitespaces=source_json.get("strip_trailing_whitespaces"); + source.show_map = source_json.get("show_map"); source.map_font_size = source_json.get("map_font_size"); diff --git a/src/config.h b/src/config.h index 71c9866..4ad5f2e 100644 --- a/src/config.h +++ b/src/config.h @@ -49,6 +49,8 @@ public: std::string font; std::string spellcheck_language; + bool strip_trailing_whitespaces; + bool show_map; std::string map_font_size; diff --git a/src/files.h b/src/files.h index 954e322..fa38779 100644 --- a/src/files.h +++ b/src/files.h @@ -1,6 +1,6 @@ #include -#define JUCI_VERSION "0.9.4" +#define JUCI_VERSION "0.9.5" const std::string configjson = "{\n" @@ -29,6 +29,8 @@ const std::string configjson = " \"font\": \"Monospace\",\n" #endif #endif +" \"strip_trailing_whitespaces_comment\": \"Remove trailing whitespace characters on save, and add trailing newline if missing\",\n" +" \"strip_trailing_whitespaces\": false,\n" " \"show_map\": true,\n" " \"map_font_size\": \"1\",\n" " \"spellcheck_language_comment\": \"Use \\\"\\\" to set language from your locale settings\",\n" diff --git a/src/notebook.cc b/src/notebook.cc index 441f9e0..6096510 100644 --- a/src/notebook.cc +++ b/src/notebook.cc @@ -172,6 +172,30 @@ bool Notebook::save(int page, bool reparse_needed) { } auto view=get_view(page); if (view->file_path != "" && view->get_buffer()->get_modified()) { + //strip trailing whitespaces and add trailing newline if missing + if(Singleton::config->source.strip_trailing_whitespaces) { + auto buffer=view->get_buffer(); + for(int line=0;lineget_line_count();line++) { + auto iter=buffer->get_iter_at_line(line); + auto end_iter=iter; + while(!end_iter.ends_line()) + end_iter.forward_char(); + if(iter==end_iter) + continue; + iter=end_iter; + while(!iter.starts_line() && (*iter==' ' || *iter=='\t' || iter.ends_line())) + iter.backward_char(); + if(!iter.starts_line()) + iter.forward_char(); + if(iter==end_iter) + continue; + buffer->erase(iter, end_iter); + } + auto iter=buffer->end(); + if(!iter.starts_line()) + buffer->insert(buffer->end(), "\n"); + } + if(filesystem::write(view->file_path, view->get_buffer())) { if(reparse_needed) { if(auto clang_view=dynamic_cast(view)) { From 6a4adbbf09d31cdf4f4dfdc846a3d47b882cd4eb Mon Sep 17 00:00:00 2001 From: eidheim Date: Sun, 8 Nov 2015 19:08:00 +0100 Subject: [PATCH 05/28] Fixed a bug in trailing whitespace stripping. --- src/notebook.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/notebook.cc b/src/notebook.cc index 6096510..c72627a 100644 --- a/src/notebook.cc +++ b/src/notebook.cc @@ -185,7 +185,7 @@ bool Notebook::save(int page, bool reparse_needed) { iter=end_iter; while(!iter.starts_line() && (*iter==' ' || *iter=='\t' || iter.ends_line())) iter.backward_char(); - if(!iter.starts_line()) + if(*iter!=' ' && *iter!='\t') iter.forward_char(); if(iter==end_iter) continue; From 5839186aa5cdbac404631f3387a49d82032a4179 Mon Sep 17 00:00:00 2001 From: eidheim Date: Sun, 8 Nov 2015 19:13:41 +0100 Subject: [PATCH 06/28] Added *_user_action to trailing whitespace stripping. --- src/notebook.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/notebook.cc b/src/notebook.cc index c72627a..29fcdc9 100644 --- a/src/notebook.cc +++ b/src/notebook.cc @@ -175,6 +175,7 @@ bool Notebook::save(int page, bool reparse_needed) { //strip trailing whitespaces and add trailing newline if missing if(Singleton::config->source.strip_trailing_whitespaces) { auto buffer=view->get_buffer(); + buffer->begin_user_action(); for(int line=0;lineget_line_count();line++) { auto iter=buffer->get_iter_at_line(line); auto end_iter=iter; @@ -194,6 +195,7 @@ bool Notebook::save(int page, bool reparse_needed) { auto iter=buffer->end(); if(!iter.starts_line()) buffer->insert(buffer->end(), "\n"); + buffer->end_user_action(); } if(filesystem::write(view->file_path, view->get_buffer())) { From 6ed8a55821d0f14d759d6f5006312c9e15a58513 Mon Sep 17 00:00:00 2001 From: eidheim Date: Sun, 8 Nov 2015 19:35:59 +0100 Subject: [PATCH 07/28] Renamed get_current_path to get_current_folder. --- src/dialogs.h | 2 +- src/dialogs_win.cc | 2 +- src/notebook.cc | 2 +- src/notebook.h | 2 +- src/window.cc | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/dialogs.h b/src/dialogs.h index 02fa700..f85a0b3 100644 --- a/src/dialogs.h +++ b/src/dialogs.h @@ -27,7 +27,7 @@ private: auto application=Glib::RefPtr::cast_static(gio_application); dialog.set_transient_for(*application->window); - auto current_path=application->window->notebook.get_current_path(); + auto current_path=application->window->notebook.get_current_folder(); if(current_path.empty()) current_path=boost::filesystem::current_path(); gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), current_path.string().c_str()); diff --git a/src/dialogs_win.cc b/src/dialogs_win.cc index b2f3ba1..f3a425c 100644 --- a/src/dialogs_win.cc +++ b/src/dialogs_win.cc @@ -97,7 +97,7 @@ private: auto gio_application=Glib::wrap(g_application, true); auto application=Glib::RefPtr::cast_static(gio_application); - auto current_path=application->window->notebook.get_current_path(); + auto current_path=application->window->notebook.get_current_folder(); if(current_path.empty()) current_path=boost::filesystem::current_path(); diff --git a/src/notebook.cc b/src/notebook.cc index 29fcdc9..4703fd6 100644 --- a/src/notebook.cc +++ b/src/notebook.cc @@ -288,7 +288,7 @@ bool Notebook::close_current_page() { return true; } -boost::filesystem::path Notebook::get_current_path() { +boost::filesystem::path Notebook::get_current_folder() { boost::filesystem::path current_path; if(get_current_page()!=-1) diff --git a/src/notebook.h b/src/notebook.h index 91840b6..15e9cd1 100644 --- a/src/notebook.h +++ b/src/notebook.h @@ -21,7 +21,7 @@ public: bool save(int page, bool reparse_needed=false); bool save_current(); void configure(int view_nr); - boost::filesystem::path get_current_path(); + boost::filesystem::path get_current_folder(); private: bool save_modified_dialog(); diff --git a/src/window.cc b/src/window.cc index 4a9446f..722c1aa 100644 --- a/src/window.cc +++ b/src/window.cc @@ -495,7 +495,7 @@ void Window::set_menu_actions() { entry_box.entries.emplace_back(last_run_command, [this](const std::string& content){ if(content!="") { last_run_command=content; - auto run_path=notebook.get_current_path(); + auto run_path=notebook.get_current_folder(); Singleton::terminal->async_print("Running: "+content+'\n'); Singleton::terminal->async_execute(content, run_path, [this, content](int exit_code){ From 39fb97d295f7c8488191e7515ad75f2abdb91749 Mon Sep 17 00:00:00 2001 From: eidheim Date: Sun, 8 Nov 2015 20:27:26 +0100 Subject: [PATCH 08/28] Renamed strip_trailing_whitespaces to cleanup_whitespace_characters --- src/config.cc | 2 +- src/config.h | 2 +- src/files.h | 4 ++-- src/notebook.cc | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/config.cc b/src/config.cc index 19077ad..4883f23 100644 --- a/src/config.cc +++ b/src/config.cc @@ -146,7 +146,7 @@ void Config::get_source() { source.style=source_json.get("style"); source.font=source_json.get("font"); - source.strip_trailing_whitespaces=source_json.get("strip_trailing_whitespaces"); + source.cleanup_whitespace_characters=source_json.get("cleanup_whitespace_characters"); source.show_map = source_json.get("show_map"); source.map_font_size = source_json.get("map_font_size"); diff --git a/src/config.h b/src/config.h index 4ad5f2e..0bfb91d 100644 --- a/src/config.h +++ b/src/config.h @@ -49,7 +49,7 @@ public: std::string font; std::string spellcheck_language; - bool strip_trailing_whitespaces; + bool cleanup_whitespace_characters; bool show_map; std::string map_font_size; diff --git a/src/files.h b/src/files.h index fa38779..a14f680 100644 --- a/src/files.h +++ b/src/files.h @@ -29,8 +29,8 @@ const std::string configjson = " \"font\": \"Monospace\",\n" #endif #endif -" \"strip_trailing_whitespaces_comment\": \"Remove trailing whitespace characters on save, and add trailing newline if missing\",\n" -" \"strip_trailing_whitespaces\": false,\n" +" \"cleanup_whitespace_characters_comment\": \"Remove trailing whitespace characters on save, and add trailing newline if missing\",\n" +" \"cleanup_whitespace_characters\": false,\n" " \"show_map\": true,\n" " \"map_font_size\": \"1\",\n" " \"spellcheck_language_comment\": \"Use \\\"\\\" to set language from your locale settings\",\n" diff --git a/src/notebook.cc b/src/notebook.cc index 4703fd6..6fd29d9 100644 --- a/src/notebook.cc +++ b/src/notebook.cc @@ -172,8 +172,8 @@ bool Notebook::save(int page, bool reparse_needed) { } auto view=get_view(page); if (view->file_path != "" && view->get_buffer()->get_modified()) { - //strip trailing whitespaces and add trailing newline if missing - if(Singleton::config->source.strip_trailing_whitespaces) { + //Remove trailing whitespace characters on save, and add trailing newline if missing + if(Singleton::config->source.cleanup_whitespace_characters) { auto buffer=view->get_buffer(); buffer->begin_user_action(); for(int line=0;lineget_line_count();line++) { From d66edc824dfdc265bf53e3173152589615ad77ec Mon Sep 17 00:00:00 2001 From: eidheim Date: Mon, 9 Nov 2015 09:11:46 +0100 Subject: [PATCH 09/28] Faster clang processing on open file, adds a slight delay first time the next reparse is performed. This is more clean with respect to using precompiled header files in the future. --- src/source_clang.cc | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/src/source_clang.cc b/src/source_clang.cc index ebad9e6..fdaef3d 100644 --- a/src/source_clang.cc +++ b/src/source_clang.cc @@ -113,24 +113,6 @@ void Source::ClangViewParse::init_parse() { parse_thread_mapped=false; parse_thread_stop=false; - auto buffer_map=get_buffer_map(); - //Remove includes for first parse for initial syntax highlighting - auto& str=buffer_map[file_path.string()]; - std::size_t pos=0; - while((pos=str.find("#include", pos))!=std::string::npos) { - auto start_pos=pos; - pos=str.find('\n', pos+8); - if(pos==std::string::npos) - break; - if(start_pos==0 || str[start_pos-1]=='\n') { - str.replace(start_pos, pos-start_pos, pos-start_pos, ' '); - } - pos++; - } - clang_tu = std::unique_ptr(new clang::TranslationUnit(clang_index, file_path.string(), get_compilation_commands(), buffer_map)); - clang_tokens=clang_tu->get_tokens(0, buffer_map.find(file_path.string())->second.size()-1); - update_syntax(); - set_status("parsing..."); if(parse_thread.joinable()) parse_thread.join(); @@ -145,7 +127,11 @@ void Source::ClangViewParse::init_parse() { parse_start(); } else if (parse_thread_mapped && parsing_mutex.try_lock() && parse_thread_buffer_map_mutex.try_lock()) { - int status=clang_tu->ReparseTranslationUnit(parse_thread_buffer_map); + int status=0; + if(!clang_tu) + clang_tu = std::unique_ptr(new clang::TranslationUnit(clang_index, file_path.string(), get_compilation_commands(), parse_thread_buffer_map)); + else + status=clang_tu->ReparseTranslationUnit(parse_thread_buffer_map); if(status==0) clang_tokens=clang_tu->get_tokens(0, parse_thread_buffer_map.find(file_path.string())->second.size()-1); else From 11d01f8fa171f764a697a8d0565e66a8d349ae6d Mon Sep 17 00:00:00 2001 From: eidheim Date: Mon, 9 Nov 2015 09:36:13 +0100 Subject: [PATCH 10/28] Starts reparse right away on buffer change if reparse has not been run before. This avoids several slow autocompletions if reparse has not been run before. --- src/source_clang.cc | 9 ++++++++- src/source_clang.h | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/source_clang.cc b/src/source_clang.cc index fdaef3d..3bf267d 100644 --- a/src/source_clang.cc +++ b/src/source_clang.cc @@ -159,13 +159,20 @@ std::map Source::ClangViewParse::get_buffer_map() cons void Source::ClangViewParse::start_reparse() { parse_thread_mapped=false; source_readable=false; + int delay; + if(!is_reparsed) { + delay=0; + is_reparsed=true; + } + else + delay=1000; delayed_reparse_connection.disconnect(); delayed_reparse_connection=Glib::signal_timeout().connect([this]() { source_readable=false; parse_thread_go=true; set_status("parsing..."); return false; - }, 1000); + }, delay); } std::vector Source::ClangViewParse::get_compilation_commands() { diff --git a/src/source_clang.h b/src/source_clang.h index 20c8214..36470f0 100644 --- a/src/source_clang.h +++ b/src/source_clang.h @@ -61,6 +61,7 @@ namespace Source { static clang::Index clang_index; std::vector get_compilation_commands(); + bool is_reparsed=false; Glib::Dispatcher parse_done; Glib::Dispatcher parse_start; Glib::Dispatcher parse_fail; From 64994a1a5b242f40b5458f830668961f0bb517b2 Mon Sep 17 00:00:00 2001 From: eidheim Date: Mon, 9 Nov 2015 10:02:33 +0100 Subject: [PATCH 11/28] Now runs reparse right after translationunit is created to avoid delays when starting to writing code. --- src/source_clang.cc | 13 ++----------- src/source_clang.h | 1 - 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/src/source_clang.cc b/src/source_clang.cc index 3bf267d..3aa2ab1 100644 --- a/src/source_clang.cc +++ b/src/source_clang.cc @@ -127,11 +127,9 @@ void Source::ClangViewParse::init_parse() { parse_start(); } else if (parse_thread_mapped && parsing_mutex.try_lock() && parse_thread_buffer_map_mutex.try_lock()) { - int status=0; if(!clang_tu) clang_tu = std::unique_ptr(new clang::TranslationUnit(clang_index, file_path.string(), get_compilation_commands(), parse_thread_buffer_map)); - else - status=clang_tu->ReparseTranslationUnit(parse_thread_buffer_map); + int status=clang_tu->ReparseTranslationUnit(parse_thread_buffer_map); if(status==0) clang_tokens=clang_tu->get_tokens(0, parse_thread_buffer_map.find(file_path.string())->second.size()-1); else @@ -159,20 +157,13 @@ std::map Source::ClangViewParse::get_buffer_map() cons void Source::ClangViewParse::start_reparse() { parse_thread_mapped=false; source_readable=false; - int delay; - if(!is_reparsed) { - delay=0; - is_reparsed=true; - } - else - delay=1000; delayed_reparse_connection.disconnect(); delayed_reparse_connection=Glib::signal_timeout().connect([this]() { source_readable=false; parse_thread_go=true; set_status("parsing..."); return false; - }, delay); + }, 1000); } std::vector Source::ClangViewParse::get_compilation_commands() { diff --git a/src/source_clang.h b/src/source_clang.h index 36470f0..20c8214 100644 --- a/src/source_clang.h +++ b/src/source_clang.h @@ -61,7 +61,6 @@ namespace Source { static clang::Index clang_index; std::vector get_compilation_commands(); - bool is_reparsed=false; Glib::Dispatcher parse_done; Glib::Dispatcher parse_start; Glib::Dispatcher parse_fail; From 50d221c3cb881b47ac1b09241a4dedaf0f3fdd39 Mon Sep 17 00:00:00 2001 From: eidheim Date: Mon, 9 Nov 2015 12:11:53 +0100 Subject: [PATCH 12/28] Now again waits with the reparse until buffer is changed, leading to faster file open, meaning less resources used, and avoiding a minor bug introduced in last commit. This should conclude the work preparing to use precompiled headers acrossed files. --- src/source_clang.cc | 19 ++++++++++++++++--- src/source_clang.h | 1 + 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/source_clang.cc b/src/source_clang.cc index 3aa2ab1..9b03afc 100644 --- a/src/source_clang.cc +++ b/src/source_clang.cc @@ -21,7 +21,7 @@ namespace sigc { clang::Index Source::ClangViewParse::clang_index(0, 0); Source::ClangViewParse::ClangViewParse(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path, Glib::RefPtr language): -Source::View(file_path, project_path, language), parse_error(false) { +Source::View(file_path, project_path, language), parse_error(false), first_time_reparse_status(0) { JDEBUG("start"); auto tag_table=get_buffer()->get_tag_table(); @@ -127,9 +127,13 @@ void Source::ClangViewParse::init_parse() { parse_start(); } else if (parse_thread_mapped && parsing_mutex.try_lock() && parse_thread_buffer_map_mutex.try_lock()) { + int status=0; if(!clang_tu) clang_tu = std::unique_ptr(new clang::TranslationUnit(clang_index, file_path.string(), get_compilation_commands(), parse_thread_buffer_map)); - int status=clang_tu->ReparseTranslationUnit(parse_thread_buffer_map); + else { + status=clang_tu->ReparseTranslationUnit(parse_thread_buffer_map); + first_time_reparse_status=2; + } if(status==0) clang_tokens=clang_tu->get_tokens(0, parse_thread_buffer_map.find(file_path.string())->second.size()-1); else @@ -157,13 +161,20 @@ std::map Source::ClangViewParse::get_buffer_map() cons void Source::ClangViewParse::start_reparse() { parse_thread_mapped=false; source_readable=false; + int delay; + if(first_time_reparse_status==0) { + first_time_reparse_status=1; + delay=0; + } + else + delay=1000; delayed_reparse_connection.disconnect(); delayed_reparse_connection=Glib::signal_timeout().connect([this]() { source_readable=false; parse_thread_go=true; set_status("parsing..."); return false; - }, 1000); + }, delay); } std::vector Source::ClangViewParse::get_compilation_commands() { @@ -807,6 +818,8 @@ void Source::ClangViewAutocomplete::autocomplete() { if(autocomplete_thread.joinable()) autocomplete_thread.join(); autocomplete_thread=std::thread([this, ac_data, line_nr, column_nr, buffer_map](){ + while(first_time_reparse_status!=2) + std::this_thread::sleep_for(std::chrono::milliseconds(10)); parsing_mutex.lock(); if(!parse_thread_stop) *ac_data=get_autocomplete_suggestions(line_nr, column_nr, *buffer_map); diff --git a/src/source_clang.h b/src/source_clang.h index 20c8214..3a80aa4 100644 --- a/src/source_clang.h +++ b/src/source_clang.h @@ -38,6 +38,7 @@ namespace Source { std::thread parse_thread; std::atomic parse_thread_stop; std::atomic parse_error; + std::atomic first_time_reparse_status; ///0: not reparsed, 1: will be reparsed, 2: reparsed virtual void show_diagnostic_tooltips(const Gdk::Rectangle &rectangle); virtual void show_type_tooltips(const Gdk::Rectangle &rectangle); From 914ed4b45aa475c13c4ab0418e602be7e4d3e0ba Mon Sep 17 00:00:00 2001 From: eidheim Date: Mon, 9 Nov 2015 20:27:44 +0100 Subject: [PATCH 13/28] Now tries to compile/compile and run even without files if a directory is open. --- src/window.cc | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/window.cc b/src/window.cc index 722c1aa..a55f8b6 100644 --- a/src/window.cc +++ b/src/window.cc @@ -432,9 +432,16 @@ void Window::set_menu_actions() { }); menu->add_action("compile_and_run", [this]() { - if(notebook.get_current_page()==-1 || compiling) + if(compiling) return; - CMake cmake(notebook.get_current_view()->file_path); + boost::filesystem::path cmake_path; + if(notebook.get_current_page()!=-1) + cmake_path=notebook.get_current_view()->file_path.parent_path(); + else + cmake_path=Singleton::directories->current_path; + if(cmake_path.empty()) + return; + CMake cmake(cmake_path); auto executables = cmake.get_functions_parameters("add_executable"); boost::filesystem::path executable_path; if(executables.size()>0 && executables[0].second.size()>0) { @@ -472,9 +479,16 @@ void Window::set_menu_actions() { } }); menu->add_action("compile", [this]() { - if(notebook.get_current_page()==-1 || compiling) + if(compiling) + return; + boost::filesystem::path cmake_path; + if(notebook.get_current_page()!=-1) + cmake_path=notebook.get_current_view()->file_path.parent_path(); + else + cmake_path=Singleton::directories->current_path; + if(cmake_path.empty()) return; - CMake cmake(notebook.get_current_view()->file_path); + CMake cmake(cmake_path); if(cmake.project_path!="") { compiling=true; Singleton::terminal->print("Compiling project "+cmake.project_path.string()+"\n"); From b373cbef55c6886dbb4d876fda2e44265478d8bd Mon Sep 17 00:00:00 2001 From: eidheim Date: Tue, 10 Nov 2015 19:57:29 +0100 Subject: [PATCH 14/28] Have tried precompiled headers, but its leading to less responsive clang-processing. Reverting back to prior clang-processing. --- src/source_clang.cc | 39 +++++++++++++++++++++------------------ src/source_clang.h | 1 - 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/src/source_clang.cc b/src/source_clang.cc index 9b03afc..d7a648e 100644 --- a/src/source_clang.cc +++ b/src/source_clang.cc @@ -21,7 +21,7 @@ namespace sigc { clang::Index Source::ClangViewParse::clang_index(0, 0); Source::ClangViewParse::ClangViewParse(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path, Glib::RefPtr language): -Source::View(file_path, project_path, language), parse_error(false), first_time_reparse_status(0) { +Source::View(file_path, project_path, language), parse_error(false) { JDEBUG("start"); auto tag_table=get_buffer()->get_tag_table(); @@ -113,6 +113,24 @@ void Source::ClangViewParse::init_parse() { parse_thread_mapped=false; parse_thread_stop=false; + auto buffer_map=get_buffer_map(); + //Remove includes for first parse for initial syntax highlighting + auto& str=buffer_map[file_path.string()]; + std::size_t pos=0; + while((pos=str.find("#include", pos))!=std::string::npos) { + auto start_pos=pos; + pos=str.find('\n', pos+8); + if(pos==std::string::npos) + break; + if(start_pos==0 || str[start_pos-1]=='\n') { + str.replace(start_pos, pos-start_pos, pos-start_pos, ' '); + } + pos++; + } + clang_tu = std::unique_ptr(new clang::TranslationUnit(clang_index, file_path.string(), get_compilation_commands(), buffer_map)); + clang_tokens=clang_tu->get_tokens(0, buffer_map.find(file_path.string())->second.size()-1); + update_syntax(); + set_status("parsing..."); if(parse_thread.joinable()) parse_thread.join(); @@ -127,13 +145,7 @@ void Source::ClangViewParse::init_parse() { parse_start(); } else if (parse_thread_mapped && parsing_mutex.try_lock() && parse_thread_buffer_map_mutex.try_lock()) { - int status=0; - if(!clang_tu) - clang_tu = std::unique_ptr(new clang::TranslationUnit(clang_index, file_path.string(), get_compilation_commands(), parse_thread_buffer_map)); - else { - status=clang_tu->ReparseTranslationUnit(parse_thread_buffer_map); - first_time_reparse_status=2; - } + auto status=clang_tu->ReparseTranslationUnit(parse_thread_buffer_map); if(status==0) clang_tokens=clang_tu->get_tokens(0, parse_thread_buffer_map.find(file_path.string())->second.size()-1); else @@ -161,20 +173,13 @@ std::map Source::ClangViewParse::get_buffer_map() cons void Source::ClangViewParse::start_reparse() { parse_thread_mapped=false; source_readable=false; - int delay; - if(first_time_reparse_status==0) { - first_time_reparse_status=1; - delay=0; - } - else - delay=1000; delayed_reparse_connection.disconnect(); delayed_reparse_connection=Glib::signal_timeout().connect([this]() { source_readable=false; parse_thread_go=true; set_status("parsing..."); return false; - }, delay); + }, 1000); } std::vector Source::ClangViewParse::get_compilation_commands() { @@ -818,8 +823,6 @@ void Source::ClangViewAutocomplete::autocomplete() { if(autocomplete_thread.joinable()) autocomplete_thread.join(); autocomplete_thread=std::thread([this, ac_data, line_nr, column_nr, buffer_map](){ - while(first_time_reparse_status!=2) - std::this_thread::sleep_for(std::chrono::milliseconds(10)); parsing_mutex.lock(); if(!parse_thread_stop) *ac_data=get_autocomplete_suggestions(line_nr, column_nr, *buffer_map); diff --git a/src/source_clang.h b/src/source_clang.h index 3a80aa4..20c8214 100644 --- a/src/source_clang.h +++ b/src/source_clang.h @@ -38,7 +38,6 @@ namespace Source { std::thread parse_thread; std::atomic parse_thread_stop; std::atomic parse_error; - std::atomic first_time_reparse_status; ///0: not reparsed, 1: will be reparsed, 2: reparsed virtual void show_diagnostic_tooltips(const Gdk::Rectangle &rectangle); virtual void show_type_tooltips(const Gdk::Rectangle &rectangle); From 92489acfe183355db68ea9186f0da6fe5d083fa4 Mon Sep 17 00:00:00 2001 From: eidheim Date: Wed, 11 Nov 2015 14:04:05 +0100 Subject: [PATCH 15/28] Added message on screen when creating compile_commands.json. --- src/CMakeLists.txt | 5 +- src/cmake.cc | 8 ++- src/dialogs.cc | 82 ++++++++++++++++++++------- src/dialogs.h | 34 ++++------- src/dialogs_unix.cc | 32 +++++++++++ src/{terminal.cc => terminal_unix.cc} | 0 6 files changed, 112 insertions(+), 49 deletions(-) create mode 100644 src/dialogs_unix.cc rename src/{terminal.cc => terminal_unix.cc} (100%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e5e7cdb..7c5bf99 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -72,6 +72,7 @@ set(source_files juci.h singletons.cc cmake.h cmake.cc + dialogs.cc ../libclangmm/src/CodeCompleteResults.cc ../libclangmm/src/CompilationDatabase.cc @@ -92,8 +93,8 @@ if(MSYS) list(APPEND source_files terminal_win.cc) list(APPEND source_files dialogs_win.cc) else() - list(APPEND source_files terminal.cc) - list(APPEND source_files dialogs.cc) + list(APPEND source_files terminal_unix.cc) + list(APPEND source_files dialogs_unix.cc) endif() add_executable(${project_name} ${source_files}) diff --git a/src/cmake.cc b/src/cmake.cc index 7304358..63c67ac 100644 --- a/src/cmake.cc +++ b/src/cmake.cc @@ -2,6 +2,7 @@ #include "singletons.h" #include "filesystem.h" #include +#include "dialogs.h" #include //TODO: remove using namespace std; //TODO: remove @@ -45,8 +46,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) { + auto message=Dialog::Message("Creating "+path.string()+"/compile_commands.json"); + message.wait_until_drawn(); + auto exit_code=Singleton::terminal->execute(Singleton::config->terminal.cmake_command+" . -DCMAKE_EXPORT_COMPILE_COMMANDS=ON", path); + message.hide(); + if(exit_code==EXIT_SUCCESS) { #ifdef _WIN32 //Temporary fix to MSYS2's libclang auto compile_commands_path=path; compile_commands_path+="/compile_commands.json"; diff --git a/src/dialogs.cc b/src/dialogs.cc index 04aff01..c34ff72 100644 --- a/src/dialogs.cc +++ b/src/dialogs.cc @@ -1,32 +1,70 @@ #include "dialogs.h" +#include "juci.h" +#include "singletons.h" -std::string Dialog::open_folder() { - return gtk_dialog("Open Folder", - {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL),std::make_pair("Open", Gtk::RESPONSE_OK)}, - Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER); +namespace sigc { +#ifndef SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE + template + struct functor_trait { + typedef decltype (::sigc::mem_fun(std::declval(), + &Functor::operator())) _intermediate; + typedef typename _intermediate::result_type result_type; + typedef Functor functor_type; + }; +#else + SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE +#endif } -std::string Dialog::new_file() { - return gtk_dialog("New File", - {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL), std::make_pair("Save", Gtk::RESPONSE_OK)}, - Gtk::FILE_CHOOSER_ACTION_SAVE); +Dialog::Message::Message(const std::string &text): Gtk::Window(Gtk::WindowType::WINDOW_POPUP), label(text) { + auto font_desc=label.get_pango_context()->get_font_description(); + font_desc.set_size(font_desc.get_size()*2); + label.create_pango_context(); + label.get_pango_context()->set_font_description(font_desc); + add(label); + + property_decorated()=false; + set_accept_focus(false); + set_skip_taskbar_hint(true); + + auto g_application=g_application_get_default(); + auto gio_application=Glib::wrap(g_application, true); + auto application=Glib::RefPtr::cast_static(gio_application); + set_transient_for(*application->window); + set_position(Gtk::WindowPosition::WIN_POS_CENTER_ON_PARENT); + label.signal_draw().connect([this](const Cairo::RefPtr& cr) { + label_drawn=true; + return false; + }); + show_all(); } -std::string Dialog::new_folder() { - return gtk_dialog("New Folder", - {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL),std::make_pair("Create", Gtk::RESPONSE_OK)}, - Gtk::FILE_CHOOSER_ACTION_CREATE_FOLDER); +void Dialog::Message::wait_until_drawn() { + while(gtk_events_pending() || !label_drawn) + gtk_main_iteration(); } -std::string Dialog::open_file() { - return gtk_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::gtk_dialog(const std::string &title, + const std::vector> &buttons, + Gtk::FileChooserAction gtk_options, + const std::string &file_name) { + Gtk::FileChooserDialog dialog(title, gtk_options); + + 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::cast_static(gio_application); + dialog.set_transient_for(*application->window); + + auto current_path=application->window->notebook.get_current_folder(); + if(current_path.empty()) + current_path=boost::filesystem::current_path(); + gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), current_path.string().c_str()); -std::string Dialog::save_file_as(const boost::filesystem::path &file_path) { - return gtk_dialog("Save File As", - {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL),std::make_pair("Save", Gtk::RESPONSE_OK)}, - Gtk::FILE_CHOOSER_ACTION_SAVE, file_path.string()); + 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); + + for (auto &button : buttons) + dialog.add_button(button.first, button.second); + return dialog.run() == Gtk::RESPONSE_OK ? dialog.get_filename() : ""; } - diff --git a/src/dialogs.h b/src/dialogs.h index f85a0b3..446cc03 100644 --- a/src/dialogs.h +++ b/src/dialogs.h @@ -4,8 +4,6 @@ #include #include #include -#include "singletons.h" -#include "juci.h" class Dialog { public: @@ -15,31 +13,21 @@ public: static std::string new_folder(); static std::string save_file_as(const boost::filesystem::path &file_path); + class Message : public Gtk::Window { + public: + Message(const std::string &text); + + void wait_until_drawn(); + private: + Gtk::Label label; + bool label_drawn=false; + }; + private: static std::string gtk_dialog(const std::string &title, const std::vector> &buttons, Gtk::FileChooserAction gtk_options, - const std::string &file_name = "") { - Gtk::FileChooserDialog dialog(title, gtk_options); - - 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::cast_static(gio_application); - dialog.set_transient_for(*application->window); - - auto current_path=application->window->notebook.get_current_folder(); - if(current_path.empty()) - current_path=boost::filesystem::current_path(); - gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), 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); - - for (auto &button : buttons) - dialog.add_button(button.first, button.second); - return dialog.run() == Gtk::RESPONSE_OK ? dialog.get_filename() : ""; - } + const std::string &file_name = ""); }; #endif //JUCI_DIALOG_H_ diff --git a/src/dialogs_unix.cc b/src/dialogs_unix.cc new file mode 100644 index 0000000..04aff01 --- /dev/null +++ b/src/dialogs_unix.cc @@ -0,0 +1,32 @@ +#include "dialogs.h" + +std::string Dialog::open_folder() { + return gtk_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 gtk_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 gtk_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::open_file() { + return gtk_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_as(const boost::filesystem::path &file_path) { + return gtk_dialog("Save File As", + {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL),std::make_pair("Save", Gtk::RESPONSE_OK)}, + Gtk::FILE_CHOOSER_ACTION_SAVE, file_path.string()); +} + diff --git a/src/terminal.cc b/src/terminal_unix.cc similarity index 100% rename from src/terminal.cc rename to src/terminal_unix.cc From 20bdb25599ae8752126c8b43fb7b9c90ed970877 Mon Sep 17 00:00:00 2001 From: "U-ole-PC\\ole" Date: Wed, 11 Nov 2015 17:39:25 +0100 Subject: [PATCH 16/28] Fixed missing include in dialogs_win. --- src/dialogs_win.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dialogs_win.cc b/src/dialogs_win.cc index f3a425c..377bf16 100644 --- a/src/dialogs_win.cc +++ b/src/dialogs_win.cc @@ -1,5 +1,6 @@ #include "dialogs.h" #include "singletons.h" +#include "juci.h" #undef NTDDI_VERSION #define NTDDI_VERSION NTDDI_VISTA From 43a740a03bce923e5f8a0df5f3c738ad62d4234c Mon Sep 17 00:00:00 2001 From: "U-ole-PC\\ole" Date: Wed, 11 Nov 2015 18:01:10 +0100 Subject: [PATCH 17/28] Now sets font correctly. --- src/dialogs.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dialogs.cc b/src/dialogs.cc index c34ff72..2d4981f 100644 --- a/src/dialogs.cc +++ b/src/dialogs.cc @@ -1,6 +1,7 @@ #include "dialogs.h" #include "juci.h" #include "singletons.h" +#include namespace sigc { #ifndef SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE @@ -18,9 +19,8 @@ namespace sigc { Dialog::Message::Message(const std::string &text): Gtk::Window(Gtk::WindowType::WINDOW_POPUP), label(text) { auto font_desc=label.get_pango_context()->get_font_description(); - font_desc.set_size(font_desc.get_size()*2); - label.create_pango_context(); - label.get_pango_context()->set_font_description(font_desc); + font_desc.set_size(static_cast(round(static_cast(font_desc.get_size())*1.25))); + label.override_font(font_desc); add(label); property_decorated()=false; From 2e54d69c6964618e46fdefb13181062477d466c9 Mon Sep 17 00:00:00 2001 From: eidheim Date: Wed, 11 Nov 2015 18:27:46 +0100 Subject: [PATCH 18/28] Now again uses pango_context instead of depricated override_font. --- src/dialogs.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dialogs.cc b/src/dialogs.cc index 2d4981f..edaab8a 100644 --- a/src/dialogs.cc +++ b/src/dialogs.cc @@ -20,7 +20,7 @@ namespace sigc { Dialog::Message::Message(const std::string &text): Gtk::Window(Gtk::WindowType::WINDOW_POPUP), label(text) { auto font_desc=label.get_pango_context()->get_font_description(); font_desc.set_size(static_cast(round(static_cast(font_desc.get_size())*1.25))); - label.override_font(font_desc); + label.get_pango_context()->set_font_description(font_desc); add(label); property_decorated()=false; From a8367e3cb3c8c1b3189d4609218625b5b18d005b Mon Sep 17 00:00:00 2001 From: eidheim Date: Wed, 11 Nov 2015 20:22:38 +0100 Subject: [PATCH 19/28] Using newer main iteration code in dialogs.cc --- src/dialogs.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dialogs.cc b/src/dialogs.cc index edaab8a..7d3fa57 100644 --- a/src/dialogs.cc +++ b/src/dialogs.cc @@ -40,8 +40,8 @@ Dialog::Message::Message(const std::string &text): Gtk::Window(Gtk::WindowType:: } void Dialog::Message::wait_until_drawn() { - while(gtk_events_pending() || !label_drawn) - gtk_main_iteration(); + while(!label_drawn) + g_main_context_iteration(NULL, false); } std::string Dialog::gtk_dialog(const std::string &title, From 086972d3c6697e7b335653a6c99eabc457456deb Mon Sep 17 00:00:00 2001 From: eidheim Date: Wed, 11 Nov 2015 20:34:43 +0100 Subject: [PATCH 20/28] Dialogs now is centered with respect to the juci application. --- src/dialogs.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dialogs.cc b/src/dialogs.cc index 7d3fa57..293b561 100644 --- a/src/dialogs.cc +++ b/src/dialogs.cc @@ -62,7 +62,7 @@ std::string Dialog::gtk_dialog(const std::string &title, 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_position(Gtk::WindowPosition::WIN_POS_CENTER_ON_PARENT); for (auto &button : buttons) dialog.add_button(button.first, button.second); From a8c77d09cfb358dc8cc2933d7eab4c833eda340c Mon Sep 17 00:00:00 2001 From: eidheim Date: Wed, 11 Nov 2015 20:46:12 +0100 Subject: [PATCH 21/28] Now compiles on older versions of gtk. --- src/cmake.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cmake.cc b/src/cmake.cc index 63c67ac..20ed316 100644 --- a/src/cmake.cc +++ b/src/cmake.cc @@ -46,7 +46,7 @@ CMake::CMake(const boost::filesystem::path &path) { } bool CMake::create_compile_commands(const boost::filesystem::path &path) { - auto message=Dialog::Message("Creating "+path.string()+"/compile_commands.json"); + Dialog::Message message("Creating "+path.string()+"/compile_commands.json"); message.wait_until_drawn(); auto exit_code=Singleton::terminal->execute(Singleton::config->terminal.cmake_command+" . -DCMAKE_EXPORT_COMPILE_COMMANDS=ON", path); message.hide(); From 85d66b8f2d347e325f31dd87e82f561c67af85b3 Mon Sep 17 00:00:00 2001 From: eidheim Date: Wed, 11 Nov 2015 20:57:04 +0100 Subject: [PATCH 22/28] Replaced old gtk_main_iteration with newer g_main_context_iteration. --- src/source_clang.cc | 4 ++-- src/window.cc | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/source_clang.cc b/src/source_clang.cc index d7a648e..bc35142 100644 --- a/src/source_clang.cc +++ b/src/source_clang.cc @@ -963,8 +963,8 @@ Source::ClangViewAutocomplete(file_path, project_path, language) { iter.forward_char(); } get_buffer()->place_cursor(iter); - while(gtk_events_pending()) - gtk_main_iteration(); + while(g_main_context_pending(NULL)) + g_main_context_iteration(NULL, false); scroll_to(get_buffer()->get_insert(), 0.0, 1.0, 0.5); } get_source_buffer()->end_user_action(); diff --git a/src/window.cc b/src/window.cc index a55f8b6..e61cba7 100644 --- a/src/window.cc +++ b/src/window.cc @@ -330,8 +330,8 @@ void Window::set_menu_actions() { }); menu->add_action("source_center_cursor", [this]() { if(notebook.get_current_page()!=-1) { - while(gtk_events_pending()) - gtk_main_iteration(); + while(g_main_context_pending(NULL)) + g_main_context_iteration(NULL, false); if(notebook.get_current_page()!=-1) notebook.get_current_view()->scroll_to(notebook.get_current_view()->get_buffer()->get_insert(), 0.0, 1.0, 0.5); } @@ -396,8 +396,8 @@ void Window::set_menu_actions() { index=std::min(index, end_line_index); buffer->place_cursor(buffer->get_iter_at_line_index(line, index)); - while(gtk_events_pending()) - gtk_main_iteration(); + while(g_main_context_pending(NULL)) + g_main_context_iteration(NULL, false); if(notebook.get_current_page()!=-1) notebook.get_current_view()->scroll_to(notebook.get_current_view()->get_buffer()->get_insert(), 0.0, 1.0, 0.5); } @@ -782,8 +782,8 @@ void Window::goto_line_entry() { if(line>0 && line<=buffer->get_line_count()) { line--; buffer->place_cursor(buffer->get_iter_at_line(line)); - while(gtk_events_pending()) - gtk_main_iteration(); + while(g_main_context_pending(NULL)) + g_main_context_iteration(NULL, false); if(notebook.get_current_page()!=-1) notebook.get_current_view()->scroll_to(buffer->get_insert(), 0.0, 1.0, 0.5); } From 0cb2c6cf2f5ba8756f648c50a93045815668b355 Mon Sep 17 00:00:00 2001 From: eidheim Date: Thu, 12 Nov 2015 10:38:38 +0100 Subject: [PATCH 23/28] Simplified installation and integration of clang-format. --- docs/install.md | 15 ++------------- src/config.cc | 14 +++++++++++++- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/docs/install.md b/docs/install.md index 9693755..fe1bdc4 100644 --- a/docs/install.md +++ b/docs/install.md @@ -4,6 +4,7 @@ Install dependencies: ```sh sudo apt-get install git cmake make g++ libclang-dev pkg-config libboost-system-dev libboost-thread-dev libboost-filesystem-dev libboost-log-dev libgtkmm-3.0-dev libgtksourceviewmm-3.0-dev aspell-en libaspell-dev +sudo apt-get install clang-format-3.6 || sudo apt-get install clang-format-3.5 ``` Get juCi++ source, compile and install: @@ -15,12 +16,6 @@ make sudo make install ``` -To use clang-format for auto-indentation of C++ files (replace \[version\] with an available clang-format version): -```sh -sudo apt-get install clang-format-[version] -sudo ln -s /usr/bin/clang-format-[version] /usr/local/bin/clang-format -``` - ## Ubuntu 14/Linux Mint 17 Install dependencies: ```sh @@ -28,7 +23,7 @@ sudo add-apt-repository ppa:ubuntu-toolchain-r/test sudo apt-get update sudo apt-get install g++-4.9 sudo apt-get remove g++-4.8 -sudo apt-get install git cmake make g++ libclang-3.6-dev pkg-config libboost-system1.55-dev libboost-thread1.55-dev libboost-filesystem1.55-dev libboost-log1.55-dev libgtkmm-3.0-dev libgtksourceviewmm-3.0-dev aspell-en libaspell-dev +sudo apt-get install git cmake make g++ libclang-3.6-dev clang-format-3.6 pkg-config libboost-system1.55-dev libboost-thread1.55-dev libboost-filesystem1.55-dev libboost-log1.55-dev libgtkmm-3.0-dev libgtksourceviewmm-3.0-dev aspell-en libaspell-dev ``` Get juCi++ source, compile and install: @@ -40,12 +35,6 @@ make sudo make install ``` -To use clang-format for auto-indentation of C++ files (replace \[version\] with an available clang-format version): -```sh -sudo apt-get install clang-format-[version] -sudo ln -s /usr/bin/clang-format-[version] /usr/local/bin/clang-format -``` - ## OS X with Homebrew (http://brew.sh/) Install dependencies (installing llvm may take some time): ```sh diff --git a/src/config.cc b/src/config.cc index 4883f23..094d57e 100644 --- a/src/config.cc +++ b/src/config.cc @@ -89,8 +89,20 @@ void Config::retrieve_config() { window.default_size = {cfg.get("default_window_size.width"), cfg.get("default_window_size.height")}; terminal.make_command=cfg.get("project.make_command"); terminal.cmake_command=cfg.get("project.cmake_command"); - terminal.clang_format_command=cfg.get("project.clang_format_command", "clang-format"); terminal.history_size=cfg.get("terminal_history_size"); + + terminal.clang_format_command=cfg.get("project.clang_format_command", "clang-format"); +#ifdef __linux + if(terminal.clang_format_command=="clang-format" && + !boost::filesystem::exists("/usr/bin/clang-format") && !boost::filesystem::exists("/usr/local/bin/clang-format")) { + if(boost::filesystem::exists("/usr/bin/clang-format-3.7")) + terminal.clang_format_command="/usr/bin/clang-format-3.7"; + else if(boost::filesystem::exists("/usr/bin/clang-format-3.6")) + terminal.clang_format_command="/usr/bin/clang-format-3.6"; + else if(boost::filesystem::exists("/usr/bin/clang-format-3.5")) + terminal.clang_format_command="/usr/bin/clang-format-3.5"; + } +#endif } bool Config::check_config_file(const boost::property_tree::ptree &default_cfg, std::string parent_path) { From 2968da7a540b2974b41d2f8242c043d49c845238 Mon Sep 17 00:00:00 2001 From: eidheim Date: Thu, 12 Nov 2015 13:45:53 +0100 Subject: [PATCH 24/28] Dialog::message is now Gtk::MessageDialog. --- src/cmake.cc | 1 - src/dialogs.cc | 23 +++-------------------- src/dialogs.h | 7 +------ 3 files changed, 4 insertions(+), 27 deletions(-) diff --git a/src/cmake.cc b/src/cmake.cc index 20ed316..3e2f1c9 100644 --- a/src/cmake.cc +++ b/src/cmake.cc @@ -47,7 +47,6 @@ CMake::CMake(const boost::filesystem::path &path) { bool CMake::create_compile_commands(const boost::filesystem::path &path) { Dialog::Message message("Creating "+path.string()+"/compile_commands.json"); - message.wait_until_drawn(); auto exit_code=Singleton::terminal->execute(Singleton::config->terminal.cmake_command+" . -DCMAKE_EXPORT_COMPILE_COMMANDS=ON", path); message.hide(); if(exit_code==EXIT_SUCCESS) { diff --git a/src/dialogs.cc b/src/dialogs.cc index 293b561..9f17204 100644 --- a/src/dialogs.cc +++ b/src/dialogs.cc @@ -17,31 +17,14 @@ namespace sigc { #endif } -Dialog::Message::Message(const std::string &text): Gtk::Window(Gtk::WindowType::WINDOW_POPUP), label(text) { - auto font_desc=label.get_pango_context()->get_font_description(); - font_desc.set_size(static_cast(round(static_cast(font_desc.get_size())*1.25))); - label.get_pango_context()->set_font_description(font_desc); - add(label); - - property_decorated()=false; - set_accept_focus(false); - set_skip_taskbar_hint(true); - +Dialog::Message::Message(const std::string &text): Gtk::MessageDialog(text, false, Gtk::MessageType::MESSAGE_INFO, Gtk::ButtonsType::BUTTONS_NONE, true) { auto g_application=g_application_get_default(); auto gio_application=Glib::wrap(g_application, true); auto application=Glib::RefPtr::cast_static(gio_application); set_transient_for(*application->window); set_position(Gtk::WindowPosition::WIN_POS_CENTER_ON_PARENT); - label.signal_draw().connect([this](const Cairo::RefPtr& cr) { - label_drawn=true; - return false; - }); - show_all(); -} - -void Dialog::Message::wait_until_drawn() { - while(!label_drawn) - g_main_context_iteration(NULL, false); + + show_now(); } std::string Dialog::gtk_dialog(const std::string &title, diff --git a/src/dialogs.h b/src/dialogs.h index 446cc03..68e5d19 100644 --- a/src/dialogs.h +++ b/src/dialogs.h @@ -13,14 +13,9 @@ public: static std::string new_folder(); static std::string save_file_as(const boost::filesystem::path &file_path); - class Message : public Gtk::Window { + class Message : public Gtk::MessageDialog { public: Message(const std::string &text); - - void wait_until_drawn(); - private: - Gtk::Label label; - bool label_drawn=false; }; private: From 819d3ffaf6aa59529013801480f05330c2b41d48 Mon Sep 17 00:00:00 2001 From: Ole Christian Eidheim Date: Thu, 12 Nov 2015 13:58:49 +0100 Subject: [PATCH 25/28] Fixed Dialog::Message for Linux. --- src/dialogs.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/dialogs.cc b/src/dialogs.cc index 9f17204..8f66ab0 100644 --- a/src/dialogs.cc +++ b/src/dialogs.cc @@ -25,6 +25,9 @@ Dialog::Message::Message(const std::string &text): Gtk::MessageDialog(text, fals set_position(Gtk::WindowPosition::WIN_POS_CENTER_ON_PARENT); show_now(); + + while(g_main_context_pending(NULL)) + g_main_context_iteration(NULL, false); } std::string Dialog::gtk_dialog(const std::string &title, From 5ad3f43850eb1af75ef7127f8592422b3dd2e941 Mon Sep 17 00:00:00 2001 From: Ole Christian Eidheim Date: Thu, 12 Nov 2015 14:09:26 +0100 Subject: [PATCH 26/28] Fixed minor bug on Debian, where text was selected in Dialog::Message. --- src/dialogs.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dialogs.cc b/src/dialogs.cc index 8f66ab0..64997a9 100644 --- a/src/dialogs.cc +++ b/src/dialogs.cc @@ -17,7 +17,7 @@ namespace sigc { #endif } -Dialog::Message::Message(const std::string &text): Gtk::MessageDialog(text, false, Gtk::MessageType::MESSAGE_INFO, Gtk::ButtonsType::BUTTONS_NONE, true) { +Dialog::Message::Message(const std::string &text): Gtk::MessageDialog(text, false, Gtk::MessageType::MESSAGE_INFO, Gtk::ButtonsType::BUTTONS_CLOSE, true) { auto g_application=g_application_get_default(); auto gio_application=Glib::wrap(g_application, true); auto application=Glib::RefPtr::cast_static(gio_application); From c6857421a9f5d60286f6a069be68a2c88363b2e3 Mon Sep 17 00:00:00 2001 From: Ole Christian Eidheim Date: Thu, 12 Nov 2015 14:31:33 +0100 Subject: [PATCH 27/28] Fixed selected text on Gtk::MessageDialog. --- src/dialogs.cc | 2 +- src/juci.cc | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/dialogs.cc b/src/dialogs.cc index 64997a9..8f66ab0 100644 --- a/src/dialogs.cc +++ b/src/dialogs.cc @@ -17,7 +17,7 @@ namespace sigc { #endif } -Dialog::Message::Message(const std::string &text): Gtk::MessageDialog(text, false, Gtk::MessageType::MESSAGE_INFO, Gtk::ButtonsType::BUTTONS_CLOSE, true) { +Dialog::Message::Message(const std::string &text): Gtk::MessageDialog(text, false, Gtk::MessageType::MESSAGE_INFO, Gtk::ButtonsType::BUTTONS_NONE, true) { auto g_application=g_application_get_default(); auto gio_application=Glib::wrap(g_application, true); auto application=Glib::RefPtr::cast_static(gio_application); diff --git a/src/juci.cc b/src/juci.cc index 6c8a339..6f3eb49 100644 --- a/src/juci.cc +++ b/src/juci.cc @@ -102,6 +102,14 @@ Application::Application() : Gtk::Application("no.sout.juci", Gio::APPLICATION_N Glib::set_application_name("juCi++"); + //Gtk::MessageDialog without buttons caused text to be selected, this prevents that + //Copied from https://mail.gnome.org/archives/gtk-app-devel-list/2007-October/msg00144.html + GtkSettings* settings = gtk_settings_get_default(); + if(settings) { + g_object_set(settings, "gtk-label-select-on-focus", false, NULL); + } + //End copy + window=std::unique_ptr(new Window()); } From b03382f3add6eaa198bcc9eab1fa19d2b37d63e5 Mon Sep 17 00:00:00 2001 From: Ole Christian Eidheim Date: Thu, 12 Nov 2015 14:39:55 +0100 Subject: [PATCH 28/28] Fixed selected text on Gtk::MessageDialog using gtkmm instead. --- src/juci.cc | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/juci.cc b/src/juci.cc index 6f3eb49..98125f1 100644 --- a/src/juci.cc +++ b/src/juci.cc @@ -103,12 +103,7 @@ Application::Application() : Gtk::Application("no.sout.juci", Gio::APPLICATION_N Glib::set_application_name("juCi++"); //Gtk::MessageDialog without buttons caused text to be selected, this prevents that - //Copied from https://mail.gnome.org/archives/gtk-app-devel-list/2007-October/msg00144.html - GtkSettings* settings = gtk_settings_get_default(); - if(settings) { - g_object_set(settings, "gtk-label-select-on-focus", false, NULL); - } - //End copy + Gtk::Settings::get_default()->property_gtk_label_select_on_focus()=false; window=std::unique_ptr(new Window()); }