From 33794a95b583da0875d61434736d6210c14ff320 Mon Sep 17 00:00:00 2001 From: eidheim Date: Tue, 15 Mar 2016 09:18:19 +0100 Subject: [PATCH 01/30] Added drag-and-drop in directory view, and WiP right click --- src/directories.cc | 106 ++++++++++++++++++++++++++++++++++++++++++++- src/directories.h | 43 +++++++++++++----- 2 files changed, 136 insertions(+), 13 deletions(-) diff --git a/src/directories.cc b/src/directories.cc index aa1a3c7..f3e2478 100644 --- a/src/directories.cc +++ b/src/directories.cc @@ -3,6 +3,8 @@ #include #include #include "source.h" +#include "terminal.h" +#include "notebook.h" #include //TODO: remove using namespace std; //TODO: remove @@ -21,10 +23,87 @@ namespace sigc { #endif } +bool Directories::TreeStore::row_drop_possible_vfunc(const Gtk::TreeModel::Path& path, const Gtk::SelectionData& selection_data) const { + return true; +} + +bool Directories::TreeStore::drag_data_received_vfunc(const TreeModel::Path &path, const Gtk::SelectionData &selection_data) { + auto &directories=Directories::get(); + + auto get_target_folder=[this, &directories](const TreeModel::Path &path) { + if(path.size()==1) + return directories.current_path; + else { + auto it=get_iter(path); + if(it) { + auto prev_path=path; + prev_path.up(); + it=get_iter(prev_path); + if(it) + return it->get_value(directories.column_record.path); + } + else { + auto prev_path=path; + prev_path.up(); + if(prev_path.size()==1) + return directories.current_path; + else { + prev_path.up(); + it=get_iter(prev_path); + if(it) + return it->get_value(directories.column_record.path); + } + } + } + return boost::filesystem::path(); + }; + + auto it=directories.get_selection()->get_selected(); + if(it) { + auto source_path=it->get_value(directories.column_record.path); + auto target_path=get_target_folder(path); + + target_path/=source_path.filename(); + + if(source_path==target_path) + return false; + + if(boost::filesystem::exists(target_path)) { + Terminal::get().print("Error: Could not move file: "+target_path.string()+" already exists\n", true); + return false; + } + + boost::system::error_code ec; + boost::filesystem::rename(source_path, target_path, ec); + if(ec) { + Terminal::get().print("Error: Could not move file: "+ec.message()+'\n', true); + return false; + } + + for(int c=0;cfile_path==source_path) { + view->file_path=target_path; + break; + } + } + + Directories::get().update(); + directories.select(target_path); + } + + return false; +} + +bool Directories::TreeStore::drag_data_delete_vfunc (const Gtk::TreeModel::Path &path) { + return false; +} + Directories::Directories() : Gtk::TreeView(), stop_update_thread(false) { this->set_enable_tree_lines(true); - tree_store = Gtk::TreeStore::create(column_record); + tree_store = TreeStore::create(); + tree_store->set_column_types(column_record); set_model(tree_store); append_column("", column_record.name); auto renderer=dynamic_cast(get_column(0)->get_first_cell()); @@ -112,6 +191,18 @@ Directories::Directories() : Gtk::TreeView(), stop_update_thread(false) { update_mutex.unlock(); } }); + + enable_model_drag_source(); + enable_model_drag_dest(); + + menu_item_delete.set_label("Delete"); + menu_item_delete.signal_activate().connect([this] { + std::cout << "delete " << menu_popup_row_path << std::endl; + }); + menu.append(menu_item_delete); + + menu.show_all(); + menu.accelerate(*this); } Directories::~Directories() { @@ -209,6 +300,19 @@ void Directories::select(const boost::filesystem::path &path) { JDEBUG("end"); } +bool Directories::on_button_press_event(GdkEventButton* event) { + if(event->type==GDK_BUTTON_PRESS && event->button==3) { + Gtk::TreeModel::Path path; + if(get_path_at_pos(static_cast(event->x), static_cast(event->y), path)) { + menu_popup_row_path=get_model()->get_iter(path)->get_value(column_record.path); + menu.popup(event->button, event->time); + return true; + } + } + + return Gtk::TreeView::on_button_press_event(event); +} + void Directories::add_path(const boost::filesystem::path& dir_path, const Gtk::TreeModel::Row &parent) { boost::system::error_code ec; auto last_write_time=boost::filesystem::last_write_time(dir_path, ec); diff --git a/src/directories.h b/src/directories.h index 5e5e374..d640af8 100644 --- a/src/directories.h +++ b/src/directories.h @@ -13,18 +13,30 @@ class Directories : public Gtk::TreeView { public: - class ColumnRecord : public Gtk::TreeModel::ColumnRecord { + class TreeStore : public Gtk::TreeStore { + protected: + TreeStore() {} + + bool row_drop_possible_vfunc(const Gtk::TreeModel::Path& path, const Gtk::SelectionData& selection_data) const override; + bool drag_data_received_vfunc(const TreeModel::Path &path, const Gtk::SelectionData &selection_data) override; + bool drag_data_delete_vfunc (const Gtk::TreeModel::Path &path) override; + public: - ColumnRecord() { - add(id); - add(name); - add(path); - add(color); - } - Gtk::TreeModelColumn id; - Gtk::TreeModelColumn name; - Gtk::TreeModelColumn path; - Gtk::TreeModelColumn color; + class ColumnRecord : public Gtk::TreeModel::ColumnRecord { + public: + ColumnRecord() { + add(id); + add(name); + add(path); + add(color); + } + Gtk::TreeModelColumn id; + Gtk::TreeModelColumn name; + Gtk::TreeModelColumn path; + Gtk::TreeModelColumn color; + }; + + static Glib::RefPtr create() {return Glib::RefPtr(new TreeStore());} }; private: @@ -43,10 +55,13 @@ public: std::unique_ptr cmake; boost::filesystem::path current_path; +protected: + bool on_button_press_event(GdkEventButton* event) override; + private: void add_path(const boost::filesystem::path& dir_path, const Gtk::TreeModel::Row &row); Glib::RefPtr tree_store; - ColumnRecord column_record; + TreeStore::ColumnRecord column_record; std::unordered_map > last_write_times; std::mutex update_mutex; @@ -54,6 +69,10 @@ private: std::atomic stop_update_thread; Dispatcher dispatcher; std::vector update_paths; + + Gtk::Menu menu; + Gtk::MenuItem menu_item_delete; + boost::filesystem::path menu_popup_row_path; }; #endif // JUCI_DIRECTORIES_H_ From 9c69f18f18bba8977ffe455dd6d36afc595adb8f Mon Sep 17 00:00:00 2001 From: eidheim Date: Thu, 17 Mar 2016 10:50:15 +0100 Subject: [PATCH 02/30] Major project cleanup. Fixes #97 making it possible to support other build tools --- src/CMakeLists.txt | 2 + src/cmake.cc | 14 +++---- src/cmake.h | 8 ++-- src/directories.cc | 47 ++++++++++----------- src/directories.h | 5 +-- src/filesystem.cc | 8 ++++ src/filesystem.h | 2 + src/notebook.cc | 75 ++++++++------------------------- src/notebook.h | 1 - src/project.cc | 99 +++++++++++++++++++++----------------------- src/project.h | 39 ++++++++--------- src/project_build.cc | 29 +++++++++++++ src/project_build.h | 39 +++++++++++++++++ src/source.cc | 4 +- src/source.h | 5 +-- src/source_clang.cc | 27 +++++------- src/source_clang.h | 8 ++-- src/window.cc | 27 ++++++------ src/window.h | 1 - 19 files changed, 233 insertions(+), 207 deletions(-) create mode 100644 src/project_build.cc create mode 100644 src/project_build.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2f16a24..52ed79e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -86,6 +86,8 @@ set(source_files juci.h dialogs.cc project.h project.cc + project_build.h + project_build.cc dispatcher.h dispatcher.cc diff --git a/src/cmake.cc b/src/cmake.cc index cff8f1b..1ff555f 100644 --- a/src/cmake.cc +++ b/src/cmake.cc @@ -18,7 +18,7 @@ CMake::CMake(const boost::filesystem::path &path) { return false; }; - auto search_path=path; + auto search_path=boost::filesystem::is_directory(path)?path:path.parent_path(); while(true) { auto search_cmake_path=search_path/"CMakeLists.txt"; if(boost::filesystem::exists(search_cmake_path)) @@ -35,7 +35,7 @@ CMake::CMake(const boost::filesystem::path &path) { } } -boost::filesystem::path CMake::get_default_build_path(const boost::filesystem::path &project_path) { +boost::filesystem::path CMake::get_default_build_path() { boost::filesystem::path default_build_path=Config::get().project.default_build_path; const std::string path_variable_project_directory_name=""; @@ -55,7 +55,7 @@ boost::filesystem::path CMake::get_default_build_path(const boost::filesystem::p return default_build_path; } -boost::filesystem::path CMake::get_debug_build_path(const boost::filesystem::path &project_path) { +boost::filesystem::path CMake::get_debug_build_path() { boost::filesystem::path debug_build_path=Config::get().project.debug_build_path; const std::string path_variable_project_directory_name=""; @@ -86,14 +86,14 @@ boost::filesystem::path CMake::get_debug_build_path(const boost::filesystem::pat return debug_build_path; } -bool CMake::create_default_build(const boost::filesystem::path &project_path, bool force) { +bool CMake::update_default_build(bool force) { if(project_path.empty()) return false; if(!boost::filesystem::exists(project_path/"CMakeLists.txt")) return false; - auto default_build_path=get_default_build_path(project_path); + auto default_build_path=get_default_build_path(); if(default_build_path.empty()) return false; if(!boost::filesystem::exists(default_build_path)) { @@ -135,14 +135,14 @@ bool CMake::create_default_build(const boost::filesystem::path &project_path, bo return false; } -bool CMake::create_debug_build(const boost::filesystem::path &project_path) { +bool CMake::update_debug_build() { if(project_path.empty()) return false; if(!boost::filesystem::exists(project_path/"CMakeLists.txt")) return false; - auto debug_build_path=get_debug_build_path(project_path); + auto debug_build_path=get_debug_build_path(); if(debug_build_path.empty()) return false; if(!boost::filesystem::exists(debug_build_path)) { diff --git a/src/cmake.h b/src/cmake.h index bfa463b..9d18f77 100644 --- a/src/cmake.h +++ b/src/cmake.h @@ -11,10 +11,10 @@ public: boost::filesystem::path project_path; std::vector paths; - static boost::filesystem::path get_default_build_path(const boost::filesystem::path &project_path); - static boost::filesystem::path get_debug_build_path(const boost::filesystem::path &project_path); - static bool create_default_build(const boost::filesystem::path &project_path, bool force=false); - static bool create_debug_build(const boost::filesystem::path &project_path); + boost::filesystem::path get_default_build_path(); + boost::filesystem::path get_debug_build_path(); + bool update_default_build(bool force=false); + bool update_debug_build(); boost::filesystem::path get_executable(const boost::filesystem::path &file_path); diff --git a/src/directories.cc b/src/directories.cc index f3e2478..652791d 100644 --- a/src/directories.cc +++ b/src/directories.cc @@ -32,7 +32,7 @@ bool Directories::TreeStore::drag_data_received_vfunc(const TreeModel::Path &pat auto get_target_folder=[this, &directories](const TreeModel::Path &path) { if(path.size()==1) - return directories.current_path; + return directories.path; else { auto it=get_iter(path); if(it) { @@ -46,7 +46,7 @@ bool Directories::TreeStore::drag_data_received_vfunc(const TreeModel::Path &pat auto prev_path=path; prev_path.up(); if(prev_path.size()==1) - return directories.current_path; + return directories.path; else { prev_path.up(); it=get_iter(prev_path); @@ -222,26 +222,21 @@ void Directories::open(const boost::filesystem::path& dir_path) { update_paths.clear(); update_mutex.unlock(); - cmake=std::unique_ptr(new CMake(dir_path)); - CMake::create_default_build(cmake->project_path); - auto project=cmake->get_functions_parameters("project"); - if(project.size()>0 && project[0].second.size()>0) { - auto title=project[0].second[0]; - //TODO: report that set_title does not handle '_' correctly? - size_t pos=0; - while((pos=title.find('_', pos))!=std::string::npos) { - title.replace(pos, 1, "__"); - pos+=2; - } - get_column(0)->set_title(title); + + //TODO: report that set_title does not handle '_' correctly? + auto title=dir_path.filename().string(); + size_t pos=0; + while((pos=title.find('_', pos))!=std::string::npos) { + title.replace(pos, 1, "__"); + pos+=2; } - else - get_column(0)->set_title(""); + get_column(0)->set_title(title); + update_mutex.lock(); add_path(dir_path, Gtk::TreeModel::Row()); update_mutex.unlock(); - current_path=dir_path; + path=dir_path; JDEBUG("end"); } @@ -256,22 +251,22 @@ void Directories::update() { JDEBUG("end"); } -void Directories::select(const boost::filesystem::path &path) { +void Directories::select(const boost::filesystem::path &select_path) { JDEBUG("start"); - if(current_path=="") + if(path=="") return; - if(path.generic_string().substr(0, current_path.generic_string().size()+1)!=current_path.generic_string()+'/') + if(select_path.generic_string().substr(0, path.generic_string().size()+1)!=path.generic_string()+'/') return; std::list paths; boost::filesystem::path parent_path; - if(boost::filesystem::is_directory(path)) - parent_path=path; + if(boost::filesystem::is_directory(select_path)) + parent_path=select_path; else - parent_path=path.parent_path(); + parent_path=select_path.parent_path(); paths.emplace_front(parent_path); - while(parent_path!=current_path) { + while(parent_path!=path) { parent_path=parent_path.parent_path(); paths.emplace_front(parent_path); } @@ -288,8 +283,8 @@ void Directories::select(const boost::filesystem::path &path) { }); } - tree_store->foreach_iter([this, &path](const Gtk::TreeModel::iterator& iter){ - if(iter->get_value(column_record.path)==path) { + tree_store->foreach_iter([this, &select_path](const Gtk::TreeModel::iterator& iter){ + if(iter->get_value(column_record.path)==select_path) { auto tree_path=Gtk::TreePath(iter); expand_to_path(tree_path); set_cursor(tree_path); diff --git a/src/directories.h b/src/directories.h index d640af8..1a8e596 100644 --- a/src/directories.h +++ b/src/directories.h @@ -5,10 +5,10 @@ #include #include #include "boost/filesystem.hpp" -#include "cmake.h" #include #include #include +#include #include "dispatcher.h" class Directories : public Gtk::TreeView { @@ -52,8 +52,7 @@ public: void select(const boost::filesystem::path &path); std::function on_row_activated; - std::unique_ptr cmake; - boost::filesystem::path current_path; + boost::filesystem::path path; protected: bool on_button_press_event(GdkEventButton* event) override; diff --git a/src/filesystem.cc b/src/filesystem.cc index 7c46dea..ec2ca87 100644 --- a/src/filesystem.cc +++ b/src/filesystem.cc @@ -1,6 +1,7 @@ #include #include #include +#include #include "filesystem.h" #include "logging.h" @@ -161,3 +162,10 @@ std::string filesystem::unescape(const std::string &argument) { } return escaped; } + +bool filesystem::file_in_path(const boost::filesystem::path &file_path, const boost::filesystem::path &path) { + if(std::distance(file_path.begin(), file_path.end()) #include -#include "cmake.h" +#include "project_build.h" #include "filesystem.h" #if GTKSOURCEVIEWMM_MAJOR_VERSION > 2 & GTKSOURCEVIEWMM_MINOR_VERSION > 17 @@ -97,24 +97,10 @@ void Notebook::open(const boost::filesystem::path &file_path) { } auto language=Source::guess_language(file_path); - boost::filesystem::path project_path; - auto &directories=Directories::get(); - if(directories.cmake && directories.cmake->project_path!="" && file_path.generic_string().substr(0, directories.cmake->project_path.generic_string().size()+1)==directories.cmake->project_path.generic_string()+'/') - project_path=directories.cmake->project_path; - else { - project_path=file_path.parent_path(); - CMake cmake(project_path); - if(cmake.project_path!="") { - project_path=cmake.project_path; - Terminal::get().print("Project path for "+file_path.string()+" set to "+project_path.string()+"\n"); - } - } - if(language && (language->get_id()=="chdr" || language->get_id()=="cpphdr" || language->get_id()=="c" || language->get_id()=="cpp" || language->get_id()=="objc")) { - CMake::create_default_build(project_path); - source_views.emplace_back(new Source::ClangView(file_path, project_path, language)); - } + if(language && (language->get_id()=="chdr" || language->get_id()=="cpphdr" || language->get_id()=="c" || language->get_id()=="cpp" || language->get_id()=="objc")) + source_views.emplace_back(new Source::ClangView(file_path, language)); else - source_views.emplace_back(new Source::GenericView(file_path, project_path, language)); + source_views.emplace_back(new Source::GenericView(file_path, language)); source_views.back()->scroll_to_cursor_delayed=[this](Source::View* view, bool center, bool show_tooltips) { while(g_main_context_pending(NULL)) @@ -260,25 +246,15 @@ bool Notebook::save(int page) { //If CMakeLists.txt have been modified: boost::filesystem::path project_path; if(view->file_path.filename()=="CMakeLists.txt") { - auto &directories=Directories::get(); - if(directories.cmake && directories.cmake->project_path!="" && view->file_path.generic_string().substr(0, directories.cmake->project_path.generic_string().size()+1)==directories.cmake->project_path.generic_string()+'/') { - if(CMake::create_default_build(directories.cmake->project_path, true)) - project_path=directories.cmake->project_path; - } - else { - CMake cmake(view->file_path.parent_path()); - if(CMake::create_default_build(cmake.project_path, true)) - project_path=cmake.project_path; - } - if(project_path!="") { - auto debug_project_path=CMake::get_debug_build_path(project_path); - if(!debug_project_path.empty() && boost::filesystem::exists(debug_project_path)) - CMake::create_debug_build(project_path); - for(auto source_view: source_views) { - if(auto source_clang_view=dynamic_cast(source_view)) { - if(project_path==source_clang_view->project_path) - source_clang_view->full_reparse_needed=true; - } + auto build=Project::get_build(view->file_path); + build->update_default_build(true); + if(boost::filesystem::exists(build->get_debug_build_path())) + build->update_debug_build(); + + for(auto source_view: source_views) { + if(auto source_clang_view=dynamic_cast(source_view)) { + if(filesystem::file_in_path(source_clang_view->file_path, build->project_path)) + source_clang_view->full_reparse_needed=true; } } } @@ -297,19 +273,6 @@ bool Notebook::save_current() { return save(get_current_page()); } -void Notebook::save_project_files() { - if(get_current_page()==-1) - return; - auto current_view=get_current_view(); - for(int c=0;cget_buffer()->get_modified()) { - if(current_view->project_path==view->project_path) - save(c); - } - } -} - bool Notebook::close(int page) { JDEBUG("start"); if (page!=-1) { @@ -358,14 +321,12 @@ bool Notebook::close_current_page() { } boost::filesystem::path Notebook::get_current_folder() { - boost::filesystem::path current_path; - - if(get_current_page()!=-1) - current_path=get_current_view()->project_path; + if(!Directories::get().path.empty()) + return Directories::get().path; + else if(get_current_page()!=-1) + return get_current_view()->file_path.parent_path(); else - current_path=Directories::get().current_path; - - return current_path; + return boost::filesystem::path(); } bool Notebook::save_modified_dialog(int page) { diff --git a/src/notebook.h b/src/notebook.h index 17dde63..6bb3127 100644 --- a/src/notebook.h +++ b/src/notebook.h @@ -34,7 +34,6 @@ public: void open(const boost::filesystem::path &file_path); bool save(int page); bool save_current(); - void save_project_files(); void configure(int view_nr); boost::filesystem::path get_current_folder(); diff --git a/src/project.cc b/src/project.cc index 774411e..989f0a2 100644 --- a/src/project.cc +++ b/src/project.cc @@ -2,6 +2,7 @@ #include "config.h" #include "terminal.h" #include "filesystem.h" +#include "directories.h" #include #include "menu.h" #include "notebook.h" @@ -9,15 +10,26 @@ #include "debug_clang.h" #endif +boost::filesystem::path Project::debug_last_stop_file_path; std::unordered_map Project::run_arguments; std::unordered_map Project::debug_run_arguments; -std::atomic Project::compiling; -std::atomic Project::debugging; +std::atomic Project::compiling(false); +std::atomic Project::debugging(false); std::pair > Project::debug_stop; -boost::filesystem::path Project::debug_last_stop_file_path; - std::unique_ptr Project::current_language; +void Project::save_files(const boost::filesystem::path &path) { + if(Notebook::get().get_current_page()==-1) + return; + for(int c=0;cget_buffer()->get_modified()) { + if(filesystem::file_in_path(view->file_path, path)) + Notebook::get().save(c); + } + } +} + void Project::debug_update_status(const std::string &debug_status) { if(debug_status.empty()) debug_status_label().set_text(""); @@ -74,39 +86,29 @@ std::unique_ptr Project::get_language() { return std::unique_ptr(new Project::Clang()); } -std::unique_ptr Project::Clang::get_cmake() { - boost::filesystem::path path; +Project::Language::Language() { if(Notebook::get().get_current_page()!=-1) - path=Notebook::get().get_current_view()->file_path.parent_path(); + build=get_build(Notebook::get().get_current_view()->file_path); else - path=Directories::get().current_path; - if(path.empty()) - return nullptr; - auto cmake=std::unique_ptr(new CMake(path)); - if(cmake->project_path.empty()) - return nullptr; - if(!CMake::create_default_build(cmake->project_path)) - return nullptr; - return cmake; + build=get_build(Directories::get().path); } std::pair Project::Clang::get_run_arguments() { - auto cmake=get_cmake(); - if(!cmake) + if(build->get_default_build_path().empty() || !build->update_default_build()) return {"", ""}; - auto project_path=cmake->project_path.string(); + auto project_path=build->project_path.string(); auto run_arguments_it=run_arguments.find(project_path); std::string arguments; if(run_arguments_it!=run_arguments.end()) arguments=run_arguments_it->second; if(arguments.empty()) { - auto executable=cmake->get_executable(Notebook::get().get_current_page()!=-1?Notebook::get().get_current_view()->file_path:"").string(); + auto executable=build->get_executable(Notebook::get().get_current_page()!=-1?Notebook::get().get_current_view()->file_path:"").string(); if(executable!="") { - auto project_path=cmake->project_path; - auto build_path=CMake::get_default_build_path(project_path); + auto project_path=build->project_path; + auto build_path=build->get_default_build_path(); if(!build_path.empty()) { size_t pos=executable.find(project_path.string()); if(pos!=std::string::npos) @@ -115,34 +117,33 @@ std::pair Project::Clang::get_run_arguments() { arguments=filesystem::escape_argument(executable); } else - arguments=filesystem::escape_argument(CMake::get_default_build_path(cmake->project_path)); + arguments=filesystem::escape_argument(build->get_default_build_path()); } return {project_path, arguments}; } void Project::Clang::compile() { - auto cmake=get_cmake(); - if(!cmake) + if(build->get_default_build_path().empty() || !build->update_default_build()) return; - auto default_build_path=CMake::get_default_build_path(cmake->project_path); + auto default_build_path=build->get_default_build_path(); if(default_build_path.empty()) return; compiling=true; - Terminal::get().print("Compiling project "+cmake->project_path.string()+"\n"); + Terminal::get().print("Compiling project "+build->project_path.string()+"\n"); Terminal::get().async_process(Config::get().project.make_command, default_build_path, [this](int exit_status) { compiling=false; }); } void Project::Clang::compile_and_run() { - auto cmake=get_cmake(); - if(!cmake) + if(build->get_default_build_path().empty() || !build->update_default_build()) return; - auto project_path=cmake->project_path; - auto default_build_path=CMake::get_default_build_path(project_path); + auto project_path=build->project_path; + + auto default_build_path=build->get_default_build_path(); if(default_build_path.empty()) return; @@ -152,11 +153,9 @@ void Project::Clang::compile_and_run() { arguments=run_arguments_it->second; if(arguments.empty()) { - arguments=cmake->get_executable(Notebook::get().get_current_page()!=-1?Notebook::get().get_current_view()->file_path:"").string(); + arguments=build->get_executable(Notebook::get().get_current_page()!=-1?Notebook::get().get_current_view()->file_path:"").string(); if(arguments.empty()) { - Terminal::get().print("Could not find add_executable in the following paths:\n"); - for(auto &path: cmake->paths) - Terminal::get().print(" "+path.string()+"\n"); + Terminal::get().print("Warning: could not find executable.\n"); Terminal::get().print("Solution: either use Project Set Run Arguments, or open a source file within a directory where add_executable is set.\n", true); return; } @@ -180,22 +179,21 @@ void Project::Clang::compile_and_run() { #ifdef JUCI_ENABLE_DEBUG std::pair Project::Clang::debug_get_run_arguments() { - auto cmake=get_cmake(); - if(!cmake) + if(build->get_default_build_path().empty() || !build->update_default_build()) return {"", ""}; - auto project_path=cmake->project_path.string(); + auto project_path=build->project_path.string(); auto run_arguments_it=debug_run_arguments.find(project_path); std::string arguments; if(run_arguments_it!=debug_run_arguments.end()) arguments=run_arguments_it->second; if(arguments.empty()) { - auto executable=cmake->get_executable(Notebook::get().get_current_page()!=-1?Notebook::get().get_current_view()->file_path:"").string(); + auto executable=build->get_executable(Notebook::get().get_current_page()!=-1?Notebook::get().get_current_view()->file_path:"").string(); if(executable!="") { - auto project_path=cmake->project_path; - auto build_path=CMake::get_debug_build_path(project_path); + auto project_path=build->project_path; + auto build_path=build->get_debug_build_path(); if(!build_path.empty()) { size_t pos=executable.find(project_path.string()); if(pos!=std::string::npos) @@ -204,22 +202,21 @@ std::pair Project::Clang::debug_get_run_arguments() { arguments=filesystem::escape_argument(executable); } else - arguments=filesystem::escape_argument(CMake::get_debug_build_path(cmake->project_path)); + arguments=filesystem::escape_argument(build->get_debug_build_path()); } return {project_path, arguments}; } void Project::Clang::debug_start() { - auto cmake=get_cmake(); - if(!cmake) + if(build->get_default_build_path().empty() || !build->update_default_build()) return; - auto project_path=cmake->project_path; + auto project_path=build->project_path; - auto debug_build_path=CMake::get_debug_build_path(project_path); + auto debug_build_path=build->get_debug_build_path(); if(debug_build_path.empty()) return; - if(!CMake::create_debug_build(project_path)) + if(!build->update_debug_build()) return; auto run_arguments_it=debug_run_arguments.find(project_path.string()); @@ -228,11 +225,9 @@ void Project::Clang::debug_start() { run_arguments=run_arguments_it->second; if(run_arguments.empty()) { - run_arguments=cmake->get_executable(Notebook::get().get_current_page()!=-1?Notebook::get().get_current_view()->file_path:"").string(); + run_arguments=build->get_executable(Notebook::get().get_current_page()!=-1?Notebook::get().get_current_view()->file_path:"").string(); if(run_arguments.empty()) { - Terminal::get().print("Could not find add_executable in the following paths:\n"); - for(auto &path: cmake->paths) - Terminal::get().print(" "+path.string()+"\n"); + Terminal::get().print("Warning: could not find executable.\n"); Terminal::get().print("Solution: either use Debug Set Run Arguments, or open a source file within a directory where add_executable is set.\n", true); return; } @@ -245,7 +240,7 @@ void Project::Clang::debug_start() { auto breakpoints=std::make_shared > >(); for(int c=0;cproject_path) { + if(filesystem::file_in_path(view->file_path, project_path)) { auto iter=view->get_buffer()->begin(); if(view->get_source_buffer()->get_source_marks_at_iter(iter, "debug_breakpoint").size()>0) breakpoints->emplace_back(view->file_path, iter.get_line()+1); diff --git a/src/project.h b/src/project.h index e3f1fc7..ad2f4bc 100644 --- a/src/project.h +++ b/src/project.h @@ -2,37 +2,40 @@ #define JUCI_PROJECT_H_ #include -#include "cmake.h" #include -#include "directories.h" #include #include +#include #include "tooltips.h" #include "dispatcher.h" +#include "cmake.h" #include +#include "project_build.h" -class Project { -private: - static boost::filesystem::path debug_last_stop_file_path; -public: - static std::unordered_map run_arguments; - static std::unordered_map debug_run_arguments; - static std::atomic compiling; - static std::atomic debugging; - static std::pair > debug_stop; - static void debug_update_stop(); - static void debug_update_status(const std::string &debug_status); +namespace Project { + void save_files(const boost::filesystem::path &path); + + extern boost::filesystem::path debug_last_stop_file_path; + extern std::unordered_map run_arguments; + extern std::unordered_map debug_run_arguments; + extern std::atomic compiling; + extern std::atomic debugging; + extern std::pair > debug_stop; + void debug_update_stop(); + void debug_update_status(const std::string &debug_status); - static Gtk::Label &debug_status_label() { + inline Gtk::Label &debug_status_label() { static Gtk::Label label; return label; } class Language { public: - Language() {} + Language(); virtual ~Language() {} + std::unique_ptr build; + virtual std::pair get_run_arguments() {return {"", ""};} virtual void compile() {} virtual void compile_and_run() {} @@ -63,8 +66,6 @@ public: Clang() : Language() {} ~Clang() { dispatcher.disconnect(); } - std::unique_ptr get_cmake(); - std::pair get_run_arguments() override; void compile() override; void compile_and_run() override; @@ -120,8 +121,8 @@ public: void compile_and_run() override; }; - static std::unique_ptr get_language(); - static std::unique_ptr current_language; + std::unique_ptr get_language(); + extern std::unique_ptr current_language; }; #endif // JUCI_PROJECT_H_ diff --git a/src/project_build.cc b/src/project_build.cc new file mode 100644 index 0000000..84ebdd8 --- /dev/null +++ b/src/project_build.cc @@ -0,0 +1,29 @@ +#include "project_build.h" + +std::unique_ptr Project::get_build(const boost::filesystem::path &path) { + return std::unique_ptr(new CMake(path)); +} + +Project::CMake::CMake(const boost::filesystem::path &path) : Project::Build(), cmake(path) { + project_path=cmake.project_path; +} + +boost::filesystem::path Project::CMake::get_default_build_path() { + return cmake.get_default_build_path(); +} + +bool Project::CMake::update_default_build(bool force) { + return cmake.update_default_build(force); +} + +boost::filesystem::path Project::CMake::get_debug_build_path() { + return cmake.get_debug_build_path(); +} + +bool Project::CMake::update_debug_build() { + return cmake.update_debug_build(); +} + +boost::filesystem::path Project::CMake::get_executable(const boost::filesystem::path &path) { + return cmake.get_executable(path); +} diff --git a/src/project_build.h b/src/project_build.h new file mode 100644 index 0000000..5057e09 --- /dev/null +++ b/src/project_build.h @@ -0,0 +1,39 @@ +#ifndef JUCI_PROJECT_BUILD_H_ +#define JUCI_PROJECT_BUILD_H_ + +#include +#include "cmake.h" + +namespace Project { + class Build { + public: + Build() {} + virtual ~Build() {} + + boost::filesystem::path project_path; + + virtual boost::filesystem::path get_default_build_path() {return boost::filesystem::path();} + virtual bool update_default_build(bool force=false) {return false;} + virtual boost::filesystem::path get_debug_build_path() {return boost::filesystem::path();} + virtual bool update_debug_build() {return false;} + + virtual boost::filesystem::path get_executable(const boost::filesystem::path &path) {return boost::filesystem::path();} + }; + + class CMake : public Build { + ::CMake cmake; + public: + CMake(const boost::filesystem::path &path); + + boost::filesystem::path get_default_build_path() override; + bool update_default_build(bool force=false) override; + boost::filesystem::path get_debug_build_path() override; + bool update_debug_build() override; + + boost::filesystem::path get_executable(const boost::filesystem::path &path) override; + }; + + std::unique_ptr get_build(const boost::filesystem::path &path); +} + +#endif // JUCI_PROJECT_BUILD_H_ diff --git a/src/source.cc b/src/source.cc index a74607b..6de9cda 100644 --- a/src/source.cc +++ b/src/source.cc @@ -82,7 +82,7 @@ std::string Source::FixIt::string(Glib::RefPtr buffer) { ////////////// AspellConfig* Source::View::spellcheck_config=NULL; -Source::View::View(const boost::filesystem::path &file_path, const boost::filesystem::path &project_path, Glib::RefPtr language): file_path(file_path), project_path(project_path), language(language) { +Source::View::View(const boost::filesystem::path &file_path, Glib::RefPtr language): file_path(file_path), language(language) { get_source_buffer()->begin_not_undoable_action(); if(language) { if(filesystem::read_non_utf8(file_path, get_buffer())==-1) @@ -1724,7 +1724,7 @@ std::vector Source::View::spellcheck_get_suggestions(const Gtk::Tex ///////////////////// //// GenericView //// ///////////////////// -Source::GenericView::GenericView(const boost::filesystem::path &file_path, const boost::filesystem::path &project_path, Glib::RefPtr language) : View(file_path, project_path, language) { +Source::GenericView::GenericView(const boost::filesystem::path &file_path, Glib::RefPtr language) : View(file_path, language) { configure(); spellcheck_all=true; diff --git a/src/source.h b/src/source.h index feffbbf..709f78e 100644 --- a/src/source.h +++ b/src/source.h @@ -58,7 +58,7 @@ namespace Source { class View : public Gsv::View { public: - View(const boost::filesystem::path &file_path, const boost::filesystem::path &project_path, Glib::RefPtr language); + View(const boost::filesystem::path &file_path, Glib::RefPtr language); ~View(); virtual void configure(); @@ -74,7 +74,6 @@ namespace Source { void paste(); boost::filesystem::path file_path; - boost::filesystem::path project_path; Glib::RefPtr language; std::function auto_indent; @@ -181,7 +180,7 @@ namespace Source { static Glib::RefPtr create() {return Glib::RefPtr(new CompletionBuffer());} }; public: - GenericView(const boost::filesystem::path &file_path, const boost::filesystem::path &project_path, Glib::RefPtr language); + GenericView(const boost::filesystem::path &file_path, Glib::RefPtr language); void parse_language_file(Glib::RefPtr &completion_buffer, bool &has_context_class, const boost::property_tree::ptree &pt); }; diff --git a/src/source_clang.cc b/src/source_clang.cc index 52800d3..e26962d 100644 --- a/src/source_clang.cc +++ b/src/source_clang.cc @@ -1,7 +1,7 @@ #include "source_clang.h" #include "config.h" #include "terminal.h" -#include "cmake.h" +#include "project.h" #ifdef JUCI_ENABLE_DEBUG #include "debug_clang.h" #endif @@ -22,8 +22,8 @@ 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) { +Source::ClangViewParse::ClangViewParse(const boost::filesystem::path &file_path, Glib::RefPtr language): +Source::View(file_path, language) { JDEBUG("start"); auto tag_table=get_buffer()->get_tag_table(); @@ -174,7 +174,9 @@ void Source::ClangViewParse::soft_reparse() { } std::vector Source::ClangViewParse::get_compilation_commands() { - clang::CompilationDatabase db(CMake::get_default_build_path(project_path).string()); + auto build=Project::get_build(file_path); + build->update_default_build(); + clang::CompilationDatabase db(build->get_default_build_path().string()); clang::CompileCommands commands(file_path.string(), db); std::vector cmds = commands.get_commands(); std::vector arguments; @@ -450,8 +452,8 @@ void Source::ClangViewParse::show_type_tooltips(const Gdk::Rectangle &rectangle) ////////////////////////////// //// ClangViewAutocomplete /// ////////////////////////////// -Source::ClangViewAutocomplete::ClangViewAutocomplete(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path, Glib::RefPtr language): -Source::ClangViewParse(file_path, project_path, language), autocomplete_state(AutocompleteState::IDLE) { +Source::ClangViewAutocomplete::ClangViewAutocomplete(const boost::filesystem::path &file_path, Glib::RefPtr language): +Source::ClangViewParse(file_path, language), autocomplete_state(AutocompleteState::IDLE) { get_buffer()->signal_changed().connect([this](){ if(autocomplete_dialog && autocomplete_dialog->shown) delayed_reparse_connection.disconnect(); @@ -791,8 +793,8 @@ bool Source::ClangViewAutocomplete::full_reparse() { //////////////////////////// //// ClangViewRefactor ///// //////////////////////////// -Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path, Glib::RefPtr language): -Source::ClangViewAutocomplete(file_path, project_path, language) { +Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file_path, Glib::RefPtr language): +Source::ClangViewAutocomplete(file_path, language) { similar_tokens_tag=get_buffer()->create_tag(); similar_tokens_tag->property_weight()=1000; //TODO: replace with Pango::WEIGHT_ULTRAHEAVY in 2016 or so (when Ubuntu 14 is history) @@ -1007,13 +1009,6 @@ Source::ClangViewAutocomplete(file_path, project_path, language) { auto referenced=cursor.get_referenced(); if(referenced) { auto usr=referenced.get_usr(); - boost::filesystem::path referenced_path=referenced.get_source_location().get_path(); - - //Terminal::get().print(usr+'\n', true); //TODO: remove - - //Return empty if referenced is within project - if(referenced_path.generic_string().substr(0, this->project_path.generic_string().size()+1)==this->project_path.generic_string()+'/') - return data; data.emplace_back("clang"); @@ -1169,7 +1164,7 @@ void Source::ClangViewRefactor::tag_similar_tokens(const Token &token) { } } -Source::ClangView::ClangView(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path, Glib::RefPtr language): ClangViewRefactor(file_path, project_path, language) { +Source::ClangView::ClangView(const boost::filesystem::path &file_path, Glib::RefPtr language): ClangViewRefactor(file_path, language) { if(language) { get_source_buffer()->set_highlight_syntax(true); get_source_buffer()->set_language(language); diff --git a/src/source_clang.h b/src/source_clang.h index e392dfd..ba1dfe8 100644 --- a/src/source_clang.h +++ b/src/source_clang.h @@ -24,7 +24,7 @@ namespace Source { int kind; }; - ClangViewParse(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path, Glib::RefPtr language); + ClangViewParse(const boost::filesystem::path &file_path, Glib::RefPtr language); void configure() override; @@ -71,7 +71,7 @@ namespace Source { std::string brief_comments; }; - ClangViewAutocomplete(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path, Glib::RefPtr language); + ClangViewAutocomplete(const boost::filesystem::path &file_path, Glib::RefPtr language); virtual void async_delete(); bool full_reparse() override; @@ -96,7 +96,7 @@ namespace Source { class ClangViewRefactor : public ClangViewAutocomplete { public: - ClangViewRefactor(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path, Glib::RefPtr language); + ClangViewRefactor(const boost::filesystem::path &file_path, Glib::RefPtr language); protected: sigc::connection delayed_tag_similar_tokens_connection; private: @@ -109,7 +109,7 @@ namespace Source { class ClangView : public ClangViewRefactor { public: - ClangView(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path, Glib::RefPtr language); + ClangView(const boost::filesystem::path &file_path, Glib::RefPtr language); void async_delete() override; }; } diff --git a/src/window.cc b/src/window.cc index c50ee81..30f6e16 100644 --- a/src/window.cc +++ b/src/window.cc @@ -6,6 +6,7 @@ //#include "api.h" #include "dialogs.h" #include "filesystem.h" +#include "project.h" namespace sigc { #ifndef SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE @@ -168,7 +169,7 @@ void Window::set_menu_actions() { } else { if(filesystem::write(path)) { - if(Directories::get().current_path!="") + if(Directories::get().path!="") Directories::get().update(); notebook.open(path); Terminal::get().print("New file "+path.string()+" created.\n"); @@ -185,7 +186,7 @@ void Window::set_menu_actions() { boost::system::error_code ec; auto last_write_time=boost::filesystem::last_write_time(path, ec); if(!ec && last_write_time>=time_now) { - if(Directories::get().current_path!="") + if(Directories::get().path!="") Directories::get().update(); Terminal::get().print("New folder "+path.string()+" created.\n"); } @@ -260,7 +261,7 @@ void Window::set_menu_actions() { if(file) { file << notebook.get_current_view()->get_buffer()->get_text(); file.close(); - if(Directories::get().current_path!="") + if(Directories::get().path!="") Directories::get().update(); notebook.open(path); Terminal::get().print("File saved to: " + notebook.get_current_view()->file_path.string()+"\n"); @@ -526,20 +527,22 @@ void Window::set_menu_actions() { if(Project::compiling || Project::debugging) return; + Project::current_language=Project::get_language(); + if(Config::get().project.save_on_compile_or_run) - notebook.save_project_files(); + Project::save_files(Project::current_language->build->project_path); - Project::current_language=Project::get_language(); Project::current_language->compile_and_run(); }); menu.add_action("compile", [this]() { if(Project::compiling || Project::debugging) return; + + Project::current_language=Project::get_language(); if(Config::get().project.save_on_compile_or_run) - notebook.save_project_files(); - - Project::current_language=Project::get_language(); + Project::save_files(Project::current_language->build->project_path); + Project::current_language->compile(); }); @@ -548,7 +551,7 @@ 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, opened directory, current directory"); + label_it->set_text("Run Command directory order: opened directory, file path, current directory"); }; label_it->update(0, ""); entry_box.entries.emplace_back(last_run_command, [this](const std::string& content){ @@ -610,11 +613,11 @@ void Window::set_menu_actions() { Project::current_language->debug_continue(); return; } + + Project::current_language=Project::get_language(); if(Config::get().project.save_on_compile_or_run) - notebook.save_project_files(); - - Project::current_language=Project::get_language(); + Project::save_files(Project::current_language->build->project_path); Project::current_language->debug_start(); }); diff --git a/src/window.h b/src/window.h index f061305..0a3a740 100644 --- a/src/window.h +++ b/src/window.h @@ -4,7 +4,6 @@ #include #include "entrybox.h" #include "notebook.h" -#include "project.h" #include class Window : public Gtk::ApplicationWindow { From 08657ad37f833c9cbf46cf48a389271e1201c098 Mon Sep 17 00:00:00 2001 From: eidheim Date: Thu, 17 Mar 2016 11:28:08 +0100 Subject: [PATCH 03/30] Cleanup: removed notebook and window dependencies in dialogs --- src/dialogs.cc | 38 ++++++++++++++++++++++---------------- src/dialogs.h | 15 +++++++-------- src/dialogs_unix.cc | 22 +++++++++++----------- src/window.cc | 10 +++++----- 4 files changed, 45 insertions(+), 40 deletions(-) diff --git a/src/dialogs.cc b/src/dialogs.cc index 32d234b..1c83d0a 100644 --- a/src/dialogs.cc +++ b/src/dialogs.cc @@ -1,6 +1,4 @@ #include "dialogs.h" -#include "window.h" -#include "notebook.h" #include namespace sigc { @@ -18,7 +16,10 @@ namespace sigc { } Dialog::Message::Message(const std::string &text): Gtk::MessageDialog(text, false, Gtk::MessageType::MESSAGE_INFO, Gtk::ButtonsType::BUTTONS_NONE, true) { - set_transient_for(::Window::get()); + 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->get_active_window()); set_position(Gtk::WindowPosition::WIN_POS_CENTER_ON_PARENT); show_now(); @@ -27,23 +28,28 @@ Dialog::Message::Message(const std::string &text): Gtk::MessageDialog(text, fals g_main_context_iteration(NULL, false); } -std::string Dialog::gtk_dialog(const std::string &title, +std::string Dialog::gtk_dialog(const boost::filesystem::path &path, const std::string &title, const std::vector> &buttons, - Gtk::FileChooserAction gtk_options, - const std::string &file_name) { + Gtk::FileChooserAction gtk_options) { Gtk::FileChooserDialog dialog(title, gtk_options); - dialog.set_transient_for(Window::get()); + auto g_application=g_application_get_default(); + auto gio_application=Glib::wrap(g_application, true); + auto application=Glib::RefPtr::cast_static(gio_application); + dialog.set_transient_for(*application->get_active_window()); + dialog.set_position(Gtk::WindowPosition::WIN_POS_CENTER_ON_PARENT); + + if(title=="Save File As") + gtk_file_chooser_set_filename((GtkFileChooser*)dialog.gobj(), path.c_str()); + else if(!path.empty()) + gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), path.c_str()); + else { + boost::system::error_code ec; + auto current_path=boost::filesystem::current_path(ec); + if(!ec) + gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), current_path.c_str()); + } - auto current_path=Notebook::get().get_current_folder(); - boost::system::error_code ec; - if(current_path.empty()) - current_path=boost::filesystem::current_path(ec); - if(!ec) - 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_ON_PARENT); for (auto &button : buttons) diff --git a/src/dialogs.h b/src/dialogs.h index 68e5d19..9565dd3 100644 --- a/src/dialogs.h +++ b/src/dialogs.h @@ -7,11 +7,11 @@ class Dialog { public: - static std::string open_folder(); - static std::string open_file(); - static std::string new_file(); - static std::string new_folder(); - static std::string save_file_as(const boost::filesystem::path &file_path); + static std::string open_folder(const boost::filesystem::path &path); + static std::string open_file(const boost::filesystem::path &path); + static std::string new_file(const boost::filesystem::path &path); + static std::string new_folder(const boost::filesystem::path &path); + static std::string save_file_as(const boost::filesystem::path &path); class Message : public Gtk::MessageDialog { public: @@ -19,10 +19,9 @@ public: }; private: - static std::string gtk_dialog(const std::string &title, + static std::string gtk_dialog(const boost::filesystem::path &path, const std::string &title, const std::vector> &buttons, - Gtk::FileChooserAction gtk_options, - const std::string &file_name = ""); + Gtk::FileChooserAction gtk_options); }; #endif //JUCI_DIALOG_H_ diff --git a/src/dialogs_unix.cc b/src/dialogs_unix.cc index 04aff01..2512ce8 100644 --- a/src/dialogs_unix.cc +++ b/src/dialogs_unix.cc @@ -1,32 +1,32 @@ #include "dialogs.h" -std::string Dialog::open_folder() { - return gtk_dialog("Open Folder", +std::string Dialog::open_folder(const boost::filesystem::path &path) { + return gtk_dialog(path, "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::string Dialog::new_file(const boost::filesystem::path &path) { + return gtk_dialog(path, "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::string Dialog::new_folder(const boost::filesystem::path &path) { + return gtk_dialog(path, "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::string Dialog::open_file(const boost::filesystem::path &path) { + return gtk_dialog(path, "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::string Dialog::save_file_as(const boost::filesystem::path &path) { + return gtk_dialog(path, "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); } diff --git a/src/window.cc b/src/window.cc index 30f6e16..6a746cc 100644 --- a/src/window.cc +++ b/src/window.cc @@ -162,7 +162,7 @@ void Window::set_menu_actions() { }); menu.add_action("new_file", [this]() { - boost::filesystem::path path = Dialog::new_file(); + boost::filesystem::path path = Dialog::new_file(notebook.get_current_folder()); if(path!="") { if(boost::filesystem::exists(path)) { Terminal::get().print("Error: "+path.string()+" already exists.\n", true); @@ -181,7 +181,7 @@ void Window::set_menu_actions() { }); menu.add_action("new_folder", [this]() { auto time_now=std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); - boost::filesystem::path path = Dialog::new_folder(); + boost::filesystem::path path = Dialog::new_folder(notebook.get_current_folder()); if(path!="" && boost::filesystem::exists(path)) { boost::system::error_code ec; auto last_write_time=boost::filesystem::last_write_time(path, ec); @@ -196,7 +196,7 @@ void Window::set_menu_actions() { } }); menu.add_action("new_project_cpp", [this]() { - boost::filesystem::path project_path = Dialog::new_folder(); + boost::filesystem::path project_path = Dialog::new_folder(notebook.get_current_folder()); if(project_path!="") { auto project_name=project_path.filename().string(); for(size_t c=0;c Date: Thu, 17 Mar 2016 11:54:45 +0100 Subject: [PATCH 04/30] Made EntryBox a singleton for use in Directories, and fixed some includes --- src/entrybox.h | 10 ++- src/project.cc | 5 ++ src/project.h | 7 +- src/source_clang.cc | 2 +- src/window.cc | 159 ++++++++++++++++++++++---------------------- src/window.h | 2 - 6 files changed, 95 insertions(+), 90 deletions(-) diff --git a/src/entrybox.h b/src/entrybox.h index 6f8cecf..3393d59 100644 --- a/src/entrybox.h +++ b/src/entrybox.h @@ -32,9 +32,15 @@ public: Label(std::function update=nullptr); std::function update; }; - -public: + +private: EntryBox(); +public: + static EntryBox &get() { + static EntryBox singleton; + return singleton; + } + Gtk::Box upper_box; Gtk::Box lower_box; void clear(); diff --git a/src/project.cc b/src/project.cc index 1d64e13..a0763a4 100644 --- a/src/project.cc +++ b/src/project.cc @@ -18,6 +18,11 @@ std::atomic Project::debugging(false); std::pair > Project::debug_stop; std::unique_ptr Project::current_language; +Gtk::Label &Project::debug_status_label() { + static Gtk::Label label; + return label; +} + void Project::save_files(const boost::filesystem::path &path) { if(Notebook::get().get_current_page()==-1) return; diff --git a/src/project.h b/src/project.h index ad2f4bc..e81e346 100644 --- a/src/project.h +++ b/src/project.h @@ -8,11 +8,11 @@ #include #include "tooltips.h" #include "dispatcher.h" -#include "cmake.h" #include #include "project_build.h" namespace Project { + Gtk::Label &debug_status_label(); void save_files(const boost::filesystem::path &path); extern boost::filesystem::path debug_last_stop_file_path; @@ -24,11 +24,6 @@ namespace Project { void debug_update_stop(); void debug_update_status(const std::string &debug_status); - inline Gtk::Label &debug_status_label() { - static Gtk::Label label; - return label; - } - class Language { public: Language(); diff --git a/src/source_clang.cc b/src/source_clang.cc index e26962d..4fe0d30 100644 --- a/src/source_clang.cc +++ b/src/source_clang.cc @@ -1,7 +1,7 @@ #include "source_clang.h" #include "config.h" #include "terminal.h" -#include "project.h" +#include "project_build.h" #ifdef JUCI_ENABLE_DEBUG #include "debug_clang.h" #endif diff --git a/src/window.cc b/src/window.cc index 6a746cc..2adcea4 100644 --- a/src/window.cc +++ b/src/window.cc @@ -7,6 +7,7 @@ #include "dialogs.h" #include "filesystem.h" #include "project.h" +#include "entrybox.h" namespace sigc { #ifndef SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE @@ -39,7 +40,7 @@ Window::Window() : notebook(Notebook::get()) { directories_scrolled_window.add(Directories::get()); directory_and_notebook_panes.pack1(directories_scrolled_window, Gtk::SHRINK); notebook_vbox.pack_start(notebook); - notebook_vbox.pack_end(entry_box, Gtk::PACK_SHRINK); + notebook_vbox.pack_end(EntryBox::get(), Gtk::PACK_SHRINK); directory_and_notebook_panes.pack2(notebook_vbox, Gtk::SHRINK); directory_and_notebook_panes.set_position(static_cast(0.2*Config::get().window.default_size.first)); vpaned.set_position(static_cast(0.75*Config::get().window.default_size.second)); @@ -73,17 +74,17 @@ Window::Window() : notebook(Notebook::get()) { Terminal::get().queue_draw(); }); - entry_box.signal_show().connect([this](){ + EntryBox::get().signal_show().connect([this](){ vpaned.set_focus_chain({&directory_and_notebook_panes}); directory_and_notebook_panes.set_focus_chain({¬ebook_vbox}); - notebook_vbox.set_focus_chain({&entry_box}); + notebook_vbox.set_focus_chain({&EntryBox::get()}); }); - entry_box.signal_hide().connect([this](){ + EntryBox::get().signal_hide().connect([this](){ vpaned.unset_focus_chain(); directory_and_notebook_panes.unset_focus_chain(); notebook_vbox.unset_focus_chain(); }); - entry_box.signal_hide().connect([this]() { + EntryBox::get().signal_hide().connect([this]() { if(notebook.get_current_page()!=-1) { notebook.get_current_view()->grab_focus(); } @@ -92,9 +93,9 @@ Window::Window() : notebook(Notebook::get()) { notebook.signal_switch_page().connect([this](Gtk::Widget* page, guint page_num) { if(notebook.get_current_page()!=-1) { auto view=notebook.get_current_view(); - if(search_entry_shown && entry_box.labels.size()>0) { + if(search_entry_shown && EntryBox::get().labels.size()>0) { view->update_search_occurrences=[this](int number){ - entry_box.labels.begin()->update(0, std::to_string(number)); + EntryBox::get().labels.begin()->update(0, std::to_string(number)); }; view->search_highlight(last_search, case_sensitive_search, regex_search); } @@ -115,7 +116,7 @@ Window::Window() : notebook(Notebook::get()) { } }); notebook.signal_page_removed().connect([this](Gtk::Widget* page, guint page_num) { - entry_box.hide(); + EntryBox::get().hide(); }); about.signal_response().connect([this](int d){ @@ -505,23 +506,23 @@ void Window::set_menu_actions() { if(run_arguments->second.empty()) return; - entry_box.clear(); - entry_box.labels.emplace_back(); - auto label_it=entry_box.labels.begin(); + EntryBox::get().clear(); + EntryBox::get().labels.emplace_back(); + auto label_it=EntryBox::get().labels.begin(); label_it->update=[label_it](int state, const std::string& message){ label_it->set_text("Set empty to let juCi++ deduce executable"); }; label_it->update(0, ""); - entry_box.entries.emplace_back(run_arguments->second, [this, run_arguments](const std::string& content){ + EntryBox::get().entries.emplace_back(run_arguments->second, [this, run_arguments](const std::string& content){ Project::run_arguments[run_arguments->first]=content; - entry_box.hide(); + EntryBox::get().hide(); }, 50); - auto entry_it=entry_box.entries.begin(); + auto entry_it=EntryBox::get().entries.begin(); entry_it->set_placeholder_text("Project: Set Run Arguments"); - entry_box.buttons.emplace_back("Project: set run arguments", [this, entry_it](){ + EntryBox::get().buttons.emplace_back("Project: set run arguments", [this, entry_it](){ entry_it->activate(); }); - entry_box.show(); + EntryBox::get().show(); }); menu.add_action("compile_and_run", [this]() { if(Project::compiling || Project::debugging) @@ -547,14 +548,14 @@ void Window::set_menu_actions() { }); menu.add_action("run_command", [this]() { - entry_box.clear(); - entry_box.labels.emplace_back(); - auto label_it=entry_box.labels.begin(); + EntryBox::get().clear(); + EntryBox::get().labels.emplace_back(); + auto label_it=EntryBox::get().labels.begin(); label_it->update=[label_it](int state, const std::string& message){ label_it->set_text("Run Command directory order: opened directory, file path, current directory"); }; label_it->update(0, ""); - entry_box.entries.emplace_back(last_run_command, [this](const std::string& content){ + EntryBox::get().entries.emplace_back(last_run_command, [this](const std::string& content){ if(content!="") { last_run_command=content; auto run_path=notebook.get_current_folder(); @@ -564,14 +565,14 @@ void Window::set_menu_actions() { Terminal::get().async_print(content+" returned: "+std::to_string(exit_status)+'\n'); }); } - entry_box.hide(); + EntryBox::get().hide(); }, 30); - auto entry_it=entry_box.entries.begin(); + auto entry_it=EntryBox::get().entries.begin(); entry_it->set_placeholder_text("Command"); - entry_box.buttons.emplace_back("Run command", [this, entry_it](){ + EntryBox::get().buttons.emplace_back("Run command", [this, entry_it](){ entry_it->activate(); }); - entry_box.show(); + EntryBox::get().show(); }); menu.add_action("kill_last_running", [this]() { @@ -588,23 +589,23 @@ void Window::set_menu_actions() { if(run_arguments->second.empty()) return; - entry_box.clear(); - entry_box.labels.emplace_back(); - auto label_it=entry_box.labels.begin(); + EntryBox::get().clear(); + EntryBox::get().labels.emplace_back(); + auto label_it=EntryBox::get().labels.begin(); label_it->update=[label_it](int state, const std::string& message){ label_it->set_text("Set empty to let juCi++ deduce executable"); }; label_it->update(0, ""); - entry_box.entries.emplace_back(run_arguments->second, [this, run_arguments](const std::string& content){ + EntryBox::get().entries.emplace_back(run_arguments->second, [this, run_arguments](const std::string& content){ Project::debug_run_arguments[run_arguments->first]=content; - entry_box.hide(); + EntryBox::get().hide(); }, 50); - auto entry_it=entry_box.entries.begin(); + auto entry_it=EntryBox::get().entries.begin(); entry_it->set_placeholder_text("Debug: Set Run Arguments"); - entry_box.buttons.emplace_back("Debug: set run arguments", [this, entry_it](){ + EntryBox::get().buttons.emplace_back("Debug: set run arguments", [this, entry_it](){ entry_it->activate(); }); - entry_box.show(); + EntryBox::get().show(); }); menu.add_action("debug_start_continue", [this](){ if(Project::compiling) @@ -650,21 +651,21 @@ void Window::set_menu_actions() { Project::current_language->debug_show_variables(); }); menu.add_action("debug_run_command", [this]() { - entry_box.clear(); - entry_box.entries.emplace_back(last_run_debug_command, [this](const std::string& content){ + EntryBox::get().clear(); + EntryBox::get().entries.emplace_back(last_run_debug_command, [this](const std::string& content){ if(content!="") { if(Project::current_language) Project::current_language->debug_run_command(content); last_run_debug_command=content; } - entry_box.hide(); + EntryBox::get().hide(); }, 30); - auto entry_it=entry_box.entries.begin(); + auto entry_it=EntryBox::get().entries.begin(); entry_it->set_placeholder_text("Debug Command"); - entry_box.buttons.emplace_back("Run debug command", [this, entry_it](){ + EntryBox::get().buttons.emplace_back("Run debug command", [this, entry_it](){ entry_it->activate(); }); - entry_box.show(); + EntryBox::get().show(); }); menu.add_action("debug_toggle_breakpoint", [this](){ if(notebook.get_current_page()!=-1) { @@ -769,7 +770,7 @@ void Window::activate_menu_items(bool activate) { bool Window::on_key_press_event(GdkEventKey *event) { if(event->keyval==GDK_KEY_Escape) { - entry_box.hide(); + EntryBox::get().hide(); } #ifdef __APPLE__ //For Apple's Command-left, right, up, down keys else if((event->state & GDK_META_MASK)>0 && (event->state & GDK_MOD1_MASK)==0) { @@ -816,9 +817,9 @@ bool Window::on_delete_event(GdkEventAny *event) { } void Window::search_and_replace_entry() { - entry_box.clear(); - entry_box.labels.emplace_back(); - auto label_it=entry_box.labels.begin(); + EntryBox::get().clear(); + EntryBox::get().labels.emplace_back(); + auto label_it=EntryBox::get().labels.begin(); label_it->update=[label_it](int state, const std::string& message){ if(state==0) { try { @@ -833,11 +834,11 @@ void Window::search_and_replace_entry() { catch(const std::exception &e) {} } }; - entry_box.entries.emplace_back(last_search, [this](const std::string& content){ + EntryBox::get().entries.emplace_back(last_search, [this](const std::string& content){ if(notebook.get_current_page()!=-1) notebook.get_current_view()->search_forward(); }); - auto search_entry_it=entry_box.entries.begin(); + auto search_entry_it=EntryBox::get().entries.begin(); search_entry_it->set_placeholder_text("Find"); if(notebook.get_current_page()!=-1) { notebook.get_current_view()->update_search_occurrences=[label_it](int number){ @@ -858,11 +859,11 @@ void Window::search_and_replace_entry() { notebook.get_current_view()->search_highlight(search_entry_it->get_text(), case_sensitive_search, regex_search); }); - entry_box.entries.emplace_back(last_replace, [this](const std::string &content){ + EntryBox::get().entries.emplace_back(last_replace, [this](const std::string &content){ if(notebook.get_current_page()!=-1) notebook.get_current_view()->replace_forward(content); }); - auto replace_entry_it=entry_box.entries.begin(); + auto replace_entry_it=EntryBox::get().entries.begin(); replace_entry_it++; replace_entry_it->set_placeholder_text("Replace"); replace_entry_it->signal_key_press_event().connect([this, replace_entry_it](GdkEventKey* event){ @@ -876,25 +877,25 @@ void Window::search_and_replace_entry() { last_replace=replace_entry_it->get_text(); }); - entry_box.buttons.emplace_back("Replace all", [this, replace_entry_it](){ + EntryBox::get().buttons.emplace_back("Replace all", [this, replace_entry_it](){ if(notebook.get_current_page()!=-1) notebook.get_current_view()->replace_all(replace_entry_it->get_text()); }); - entry_box.toggle_buttons.emplace_back("Match case"); - entry_box.toggle_buttons.back().set_active(case_sensitive_search); - entry_box.toggle_buttons.back().on_activate=[this, search_entry_it](){ + EntryBox::get().toggle_buttons.emplace_back("Match case"); + EntryBox::get().toggle_buttons.back().set_active(case_sensitive_search); + EntryBox::get().toggle_buttons.back().on_activate=[this, search_entry_it](){ case_sensitive_search=!case_sensitive_search; if(notebook.get_current_page()!=-1) notebook.get_current_view()->search_highlight(search_entry_it->get_text(), case_sensitive_search, regex_search); }; - entry_box.toggle_buttons.emplace_back("Use regex"); - entry_box.toggle_buttons.back().set_active(regex_search); - entry_box.toggle_buttons.back().on_activate=[this, search_entry_it](){ + EntryBox::get().toggle_buttons.emplace_back("Use regex"); + EntryBox::get().toggle_buttons.back().set_active(regex_search); + EntryBox::get().toggle_buttons.back().on_activate=[this, search_entry_it](){ regex_search=!regex_search; if(notebook.get_current_page()!=-1) notebook.get_current_view()->search_highlight(search_entry_it->get_text(), case_sensitive_search, regex_search); }; - entry_box.signal_hide().connect([this]() { + EntryBox::get().signal_hide().connect([this]() { for(int c=0;cupdate_search_occurrences=nullptr; notebook.get_view(c)->search_highlight("", case_sensitive_search, regex_search); @@ -902,19 +903,19 @@ void Window::search_and_replace_entry() { search_entry_shown=false; }); search_entry_shown=true; - entry_box.show(); + EntryBox::get().show(); } void Window::set_tab_entry() { - entry_box.clear(); + EntryBox::get().clear(); if(notebook.get_current_page()!=-1) { auto tab_char_and_size=notebook.get_current_view()->get_tab_char_and_size(); - entry_box.labels.emplace_back(); - auto label_it=entry_box.labels.begin(); + EntryBox::get().labels.emplace_back(); + auto label_it=EntryBox::get().labels.begin(); - entry_box.entries.emplace_back(std::to_string(tab_char_and_size.second)); - auto entry_tab_size_it=entry_box.entries.begin(); + EntryBox::get().entries.emplace_back(std::to_string(tab_char_and_size.second)); + auto entry_tab_size_it=EntryBox::get().entries.begin(); entry_tab_size_it->set_placeholder_text("Tab size"); char tab_char=tab_char_and_size.first; @@ -924,8 +925,8 @@ void Window::set_tab_entry() { else if(tab_char=='\t') tab_char_string="tab"; - entry_box.entries.emplace_back(tab_char_string); - auto entry_tab_char_it=entry_box.entries.rbegin(); + EntryBox::get().entries.emplace_back(tab_char_string); + auto entry_tab_char_it=EntryBox::get().entries.rbegin(); entry_tab_char_it->set_placeholder_text("Tab char"); const auto activate_function=[this, entry_tab_char_it, entry_tab_size_it, label_it](const std::string& content){ @@ -945,7 +946,7 @@ void Window::set_tab_entry() { if(tab_char!=0 && tab_size>0) { notebook.get_current_view()->set_tab_char_and_size(tab_char, tab_size); - entry_box.hide(); + EntryBox::get().hide(); } else { label_it->set_text("Tab size must be >0 and tab char set to either 'space' or 'tab'"); @@ -956,18 +957,18 @@ void Window::set_tab_entry() { entry_tab_char_it->on_activate=activate_function; entry_tab_size_it->on_activate=activate_function; - entry_box.buttons.emplace_back("Set tab in current buffer", [this, entry_tab_char_it](){ + EntryBox::get().buttons.emplace_back("Set tab in current buffer", [this, entry_tab_char_it](){ entry_tab_char_it->activate(); }); - entry_box.show(); + EntryBox::get().show(); } } void Window::goto_line_entry() { - entry_box.clear(); + EntryBox::get().clear(); if(notebook.get_current_page()!=-1) { - entry_box.entries.emplace_back("", [this](const std::string& content){ + EntryBox::get().entries.emplace_back("", [this](const std::string& content){ if(notebook.get_current_page()!=-1) { auto view=notebook.get_current_view(); try { @@ -980,31 +981,31 @@ void Window::goto_line_entry() { } } catch(const std::exception &e) {} - entry_box.hide(); + EntryBox::get().hide(); } }); - auto entry_it=entry_box.entries.begin(); + auto entry_it=EntryBox::get().entries.begin(); entry_it->set_placeholder_text("Line number"); - entry_box.buttons.emplace_back("Go to line", [this, entry_it](){ + EntryBox::get().buttons.emplace_back("Go to line", [this, entry_it](){ entry_it->activate(); }); - entry_box.show(); + EntryBox::get().show(); } } void Window::rename_token_entry() { - entry_box.clear(); + EntryBox::get().clear(); if(notebook.get_current_page()!=-1) { if(notebook.get_current_view()->get_token) { auto token=std::make_shared(notebook.get_current_view()->get_token()); if(*token) { - entry_box.labels.emplace_back(); - auto label_it=entry_box.labels.begin(); + EntryBox::get().labels.emplace_back(); + auto label_it=EntryBox::get().labels.begin(); label_it->update=[label_it](int state, const std::string& message){ label_it->set_text("Warning: only opened and parsed tabs will have its content renamed, and modified files will be saved"); }; label_it->update(0, ""); - entry_box.entries.emplace_back(token->spelling, [this, token](const std::string& content){ + EntryBox::get().entries.emplace_back(token->spelling, [this, token](const std::string& content){ if(notebook.get_current_page()!=-1 && content!=token->spelling) { std::vector modified_pages; for(int c=0;csoft_reparse_needed=false; - entry_box.hide(); + EntryBox::get().hide(); } }); - auto entry_it=entry_box.entries.begin(); + auto entry_it=EntryBox::get().entries.begin(); entry_it->set_placeholder_text("New name"); - entry_box.buttons.emplace_back("Rename", [this, entry_it](){ + EntryBox::get().buttons.emplace_back("Rename", [this, entry_it](){ entry_it->activate(); }); - entry_box.show(); + EntryBox::get().show(); } } } diff --git a/src/window.h b/src/window.h index 0a3a740..c8ed3ee 100644 --- a/src/window.h +++ b/src/window.h @@ -2,7 +2,6 @@ #define JUCI_WINDOW_H_ #include -#include "entrybox.h" #include "notebook.h" #include @@ -29,7 +28,6 @@ private: Gtk::ScrolledWindow terminal_scrolled_window; Gtk::HBox info_and_status_hbox; Gtk::AboutDialog about; - EntryBox entry_box; void configure(); void set_menu_actions(); From 6784597dac1e89952838eb042a091950e24746e2 Mon Sep 17 00:00:00 2001 From: eidheim Date: Thu, 17 Mar 2016 12:22:26 +0100 Subject: [PATCH 05/30] Added right click delete in directory view --- src/directories.cc | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/directories.cc b/src/directories.cc index 652791d..e0fe9b4 100644 --- a/src/directories.cc +++ b/src/directories.cc @@ -5,6 +5,7 @@ #include "source.h" #include "terminal.h" #include "notebook.h" +#include "filesystem.h" #include //TODO: remove using namespace std; //TODO: remove @@ -197,7 +198,34 @@ Directories::Directories() : Gtk::TreeView(), stop_update_thread(false) { menu_item_delete.set_label("Delete"); menu_item_delete.signal_activate().connect([this] { - std::cout << "delete " << menu_popup_row_path << std::endl; + if(menu_popup_row_path.empty()) + return; + Gtk::MessageDialog dialog((Gtk::Window&)(*get_toplevel()), "Delete!", false, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO); + dialog.set_default_response(Gtk::RESPONSE_NO); + dialog.set_secondary_text("Are you sure you want to delete "+menu_popup_row_path.string()+"?"); + int result = dialog.run(); + if(result==Gtk::RESPONSE_YES) { + bool is_directory=boost::filesystem::is_directory(menu_popup_row_path); + + boost::system::error_code ec; + boost::filesystem::remove_all(menu_popup_row_path, ec); + if(ec) + Terminal::get().print("Error: could not delete "+menu_popup_row_path.string()+": "+ec.message()+"\n", true); + else { + update(); + + for(int c=0;cfile_path, menu_popup_row_path)) + view->get_buffer()->set_modified(); + } + else if(view->file_path==menu_popup_row_path) + view->get_buffer()->set_modified(); + } + } + } }); menu.append(menu_item_delete); From 2f705d2ee76fba32b05708ceadbf3aefb078815a Mon Sep 17 00:00:00 2001 From: eidheim Date: Thu, 17 Mar 2016 13:07:56 +0100 Subject: [PATCH 06/30] Fixes #6, added right-click rename file in directory view --- src/directories.cc | 62 ++++++++++++++++++++++++++++++++++++++++++++-- src/directories.h | 1 + 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/src/directories.cc b/src/directories.cc index e0fe9b4..152828d 100644 --- a/src/directories.cc +++ b/src/directories.cc @@ -6,6 +6,7 @@ #include "terminal.h" #include "notebook.h" #include "filesystem.h" +#include "entrybox.h" #include //TODO: remove using namespace std; //TODO: remove @@ -70,19 +71,32 @@ bool Directories::TreeStore::drag_data_received_vfunc(const TreeModel::Path &pat return false; if(boost::filesystem::exists(target_path)) { - Terminal::get().print("Error: Could not move file: "+target_path.string()+" already exists\n", true); + Terminal::get().print("Error: could not move file: "+target_path.string()+" already exists\n", true); return false; } + bool is_directory=boost::filesystem::is_directory(source_path); + boost::system::error_code ec; boost::filesystem::rename(source_path, target_path, ec); if(ec) { - Terminal::get().print("Error: Could not move file: "+ec.message()+'\n', true); + Terminal::get().print("Error: could not move file: "+ec.message()+'\n', true); return false; } for(int c=0;cfile_path, source_path)) { + auto file_it=view->file_path.begin(); + for(auto source_it=source_path.begin();source_it!=source_path.end();source_it++) + file_it++; + auto new_file_path=target_path; + for(;file_it!=view->file_path.end();file_it++) + new_file_path/=*file_it; + view->file_path=new_file_path; + } + } if(view->file_path==source_path) { view->file_path=target_path; break; @@ -196,6 +210,50 @@ Directories::Directories() : Gtk::TreeView(), stop_update_thread(false) { enable_model_drag_source(); enable_model_drag_dest(); + menu_item_rename.set_label("Rename"); + menu_item_rename.signal_activate().connect([this] { + EntryBox::get().clear(); + auto source_path=std::make_shared(menu_popup_row_path); + EntryBox::get().entries.emplace_back(menu_popup_row_path.filename().string(), [this, source_path](const std::string& content){ + bool is_directory=boost::filesystem::is_directory(*source_path); + + boost::system::error_code ec; + auto target_path=source_path->parent_path()/content; + boost::filesystem::rename(*source_path, target_path, ec); + if(ec) + Terminal::get().print("Error: could not rename "+source_path->string()+": "+ec.message()+'\n'); + else { + update(); + + for(int c=0;cfile_path, *source_path)) { + auto file_it=view->file_path.begin(); + for(auto source_it=source_path->begin();source_it!=source_path->end();source_it++) + file_it++; + auto new_file_path=target_path; + for(;file_it!=view->file_path.end();file_it++) + new_file_path/=*file_it; + view->file_path=new_file_path; + } + } + else if(view->file_path==menu_popup_row_path) + view->get_buffer()->set_modified(); + } + + EntryBox::get().hide(); + } + }); + auto entry_it=EntryBox::get().entries.begin(); + entry_it->set_placeholder_text("Filename"); + EntryBox::get().buttons.emplace_back("Rename file", [this, entry_it](){ + entry_it->activate(); + }); + EntryBox::get().show(); + }); + menu.append(menu_item_rename); + menu_item_delete.set_label("Delete"); menu_item_delete.signal_activate().connect([this] { if(menu_popup_row_path.empty()) diff --git a/src/directories.h b/src/directories.h index 1a8e596..dc4d947 100644 --- a/src/directories.h +++ b/src/directories.h @@ -70,6 +70,7 @@ private: std::vector update_paths; Gtk::Menu menu; + Gtk::MenuItem menu_item_rename; Gtk::MenuItem menu_item_delete; boost::filesystem::path menu_popup_row_path; }; From ef54c0a52c1d15f1207bb54a7082d9467d32bff4 Mon Sep 17 00:00:00 2001 From: eidheim Date: Thu, 17 Mar 2016 13:51:37 +0100 Subject: [PATCH 07/30] Fixes to directory right click methods --- src/directories.cc | 18 ++++++++++++++++-- src/notebook.cc | 4 ++++ src/notebook.h | 1 + 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/directories.cc b/src/directories.cc index 152828d..eba9370 100644 --- a/src/directories.cc +++ b/src/directories.cc @@ -212,6 +212,8 @@ Directories::Directories() : Gtk::TreeView(), stop_update_thread(false) { menu_item_rename.set_label("Rename"); menu_item_rename.signal_activate().connect([this] { + if(menu_popup_row_path.empty()) + return; EntryBox::get().clear(); auto source_path=std::make_shared(menu_popup_row_path); EntryBox::get().entries.emplace_back(menu_popup_row_path.filename().string(), [this, source_path](const std::string& content){ @@ -224,6 +226,7 @@ Directories::Directories() : Gtk::TreeView(), stop_update_thread(false) { Terminal::get().print("Error: could not rename "+source_path->string()+": "+ec.message()+'\n'); else { update(); + select(target_path); for(int c=0;cfile_path=new_file_path; } } - else if(view->file_path==menu_popup_row_path) - view->get_buffer()->set_modified(); + else if(view->file_path==*source_path) { + view->file_path=target_path; + Notebook::get().set_tab_label(c, target_path.filename().string()); + std::string old_language_id; + if(view->language) + old_language_id=view->language->get_id(); + view->language=Source::guess_language(target_path); + std::string new_language_id; + if(view->language) + new_language_id=view->language->get_id(); + if(new_language_id!=old_language_id) + Terminal::get().print("Warning: language for "+target_path.string()+" has changed. Please reopen the file\n"); + } } EntryBox::get().hide(); diff --git a/src/notebook.cc b/src/notebook.cc index ea9124b..df4f9c2 100644 --- a/src/notebook.cc +++ b/src/notebook.cc @@ -329,6 +329,10 @@ boost::filesystem::path Notebook::get_current_folder() { return boost::filesystem::path(); } +void Notebook::set_tab_label(int page, const std::string &label) { + tab_labels.at(get_index(page))->label.set_text(label); +} + bool Notebook::save_modified_dialog(int page) { 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 6bb3127..0654165 100644 --- a/src/notebook.h +++ b/src/notebook.h @@ -36,6 +36,7 @@ public: bool save_current(); void configure(int view_nr); boost::filesystem::path get_current_folder(); + void set_tab_label(int page, const std::string &label); Gtk::Label info; Gtk::Label status; From b64ffd137d9e6f9ca8b16ebf00a2968c5892d0d5 Mon Sep 17 00:00:00 2001 From: eidheim Date: Thu, 17 Mar 2016 16:53:35 +0100 Subject: [PATCH 08/30] Found a couple uninitialized variables through valgrind --- src/source.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/source.h b/src/source.h index 709f78e..1e0a3b0 100644 --- a/src/source.h +++ b/src/source.h @@ -116,8 +116,8 @@ namespace Source { Tooltips type_tooltips; virtual void show_diagnostic_tooltips(const Gdk::Rectangle &rectangle) {} virtual void show_type_tooltips(const Gdk::Rectangle &rectangle) {} - gdouble on_motion_last_x; - gdouble on_motion_last_y; + gdouble on_motion_last_x=0.0; + gdouble on_motion_last_y=0.0; void set_tooltip_and_dialog_events(); std::string get_line(const Gtk::TextIter &iter); From 073584dd8b2faee16e73bbb7bdb5aeda1a49fee8 Mon Sep 17 00:00:00 2001 From: eidheim Date: Thu, 17 Mar 2016 19:41:36 +0100 Subject: [PATCH 09/30] Minor cleanup of directories --- src/directories.cc | 20 ++++++++++---------- src/directories.h | 8 ++++---- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/directories.cc b/src/directories.cc index eba9370..f703f21 100644 --- a/src/directories.cc +++ b/src/directories.cc @@ -25,7 +25,7 @@ namespace sigc { #endif } -bool Directories::TreeStore::row_drop_possible_vfunc(const Gtk::TreeModel::Path& path, const Gtk::SelectionData& selection_data) const { +bool Directories::TreeStore::row_drop_possible_vfunc(const Gtk::TreeModel::Path &path, const Gtk::SelectionData &selection_data) const { return true; } @@ -128,7 +128,7 @@ Directories::Directories() : Gtk::TreeView(), stop_update_thread(false) { set_enable_search(true); //TODO: why does this not work in OS X? set_search_column(column_record.name); - signal_row_activated().connect([this](const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* column){ + signal_row_activated().connect([this](const Gtk::TreeModel::Path &path, Gtk::TreeViewColumn *column){ auto iter = tree_store->get_iter(path); if (iter) { auto filesystem_path=iter->get_value(column_record.path); @@ -143,7 +143,7 @@ Directories::Directories() : Gtk::TreeView(), stop_update_thread(false) { } }); - signal_test_expand_row().connect([this](const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& path){ + signal_test_expand_row().connect([this](const Gtk::TreeModel::iterator &iter, const Gtk::TreeModel::Path &path){ if(iter->children().begin()->get_value(column_record.path)=="") { update_mutex.lock(); add_path(iter->get_value(column_record.path), *iter); @@ -151,7 +151,7 @@ Directories::Directories() : Gtk::TreeView(), stop_update_thread(false) { } return false; }); - signal_row_collapsed().connect([this](const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& path){ + signal_row_collapsed().connect([this](const Gtk::TreeModel::iterator &iter, const Gtk::TreeModel::Path &path){ update_mutex.lock(); auto directory_str=iter->get_value(column_record.path).string(); for(auto it=last_write_times.begin();it!=last_write_times.end();) { @@ -216,7 +216,7 @@ Directories::Directories() : Gtk::TreeView(), stop_update_thread(false) { return; EntryBox::get().clear(); auto source_path=std::make_shared(menu_popup_row_path); - EntryBox::get().entries.emplace_back(menu_popup_row_path.filename().string(), [this, source_path](const std::string& content){ + EntryBox::get().entries.emplace_back(menu_popup_row_path.filename().string(), [this, source_path](const std::string &content){ bool is_directory=boost::filesystem::is_directory(*source_path); boost::system::error_code ec; @@ -311,7 +311,7 @@ Directories::~Directories() { dispatcher.disconnect(); } -void Directories::open(const boost::filesystem::path& dir_path) { +void Directories::open(const boost::filesystem::path &dir_path) { JDEBUG("start"); if(dir_path.empty()) return; @@ -372,7 +372,7 @@ void Directories::select(const boost::filesystem::path &select_path) { } for(auto &a_path: paths) { - tree_store->foreach_iter([this, &a_path](const Gtk::TreeModel::iterator& iter){ + tree_store->foreach_iter([this, &a_path](const Gtk::TreeModel::iterator &iter){ if(iter->get_value(column_record.path)==a_path) { update_mutex.lock(); add_path(a_path, *iter); @@ -383,7 +383,7 @@ void Directories::select(const boost::filesystem::path &select_path) { }); } - tree_store->foreach_iter([this, &select_path](const Gtk::TreeModel::iterator& iter){ + tree_store->foreach_iter([this, &select_path](const Gtk::TreeModel::iterator &iter){ if(iter->get_value(column_record.path)==select_path) { auto tree_path=Gtk::TreePath(iter); expand_to_path(tree_path); @@ -396,7 +396,7 @@ void Directories::select(const boost::filesystem::path &select_path) { } bool Directories::on_button_press_event(GdkEventButton* event) { - if(event->type==GDK_BUTTON_PRESS && event->button==3) { + if(event->type==GDK_BUTTON_PRESS && event->button==GDK_BUTTON_SECONDARY) { Gtk::TreeModel::Path path; if(get_path_at_pos(static_cast(event->x), static_cast(event->y), path)) { menu_popup_row_path=get_model()->get_iter(path)->get_value(column_record.path); @@ -408,7 +408,7 @@ bool Directories::on_button_press_event(GdkEventButton* event) { return Gtk::TreeView::on_button_press_event(event); } -void Directories::add_path(const boost::filesystem::path& dir_path, const Gtk::TreeModel::Row &parent) { +void Directories::add_path(const boost::filesystem::path &dir_path, const Gtk::TreeModel::Row &parent) { boost::system::error_code ec; auto last_write_time=boost::filesystem::last_write_time(dir_path, ec); if(ec) diff --git a/src/directories.h b/src/directories.h index dc4d947..fda3a9f 100644 --- a/src/directories.h +++ b/src/directories.h @@ -17,7 +17,7 @@ public: protected: TreeStore() {} - bool row_drop_possible_vfunc(const Gtk::TreeModel::Path& path, const Gtk::SelectionData& selection_data) const override; + bool row_drop_possible_vfunc(const Gtk::TreeModel::Path &path, const Gtk::SelectionData &selection_data) const override; bool drag_data_received_vfunc(const TreeModel::Path &path, const Gtk::SelectionData &selection_data) override; bool drag_data_delete_vfunc (const Gtk::TreeModel::Path &path) override; @@ -47,7 +47,7 @@ public: return singleton; } ~Directories(); - void open(const boost::filesystem::path& dir_path=""); + void open(const boost::filesystem::path &dir_path=""); void update(); void select(const boost::filesystem::path &path); @@ -55,10 +55,10 @@ public: boost::filesystem::path path; protected: - bool on_button_press_event(GdkEventButton* event) override; + bool on_button_press_event(GdkEventButton *event) override; private: - void add_path(const boost::filesystem::path& dir_path, const Gtk::TreeModel::Row &row); + void add_path(const boost::filesystem::path &dir_path, const Gtk::TreeModel::Row &row); Glib::RefPtr tree_store; TreeStore::ColumnRecord column_record; From 8619686c83bb32bfb0c352772ad3542e58c43258 Mon Sep 17 00:00:00 2001 From: "U-olece-PC\\olece" Date: Thu, 17 Mar 2016 20:15:18 +0100 Subject: [PATCH 10/30] MSYS2 compile fix --- src/dialogs.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dialogs.cc b/src/dialogs.cc index 1c83d0a..f9b6b92 100644 --- a/src/dialogs.cc +++ b/src/dialogs.cc @@ -40,14 +40,14 @@ std::string Dialog::gtk_dialog(const boost::filesystem::path &path, const std::s dialog.set_position(Gtk::WindowPosition::WIN_POS_CENTER_ON_PARENT); if(title=="Save File As") - gtk_file_chooser_set_filename((GtkFileChooser*)dialog.gobj(), path.c_str()); + gtk_file_chooser_set_filename((GtkFileChooser*)dialog.gobj(), path.string().c_str()); else if(!path.empty()) - gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), path.c_str()); + gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), path.string().c_str()); else { boost::system::error_code ec; auto current_path=boost::filesystem::current_path(ec); if(!ec) - gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), current_path.c_str()); + gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), current_path.string().c_str()); } dialog.set_position(Gtk::WindowPosition::WIN_POS_CENTER_ON_PARENT); From d901cca6113663667c3bb958365c8297f987a159 Mon Sep 17 00:00:00 2001 From: eidheim Date: Fri, 18 Mar 2016 10:05:51 +0100 Subject: [PATCH 11/30] Removed Notebook::set_tab_label and used g_signal_emit instead for updating notebook tab labels --- src/directories.cc | 3 ++- src/notebook.cc | 4 ---- src/notebook.h | 1 - 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/directories.cc b/src/directories.cc index f703f21..24d2323 100644 --- a/src/directories.cc +++ b/src/directories.cc @@ -243,7 +243,8 @@ Directories::Directories() : Gtk::TreeView(), stop_update_thread(false) { } else if(view->file_path==*source_path) { view->file_path=target_path; - Notebook::get().set_tab_label(c, target_path.filename().string()); + g_signal_emit_by_name(view->get_buffer()->gobj(), "modified_changed"); + std::string old_language_id; if(view->language) old_language_id=view->language->get_id(); diff --git a/src/notebook.cc b/src/notebook.cc index df4f9c2..ea9124b 100644 --- a/src/notebook.cc +++ b/src/notebook.cc @@ -329,10 +329,6 @@ boost::filesystem::path Notebook::get_current_folder() { return boost::filesystem::path(); } -void Notebook::set_tab_label(int page, const std::string &label) { - tab_labels.at(get_index(page))->label.set_text(label); -} - bool Notebook::save_modified_dialog(int page) { 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 0654165..6bb3127 100644 --- a/src/notebook.h +++ b/src/notebook.h @@ -36,7 +36,6 @@ public: bool save_current(); void configure(int view_nr); boost::filesystem::path get_current_folder(); - void set_tab_label(int page, const std::string &label); Gtk::Label info; Gtk::Label status; From 7118026df275ac27e7b1613057677f890b2a8008 Mon Sep 17 00:00:00 2001 From: eidheim Date: Fri, 18 Mar 2016 10:21:21 +0100 Subject: [PATCH 12/30] Minor debug build cleanup --- src/cmake.cc | 19 ++++--------------- src/cmake.h | 3 +-- src/notebook.cc | 2 +- src/project.cc | 24 +++++++----------------- src/project_build.cc | 4 ++-- src/project_build.h | 4 ++-- 6 files changed, 17 insertions(+), 39 deletions(-) diff --git a/src/cmake.cc b/src/cmake.cc index 1ff555f..4b4150c 100644 --- a/src/cmake.cc +++ b/src/cmake.cc @@ -5,8 +5,6 @@ #include "terminal.h" #include -std::unordered_set CMake::debug_build_needed; - CMake::CMake(const boost::filesystem::path &path) { const auto find_cmake_project=[this](const boost::filesystem::path &cmake_path) { for(auto &line: filesystem::read_lines(cmake_path)) { @@ -108,8 +106,6 @@ bool CMake::update_default_build(bool force) { if(!force && boost::filesystem::exists(default_build_path/"compile_commands.json")) return true; - debug_build_needed.emplace(project_path.string()); - auto compile_commands_path=default_build_path/"compile_commands.json"; Dialog::Message message("Creating/updating default build"); auto exit_status=Terminal::get().process(Config::get().project.cmake_command+" "+ @@ -135,7 +131,7 @@ bool CMake::update_default_build(bool force) { return false; } -bool CMake::update_debug_build() { +bool CMake::update_debug_build(bool force) { if(project_path.empty()) return false; @@ -154,11 +150,8 @@ bool CMake::update_debug_build() { } } - if(boost::filesystem::exists(debug_build_path/"CMakeCache.txt")) { - auto it=debug_build_needed.find(project_path.string()); - if(it==debug_build_needed.end()) - return true; - } + if(!force && boost::filesystem::exists(debug_build_path/"CMakeCache.txt")) + return true; std::unique_ptr message; message=std::unique_ptr(new Dialog::Message("Creating/updating debug build")); @@ -166,12 +159,8 @@ bool CMake::update_debug_build() { filesystem::escape_argument(project_path)+" -DCMAKE_BUILD_TYPE=Debug", debug_build_path); if(message) message->hide(); - if(exit_status==EXIT_SUCCESS) { - auto it=debug_build_needed.find(project_path.string()); - if(it!=debug_build_needed.end()) - debug_build_needed.erase(it); + if(exit_status==EXIT_SUCCESS) return true; - } return false; } diff --git a/src/cmake.h b/src/cmake.h index 9d18f77..eb282db 100644 --- a/src/cmake.h +++ b/src/cmake.h @@ -14,7 +14,7 @@ public: boost::filesystem::path get_default_build_path(); boost::filesystem::path get_debug_build_path(); bool update_default_build(bool force=false); - bool update_debug_build(); + bool update_debug_build(bool force=false); boost::filesystem::path get_executable(const boost::filesystem::path &file_path); @@ -31,6 +31,5 @@ private: void parse(); std::vector get_function_parameters(std::string &data); bool parsed=false; - static std::unordered_set debug_build_needed; }; #endif //JUCI_CMAKE_H_ diff --git a/src/notebook.cc b/src/notebook.cc index ea9124b..0497b21 100644 --- a/src/notebook.cc +++ b/src/notebook.cc @@ -249,7 +249,7 @@ bool Notebook::save(int page) { auto build=Project::get_build(view->file_path); build->update_default_build(true); if(boost::filesystem::exists(build->get_debug_build_path())) - build->update_debug_build(); + build->update_debug_build(true); for(auto source_view: source_views) { if(auto source_clang_view=dynamic_cast(source_view)) { diff --git a/src/project.cc b/src/project.cc index a0763a4..cf2c5d3 100644 --- a/src/project.cc +++ b/src/project.cc @@ -131,13 +131,11 @@ std::pair Project::Clang::get_run_arguments() { return {project_path, arguments}; } -void Project::Clang::compile() { - if(build->get_default_build_path().empty() || !build->update_default_build()) - return; - +void Project::Clang::compile() { auto default_build_path=build->get_default_build_path(); - if(default_build_path.empty()) + if(default_build_path.empty() || !build->update_default_build()) return; + compiling=true; Terminal::get().print("Compiling project "+build->project_path.string()+"\n"); Terminal::get().async_process(Config::get().project.make_command, default_build_path, [this](int exit_status) { @@ -146,15 +144,12 @@ void Project::Clang::compile() { } void Project::Clang::compile_and_run() { - if(build->get_default_build_path().empty() || !build->update_default_build()) + auto default_build_path=build->get_default_build_path(); + if(default_build_path.empty() || !build->update_default_build()) return; auto project_path=build->project_path; - auto default_build_path=build->get_default_build_path(); - if(default_build_path.empty()) - return; - auto run_arguments_it=run_arguments.find(project_path.string()); std::string arguments; if(run_arguments_it!=run_arguments.end()) @@ -217,15 +212,10 @@ std::pair Project::Clang::debug_get_run_arguments() { } void Project::Clang::debug_start() { - if(build->get_default_build_path().empty() || !build->update_default_build()) - return; - auto project_path=build->project_path; - auto debug_build_path=build->get_debug_build_path(); - if(debug_build_path.empty()) - return; - if(!build->update_debug_build()) + if(debug_build_path.empty() || !build->update_debug_build()) return; + auto project_path=build->project_path; auto run_arguments_it=debug_run_arguments.find(project_path.string()); std::string run_arguments; diff --git a/src/project_build.cc b/src/project_build.cc index 84ebdd8..5da6b64 100644 --- a/src/project_build.cc +++ b/src/project_build.cc @@ -20,8 +20,8 @@ boost::filesystem::path Project::CMake::get_debug_build_path() { return cmake.get_debug_build_path(); } -bool Project::CMake::update_debug_build() { - return cmake.update_debug_build(); +bool Project::CMake::update_debug_build(bool force) { + return cmake.update_debug_build(force); } boost::filesystem::path Project::CMake::get_executable(const boost::filesystem::path &path) { diff --git a/src/project_build.h b/src/project_build.h index 5057e09..ffd36cb 100644 --- a/src/project_build.h +++ b/src/project_build.h @@ -15,7 +15,7 @@ namespace Project { virtual boost::filesystem::path get_default_build_path() {return boost::filesystem::path();} virtual bool update_default_build(bool force=false) {return false;} virtual boost::filesystem::path get_debug_build_path() {return boost::filesystem::path();} - virtual bool update_debug_build() {return false;} + virtual bool update_debug_build(bool force=false) {return false;} virtual boost::filesystem::path get_executable(const boost::filesystem::path &path) {return boost::filesystem::path();} }; @@ -28,7 +28,7 @@ namespace Project { boost::filesystem::path get_default_build_path() override; bool update_default_build(bool force=false) override; boost::filesystem::path get_debug_build_path() override; - bool update_debug_build() override; + bool update_debug_build(bool force=false) override; boost::filesystem::path get_executable(const boost::filesystem::path &path) override; }; From 7912649b5bdb99fec50621ab38b2dd465ce73e95 Mon Sep 17 00:00:00 2001 From: eidheim Date: Fri, 18 Mar 2016 10:38:23 +0100 Subject: [PATCH 13/30] Replaced c-style cast with reinterpret_cast in dialogs.cc --- src/dialogs.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dialogs.cc b/src/dialogs.cc index f9b6b92..832c5be 100644 --- a/src/dialogs.cc +++ b/src/dialogs.cc @@ -40,14 +40,14 @@ std::string Dialog::gtk_dialog(const boost::filesystem::path &path, const std::s dialog.set_position(Gtk::WindowPosition::WIN_POS_CENTER_ON_PARENT); if(title=="Save File As") - gtk_file_chooser_set_filename((GtkFileChooser*)dialog.gobj(), path.string().c_str()); + gtk_file_chooser_set_filename(reinterpret_cast(dialog.gobj()), path.string().c_str()); else if(!path.empty()) - gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), path.string().c_str()); + gtk_file_chooser_set_current_folder(reinterpret_cast(dialog.gobj()), path.string().c_str()); else { boost::system::error_code ec; auto current_path=boost::filesystem::current_path(ec); if(!ec) - gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), current_path.string().c_str()); + gtk_file_chooser_set_current_folder(reinterpret_cast(dialog.gobj()), current_path.string().c_str()); } dialog.set_position(Gtk::WindowPosition::WIN_POS_CENTER_ON_PARENT); From 7546e9658e8b5dd442df189c6d859d9616139fd3 Mon Sep 17 00:00:00 2001 From: eidheim Date: Fri, 18 Mar 2016 10:43:01 +0100 Subject: [PATCH 14/30] Got rid of double dialog.set_position calls in dialogs.cc --- src/dialogs.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/dialogs.cc b/src/dialogs.cc index 832c5be..c135a4c 100644 --- a/src/dialogs.cc +++ b/src/dialogs.cc @@ -50,8 +50,6 @@ std::string Dialog::gtk_dialog(const boost::filesystem::path &path, const std::s gtk_file_chooser_set_current_folder(reinterpret_cast(dialog.gobj()), current_path.string().c_str()); } - dialog.set_position(Gtk::WindowPosition::WIN_POS_CENTER_ON_PARENT); - for (auto &button : buttons) dialog.add_button(button.first, button.second); return dialog.run() == Gtk::RESPONSE_OK ? dialog.get_filename() : ""; From a662b0a2da4154616ac4ec9c77729b49a9907a3c Mon Sep 17 00:00:00 2001 From: eidheim Date: Sat, 19 Mar 2016 13:48:20 +0100 Subject: [PATCH 15/30] Getting default/debug path cleanup --- src/cmake.cc | 57 ++-------------------------------------- src/cmake.h | 6 ++--- src/project_build.cc | 62 +++++++++++++++++++++++++++++++++++++------- src/project_build.h | 6 ++--- 4 files changed, 59 insertions(+), 72 deletions(-) diff --git a/src/cmake.cc b/src/cmake.cc index 4b4150c..01e372c 100644 --- a/src/cmake.cc +++ b/src/cmake.cc @@ -33,65 +33,13 @@ CMake::CMake(const boost::filesystem::path &path) { } } -boost::filesystem::path CMake::get_default_build_path() { - boost::filesystem::path default_build_path=Config::get().project.default_build_path; - - const std::string path_variable_project_directory_name=""; - size_t pos=0; - auto default_build_path_string=default_build_path.string(); - auto path_filename_string=project_path.filename().string(); - while((pos=default_build_path_string.find(path_variable_project_directory_name, pos))!=std::string::npos) { - default_build_path_string.replace(pos, path_variable_project_directory_name.size(), path_filename_string); - pos+=path_filename_string.size(); - } - if(pos!=0) - default_build_path=default_build_path_string; - - if(default_build_path.is_relative()) - default_build_path=project_path/default_build_path; - - return default_build_path; -} - -boost::filesystem::path CMake::get_debug_build_path() { - boost::filesystem::path debug_build_path=Config::get().project.debug_build_path; - - const std::string path_variable_project_directory_name=""; - size_t pos=0; - auto debug_build_path_string=debug_build_path.string(); - auto path_filename_string=project_path.filename().string(); - while((pos=debug_build_path_string.find(path_variable_project_directory_name, pos))!=std::string::npos) { - debug_build_path_string.replace(pos, path_variable_project_directory_name.size(), path_filename_string); - pos+=path_filename_string.size(); - } - if(pos!=0) - debug_build_path=debug_build_path_string; - - const std::string path_variable_default_build_path=""; - pos=0; - debug_build_path_string=debug_build_path.string(); - auto default_build_path=Config::get().project.default_build_path; - while((pos=debug_build_path_string.find(path_variable_default_build_path, pos))!=std::string::npos) { - debug_build_path_string.replace(pos, path_variable_default_build_path.size(), default_build_path); - pos+=default_build_path.size(); - } - if(pos!=0) - debug_build_path=debug_build_path_string; - - if(debug_build_path.is_relative()) - debug_build_path=project_path/debug_build_path; - - return debug_build_path; -} - -bool CMake::update_default_build(bool force) { +bool CMake::update_default_build(const boost::filesystem::path &default_build_path, bool force) { if(project_path.empty()) return false; if(!boost::filesystem::exists(project_path/"CMakeLists.txt")) return false; - auto default_build_path=get_default_build_path(); if(default_build_path.empty()) return false; if(!boost::filesystem::exists(default_build_path)) { @@ -131,14 +79,13 @@ bool CMake::update_default_build(bool force) { return false; } -bool CMake::update_debug_build(bool force) { +bool CMake::update_debug_build(const boost::filesystem::path &debug_build_path, bool force) { if(project_path.empty()) return false; if(!boost::filesystem::exists(project_path/"CMakeLists.txt")) return false; - auto debug_build_path=get_debug_build_path(); if(debug_build_path.empty()) return false; if(!boost::filesystem::exists(debug_build_path)) { diff --git a/src/cmake.h b/src/cmake.h index eb282db..004688d 100644 --- a/src/cmake.h +++ b/src/cmake.h @@ -11,10 +11,8 @@ public: boost::filesystem::path project_path; std::vector paths; - boost::filesystem::path get_default_build_path(); - boost::filesystem::path get_debug_build_path(); - bool update_default_build(bool force=false); - bool update_debug_build(bool force=false); + bool update_default_build(const boost::filesystem::path &default_build_path, bool force=false); + bool update_debug_build(const boost::filesystem::path &debug_build_path, bool force=false); boost::filesystem::path get_executable(const boost::filesystem::path &file_path); diff --git a/src/project_build.cc b/src/project_build.cc index 5da6b64..534742b 100644 --- a/src/project_build.cc +++ b/src/project_build.cc @@ -1,27 +1,71 @@ #include "project_build.h" +#include "config.h" std::unique_ptr Project::get_build(const boost::filesystem::path &path) { return std::unique_ptr(new CMake(path)); } -Project::CMake::CMake(const boost::filesystem::path &path) : Project::Build(), cmake(path) { - project_path=cmake.project_path; +boost::filesystem::path Project::Build::get_default_build_path() { + boost::filesystem::path default_build_path=Config::get().project.default_build_path; + + const std::string path_variable_project_directory_name=""; + size_t pos=0; + auto default_build_path_string=default_build_path.string(); + auto path_filename_string=project_path.filename().string(); + while((pos=default_build_path_string.find(path_variable_project_directory_name, pos))!=std::string::npos) { + default_build_path_string.replace(pos, path_variable_project_directory_name.size(), path_filename_string); + pos+=path_filename_string.size(); + } + if(pos!=0) + default_build_path=default_build_path_string; + + if(default_build_path.is_relative()) + default_build_path=project_path/default_build_path; + + return default_build_path; } -boost::filesystem::path Project::CMake::get_default_build_path() { - return cmake.get_default_build_path(); +boost::filesystem::path Project::Build::get_debug_build_path() { + boost::filesystem::path debug_build_path=Config::get().project.debug_build_path; + + const std::string path_variable_project_directory_name=""; + size_t pos=0; + auto debug_build_path_string=debug_build_path.string(); + auto path_filename_string=project_path.filename().string(); + while((pos=debug_build_path_string.find(path_variable_project_directory_name, pos))!=std::string::npos) { + debug_build_path_string.replace(pos, path_variable_project_directory_name.size(), path_filename_string); + pos+=path_filename_string.size(); + } + if(pos!=0) + debug_build_path=debug_build_path_string; + + const std::string path_variable_default_build_path=""; + pos=0; + debug_build_path_string=debug_build_path.string(); + auto default_build_path=Config::get().project.default_build_path; + while((pos=debug_build_path_string.find(path_variable_default_build_path, pos))!=std::string::npos) { + debug_build_path_string.replace(pos, path_variable_default_build_path.size(), default_build_path); + pos+=default_build_path.size(); + } + if(pos!=0) + debug_build_path=debug_build_path_string; + + if(debug_build_path.is_relative()) + debug_build_path=project_path/debug_build_path; + + return debug_build_path; } -bool Project::CMake::update_default_build(bool force) { - return cmake.update_default_build(force); +Project::CMake::CMake(const boost::filesystem::path &path) : Project::Build(), cmake(path) { + project_path=cmake.project_path; } -boost::filesystem::path Project::CMake::get_debug_build_path() { - return cmake.get_debug_build_path(); +bool Project::CMake::update_default_build(bool force) { + return cmake.update_default_build(get_default_build_path(), force); } bool Project::CMake::update_debug_build(bool force) { - return cmake.update_debug_build(force); + return cmake.update_debug_build(get_debug_build_path(), force); } boost::filesystem::path Project::CMake::get_executable(const boost::filesystem::path &path) { diff --git a/src/project_build.h b/src/project_build.h index ffd36cb..ea12926 100644 --- a/src/project_build.h +++ b/src/project_build.h @@ -12,9 +12,9 @@ namespace Project { boost::filesystem::path project_path; - virtual boost::filesystem::path get_default_build_path() {return boost::filesystem::path();} + boost::filesystem::path get_default_build_path(); virtual bool update_default_build(bool force=false) {return false;} - virtual boost::filesystem::path get_debug_build_path() {return boost::filesystem::path();} + boost::filesystem::path get_debug_build_path(); virtual bool update_debug_build(bool force=false) {return false;} virtual boost::filesystem::path get_executable(const boost::filesystem::path &path) {return boost::filesystem::path();} @@ -25,9 +25,7 @@ namespace Project { public: CMake(const boost::filesystem::path &path); - boost::filesystem::path get_default_build_path() override; bool update_default_build(bool force=false) override; - boost::filesystem::path get_debug_build_path() override; bool update_debug_build(bool force=false) override; boost::filesystem::path get_executable(const boost::filesystem::path &path) override; From 8a1c42450d955bb685ce8af134ad1569fb36b904 Mon Sep 17 00:00:00 2001 From: eidheim Date: Sun, 20 Mar 2016 09:50:56 +0100 Subject: [PATCH 16/30] Minor cleanup of project code --- src/notebook.cc | 19 +++---------------- src/project.cc | 22 ++++++++++++++++++++++ src/project.h | 1 + src/project_build.cc | 6 +++++- 4 files changed, 31 insertions(+), 17 deletions(-) diff --git a/src/notebook.cc b/src/notebook.cc index 0497b21..ab4541d 100644 --- a/src/notebook.cc +++ b/src/notebook.cc @@ -4,7 +4,7 @@ #include "logging.h" #include #include -#include "project_build.h" +#include "project.h" #include "filesystem.h" #if GTKSOURCEVIEWMM_MAJOR_VERSION > 2 & GTKSOURCEVIEWMM_MINOR_VERSION > 17 @@ -243,21 +243,8 @@ bool Notebook::save(int page) { view->get_buffer()->set_modified(false); - //If CMakeLists.txt have been modified: - boost::filesystem::path project_path; - if(view->file_path.filename()=="CMakeLists.txt") { - auto build=Project::get_build(view->file_path); - build->update_default_build(true); - if(boost::filesystem::exists(build->get_debug_build_path())) - build->update_debug_build(true); - - for(auto source_view: source_views) { - if(auto source_clang_view=dynamic_cast(source_view)) { - if(filesystem::file_in_path(source_clang_view->file_path, build->project_path)) - source_clang_view->full_reparse_needed=true; - } - } - } + Project::on_save(); + JDEBUG("end true"); return true; } diff --git a/src/project.cc b/src/project.cc index cf2c5d3..76a74ab 100644 --- a/src/project.cc +++ b/src/project.cc @@ -35,6 +35,28 @@ void Project::save_files(const boost::filesystem::path &path) { } } +void Project::on_save() { + if(Notebook::get().get_current_page()==-1) + return; + auto view=Notebook::get().get_current_view(); + if(view->file_path.filename()=="CMakeLists.txt") { + auto build=get_build(view->file_path); + if(dynamic_cast(build.get())) { + build->update_default_build(true); + if(boost::filesystem::exists(build->get_debug_build_path())) + build->update_debug_build(true); + + for(int c=0;c(source_view)) { + if(filesystem::file_in_path(source_clang_view->file_path, build->project_path)) + source_clang_view->full_reparse_needed=true; + } + } + } + } +} + void Project::debug_update_status(const std::string &debug_status) { if(debug_status.empty()) debug_status_label().set_text(""); diff --git a/src/project.h b/src/project.h index e81e346..285b341 100644 --- a/src/project.h +++ b/src/project.h @@ -14,6 +14,7 @@ namespace Project { Gtk::Label &debug_status_label(); void save_files(const boost::filesystem::path &path); + void on_save(); extern boost::filesystem::path debug_last_stop_file_path; extern std::unordered_map run_arguments; diff --git a/src/project_build.cc b/src/project_build.cc index 534742b..430d0fb 100644 --- a/src/project_build.cc +++ b/src/project_build.cc @@ -2,7 +2,11 @@ #include "config.h" std::unique_ptr Project::get_build(const boost::filesystem::path &path) { - return std::unique_ptr(new CMake(path)); + auto cmake=new CMake(path); + if(!cmake->project_path.empty()) + return std::unique_ptr(cmake); + else + return std::unique_ptr(new Project::Build()); } boost::filesystem::path Project::Build::get_default_build_path() { From ed0004fa6caebfe48f8e05928a7c0922c27c898f Mon Sep 17 00:00:00 2001 From: eidheim Date: Sun, 20 Mar 2016 09:56:33 +0100 Subject: [PATCH 17/30] Added page parameter to Project::on_save --- src/notebook.cc | 2 +- src/project.cc | 6 +++--- src/project.h | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/notebook.cc b/src/notebook.cc index ab4541d..9a43194 100644 --- a/src/notebook.cc +++ b/src/notebook.cc @@ -243,7 +243,7 @@ bool Notebook::save(int page) { view->get_buffer()->set_modified(false); - Project::on_save(); + Project::on_save(page); JDEBUG("end true"); return true; diff --git a/src/project.cc b/src/project.cc index 76a74ab..f581617 100644 --- a/src/project.cc +++ b/src/project.cc @@ -35,10 +35,10 @@ void Project::save_files(const boost::filesystem::path &path) { } } -void Project::on_save() { - if(Notebook::get().get_current_page()==-1) +void Project::on_save(int page) { + if(page>=Notebook::get().size()) return; - auto view=Notebook::get().get_current_view(); + auto view=Notebook::get().get_view(page); if(view->file_path.filename()=="CMakeLists.txt") { auto build=get_build(view->file_path); if(dynamic_cast(build.get())) { diff --git a/src/project.h b/src/project.h index 285b341..ed8f8f0 100644 --- a/src/project.h +++ b/src/project.h @@ -14,7 +14,7 @@ namespace Project { Gtk::Label &debug_status_label(); void save_files(const boost::filesystem::path &path); - void on_save(); + void on_save(int page); extern boost::filesystem::path debug_last_stop_file_path; extern std::unordered_map run_arguments; From f9e22d55f75e772b9c302442c8158be34650d12a Mon Sep 17 00:00:00 2001 From: eidheim Date: Sun, 20 Mar 2016 13:52:52 +0100 Subject: [PATCH 18/30] build now created in get_language so that language can be chosen based on build management system found --- src/project.cc | 23 ++++++++++++----------- src/project.h | 12 ++++++------ 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/project.cc b/src/project.cc index f581617..5d097d0 100644 --- a/src/project.cc +++ b/src/project.cc @@ -98,29 +98,30 @@ void Project::debug_update_stop() { } std::unique_ptr Project::get_language() { + std::unique_ptr build; + if(Notebook::get().get_current_page()!=-1) { auto view=Notebook::get().get_current_view(); + build=get_build(view->file_path); if(view->language) { auto language_id=view->language->get_id(); if(language_id=="markdown") - return std::unique_ptr(new Project::Markdown()); + return std::unique_ptr(new Project::Markdown(build)); if(language_id=="python") - return std::unique_ptr(new Project::Python()); + return std::unique_ptr(new Project::Python(build)); if(language_id=="js") - return std::unique_ptr(new Project::JavaScript()); + return std::unique_ptr(new Project::JavaScript(build)); if(language_id=="html") - return std::unique_ptr(new Project::HTML()); + return std::unique_ptr(new Project::HTML(build)); } } - - return std::unique_ptr(new Project::Clang()); -} - -Project::Language::Language() { - if(Notebook::get().get_current_page()!=-1) - build=get_build(Notebook::get().get_current_view()->file_path); else build=get_build(Directories::get().path); + + if(dynamic_cast(build.get())) + return std::unique_ptr(new Project::Clang(build)); + else + return std::unique_ptr(new Project::Language(build)); } std::pair Project::Clang::get_run_arguments() { diff --git a/src/project.h b/src/project.h index ed8f8f0..d2fb2d9 100644 --- a/src/project.h +++ b/src/project.h @@ -27,7 +27,7 @@ namespace Project { class Language { public: - Language(); + Language(std::unique_ptr &build): build(std::move(build)) {} virtual ~Language() {} std::unique_ptr build; @@ -59,7 +59,7 @@ namespace Project { private: Dispatcher dispatcher; public: - Clang() : Language() {} + Clang(std::unique_ptr &build) : Language(build) {} ~Clang() { dispatcher.disconnect(); } std::pair get_run_arguments() override; @@ -89,7 +89,7 @@ namespace Project { class Markdown : public Language { public: - Markdown() : Language() {} + Markdown(std::unique_ptr &build) : Language(build) {} ~Markdown(); boost::filesystem::path last_temp_path; @@ -98,21 +98,21 @@ namespace Project { class Python : public Language { public: - Python() : Language() {} + Python(std::unique_ptr &build) : Language(build) {} void compile_and_run() override; }; class JavaScript : public Language { public: - JavaScript() : Language() {} + JavaScript(std::unique_ptr &build) : Language(build) {} void compile_and_run() override; }; class HTML : public Language { public: - HTML() : Language() {} + HTML(std::unique_ptr &build) : Language(build) {} void compile_and_run() override; }; From 4a3eb43ebb55e0ebedda806571a83ddd12eed806 Mon Sep 17 00:00:00 2001 From: eidheim Date: Sun, 20 Mar 2016 14:08:01 +0100 Subject: [PATCH 19/30] Now properly uses std::move in get_language --- src/project.cc | 12 ++++++------ src/project.h | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/project.cc b/src/project.cc index 5d097d0..443fcb7 100644 --- a/src/project.cc +++ b/src/project.cc @@ -106,22 +106,22 @@ std::unique_ptr Project::get_language() { if(view->language) { auto language_id=view->language->get_id(); if(language_id=="markdown") - return std::unique_ptr(new Project::Markdown(build)); + return std::unique_ptr(new Project::Markdown(std::move(build))); if(language_id=="python") - return std::unique_ptr(new Project::Python(build)); + return std::unique_ptr(new Project::Python(std::move(build))); if(language_id=="js") - return std::unique_ptr(new Project::JavaScript(build)); + return std::unique_ptr(new Project::JavaScript(std::move(build))); if(language_id=="html") - return std::unique_ptr(new Project::HTML(build)); + return std::unique_ptr(new Project::HTML(std::move(build))); } } else build=get_build(Directories::get().path); if(dynamic_cast(build.get())) - return std::unique_ptr(new Project::Clang(build)); + return std::unique_ptr(new Project::Clang(std::move(build))); else - return std::unique_ptr(new Project::Language(build)); + return std::unique_ptr(new Project::Language(std::move(build))); } std::pair Project::Clang::get_run_arguments() { diff --git a/src/project.h b/src/project.h index d2fb2d9..51d5bde 100644 --- a/src/project.h +++ b/src/project.h @@ -27,7 +27,7 @@ namespace Project { class Language { public: - Language(std::unique_ptr &build): build(std::move(build)) {} + Language(std::unique_ptr &&build): build(std::move(build)) {} virtual ~Language() {} std::unique_ptr build; @@ -59,7 +59,7 @@ namespace Project { private: Dispatcher dispatcher; public: - Clang(std::unique_ptr &build) : Language(build) {} + Clang(std::unique_ptr &&build) : Language(std::move(build)) {} ~Clang() { dispatcher.disconnect(); } std::pair get_run_arguments() override; @@ -89,7 +89,7 @@ namespace Project { class Markdown : public Language { public: - Markdown(std::unique_ptr &build) : Language(build) {} + Markdown(std::unique_ptr &&build) : Language(std::move(build)) {} ~Markdown(); boost::filesystem::path last_temp_path; @@ -98,21 +98,21 @@ namespace Project { class Python : public Language { public: - Python(std::unique_ptr &build) : Language(build) {} + Python(std::unique_ptr &&build) : Language(std::move(build)) {} void compile_and_run() override; }; class JavaScript : public Language { public: - JavaScript(std::unique_ptr &build) : Language(build) {} + JavaScript(std::unique_ptr &&build) : Language(std::move(build)) {} void compile_and_run() override; }; class HTML : public Language { public: - HTML(std::unique_ptr &build) : Language(build) {} + HTML(std::unique_ptr &&build) : Language(std::move(build)) {} void compile_and_run() override; }; From 117857f937c221e931e6bdbe42e10781426e8ba1 Mon Sep 17 00:00:00 2001 From: eidheim Date: Mon, 21 Mar 2016 10:00:25 +0100 Subject: [PATCH 20/30] Added automated cmake processing for all cmake files in Project::on_save --- src/filesystem.cc | 11 +++++++++++ src/filesystem.h | 1 + src/project.cc | 32 ++++++++++++++++++++------------ 3 files changed, 32 insertions(+), 12 deletions(-) diff --git a/src/filesystem.cc b/src/filesystem.cc index ec2ca87..d83ca13 100644 --- a/src/filesystem.cc +++ b/src/filesystem.cc @@ -169,3 +169,14 @@ bool filesystem::file_in_path(const boost::filesystem::path &file_path, const bo return std::equal(path.begin(), path.end(), file_path.begin()); } +boost::filesystem::path filesystem::find_file_in_path_parents(const std::string &file_name, const boost::filesystem::path &path) { + auto current_path=path; + while(true) { + auto test_path=current_path/file_name; + if(boost::filesystem::exists(test_path)) + return test_path; + if(current_path==current_path.root_directory()) + return boost::filesystem::path(); + current_path=current_path.parent_path(); + } +} diff --git a/src/filesystem.h b/src/filesystem.h index 1326ab9..74a82aa 100644 --- a/src/filesystem.h +++ b/src/filesystem.h @@ -30,5 +30,6 @@ public: static std::string unescape(const std::string &argument); static bool file_in_path(const boost::filesystem::path &file_path, const boost::filesystem::path &path); + static boost::filesystem::path find_file_in_path_parents(const std::string &file_name, const boost::filesystem::path &path); }; #endif // JUCI_FILESYSTEM_H_ diff --git a/src/project.cc b/src/project.cc index 443fcb7..c224d6c 100644 --- a/src/project.cc +++ b/src/project.cc @@ -39,18 +39,26 @@ void Project::on_save(int page) { if(page>=Notebook::get().size()) return; auto view=Notebook::get().get_view(page); - if(view->file_path.filename()=="CMakeLists.txt") { - auto build=get_build(view->file_path); - if(dynamic_cast(build.get())) { - build->update_default_build(true); - if(boost::filesystem::exists(build->get_debug_build_path())) - build->update_debug_build(true); - - for(int c=0;c(source_view)) { - if(filesystem::file_in_path(source_clang_view->file_path, build->project_path)) - source_clang_view->full_reparse_needed=true; + if(view->language && view->language->get_id()=="cmake") { + boost::filesystem::path cmake_path; + if(view->file_path.filename()=="CMakeLists.txt") + cmake_path=view->file_path; + else + cmake_path=filesystem::find_file_in_path_parents("CMakeLists.txt", view->file_path.parent_path()); + + if(!cmake_path.empty()) { + auto build=get_build(cmake_path); + if(dynamic_cast(build.get())) { + build->update_default_build(true); + if(boost::filesystem::exists(build->get_debug_build_path())) + build->update_debug_build(true); + + for(int c=0;c(source_view)) { + if(filesystem::file_in_path(source_clang_view->file_path, build->project_path)) + source_clang_view->full_reparse_needed=true; + } } } } From 1cd001294b7e0a277025b0f619c467b13f7ddde1 Mon Sep 17 00:00:00 2001 From: eidheim Date: Mon, 21 Mar 2016 10:48:34 +0100 Subject: [PATCH 21/30] Now handles autocomplete even when the line starts with a comment (/*...*/) --- src/source_clang.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/source_clang.cc b/src/source_clang.cc index 4fe0d30..98d297d 100644 --- a/src/source_clang.cc +++ b/src/source_clang.cc @@ -639,7 +639,7 @@ void Source::ClangViewAutocomplete::autocomplete() { auto buffer=std::make_shared(get_buffer()->get_text()); auto iter=get_buffer()->get_insert()->get_iter(); auto line_nr=iter.get_line()+1; - auto column_nr=iter.get_line_offset()+1; + auto column_nr=iter.get_line_index()+1; auto pos=iter.get_offset()-1; while(pos>=0 && (((*buffer)[pos]>='a' && (*buffer)[pos]<='z') || ((*buffer)[pos]>='A' && (*buffer)[pos]<='Z') || ((*buffer)[pos]>='0' && (*buffer)[pos]<='9') || (*buffer)[pos]=='_')) { From 2b172d6e961181d18bf8e23e8906ed9a384ecc1e Mon Sep 17 00:00:00 2001 From: eidheim Date: Mon, 21 Mar 2016 13:38:33 +0100 Subject: [PATCH 22/30] Fixes a segmentation fault caused by Gtk::TextView::on_key_press_event. Have once in a while experienced this issue, but only on OS X --- src/source.cc | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/source.cc b/src/source.cc index 6de9cda..564fbde 100644 --- a/src/source.cc +++ b/src/source.cc @@ -1283,9 +1283,27 @@ bool Source::View::on_key_press_event_basic(GdkEventKey* key) { return true; } - bool stop=Gsv::View::on_key_press_event(key); + //Workaround for TextView::on_key_press_event bug sometimes causing segmentation faults TODO: figure out the bug and create pull request to gtk + //Note: valgrind reports issues on TextView::on_key_press_event as well + auto unicode=gdk_keyval_to_unicode(key->keyval); + if(unicode>=32 && unicode!=127) { + if(get_buffer()->get_has_selection()) { + Gtk::TextIter selection_start, selection_end; + get_buffer()->get_selection_bounds(selection_start, selection_end); + get_buffer()->erase(selection_start, selection_end); + } + get_buffer()->insert_at_cursor(Glib::ustring(1, unicode)); + get_source_buffer()->end_user_action(); + + //Trick to make the cursor visible right after insertion: + set_cursor_visible(false); + set_cursor_visible(); + + return true; + } + get_source_buffer()->end_user_action(); - return stop; + return Gsv::View::on_key_press_event(key); } //Bracket language indentation From d76bb115cbf201638581429a96e574c57511e1b2 Mon Sep 17 00:00:00 2001 From: eidheim Date: Mon, 21 Mar 2016 13:55:50 +0100 Subject: [PATCH 23/30] Fixed comments on the Gtk::TextView::on_key_press_event issue --- src/source.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/source.cc b/src/source.cc index 564fbde..72d0c87 100644 --- a/src/source.cc +++ b/src/source.cc @@ -1283,7 +1283,9 @@ bool Source::View::on_key_press_event_basic(GdkEventKey* key) { return true; } - //Workaround for TextView::on_key_press_event bug sometimes causing segmentation faults TODO: figure out the bug and create pull request to gtk + //Workaround for TextView::on_key_press_event bug sometimes causing segmentation faults + //TODO: figure out the bug and create pull request to gtk + //Have only experienced this on OS X //Note: valgrind reports issues on TextView::on_key_press_event as well auto unicode=gdk_keyval_to_unicode(key->keyval); if(unicode>=32 && unicode!=127) { From 2f78ea61b682d87dfaaf9e9da8cf4167f4b53553 Mon Sep 17 00:00:00 2001 From: eidheim Date: Tue, 22 Mar 2016 09:26:55 +0100 Subject: [PATCH 24/30] Changed default window width and height in preferences, and save_on_compile_or_run is now true by default --- src/files.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/files.h b/src/files.h index 03575ce..c69c48d 100644 --- a/src/files.h +++ b/src/files.h @@ -8,8 +8,8 @@ const std::string configjson = "{\n" " \"version\": \""+std::string(JUCI_VERSION)+"\",\n" " \"default_window_size\": {\n" -" \"width\": 600,\n" -" \"height\": 400\n" +" \"width\": 800,\n" +" \"height\": 600\n" " },\n" " \"terminal_history_size\": 1000,\n" " \"gtk_theme\": {\n" @@ -130,7 +130,7 @@ const std::string configjson = " \"cmake_command\": \"cmake\",\n" #endif " \"make_command\": \"cmake --build .\",\n" -" \"save_on_compile_or_run\": false\n" +" \"save_on_compile_or_run\": true\n" " },\n" " \"documentation_searches\": {\n" " \"clang\": {\n" From c31f595f902c2694891171cc4ea6d7b19e7212a4 Mon Sep 17 00:00:00 2001 From: eidheim Date: Tue, 22 Mar 2016 12:27:20 +0100 Subject: [PATCH 25/30] Minor directories update thread cleanup --- src/directories.cc | 39 ++++++++++++++++----------------------- src/directories.h | 1 - 2 files changed, 16 insertions(+), 24 deletions(-) diff --git a/src/directories.cc b/src/directories.cc index 24d2323..79ec8b8 100644 --- a/src/directories.cc +++ b/src/directories.cc @@ -178,30 +178,24 @@ Directories::Directories() : Gtk::TreeView(), stop_update_thread(false) { while(!stop_update_thread) { std::this_thread::sleep_for(std::chrono::milliseconds(1000)); update_mutex.lock(); - if(update_paths.size()==0) { - for(auto it=last_write_times.begin();it!=last_write_times.end();) { - boost::system::error_code ec; - auto last_write_time=boost::filesystem::last_write_time(it->first, ec); - if(!ec) { - if(it->second.secondfirst); - } - it++; + for(auto it=last_write_times.begin();it!=last_write_times.end();) { + boost::system::error_code ec; + auto last_write_time=boost::filesystem::last_write_time(it->first, ec); + if(!ec) { + if(it->second.second(it->first); + dispatcher.post([this, path] { + update_mutex.lock(); + auto it=last_write_times.find(*path); + if(it!=last_write_times.end()) + add_path(*path, it->second.first); + update_mutex.unlock(); + }); } - else - it=last_write_times.erase(it); - } - if(update_paths.size()>0) { - dispatcher.post([this] { - update_mutex.lock(); - for(auto &path: update_paths) { - if(last_write_times.count(path)>0) - add_path(path, last_write_times.at(path).first); - } - update_paths.clear(); - update_mutex.unlock(); - }); + it++; } + else + it=last_write_times.erase(it); } update_mutex.unlock(); } @@ -320,7 +314,6 @@ void Directories::open(const boost::filesystem::path &dir_path) { tree_store->clear(); update_mutex.lock(); last_write_times.clear(); - update_paths.clear(); update_mutex.unlock(); diff --git a/src/directories.h b/src/directories.h index fda3a9f..f0b9202 100644 --- a/src/directories.h +++ b/src/directories.h @@ -67,7 +67,6 @@ private: std::thread update_thread; std::atomic stop_update_thread; Dispatcher dispatcher; - std::vector update_paths; Gtk::Menu menu; Gtk::MenuItem menu_item_rename; From 38867c081d33f89e5c2029549c0c866286eefe1b Mon Sep 17 00:00:00 2001 From: eidheim Date: Tue, 22 Mar 2016 16:26:30 +0100 Subject: [PATCH 26/30] Added a slight delay to directory view update to avoid missing directory changes --- src/directories.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/directories.cc b/src/directories.cc index 79ec8b8..373e3b0 100644 --- a/src/directories.cc +++ b/src/directories.cc @@ -181,8 +181,9 @@ Directories::Directories() : Gtk::TreeView(), stop_update_thread(false) { for(auto it=last_write_times.begin();it!=last_write_times.end();) { boost::system::error_code ec; auto last_write_time=boost::filesystem::last_write_time(it->first, ec); + auto now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); if(!ec) { - if(it->second.secondsecond.second(it->first); dispatcher.post([this, path] { update_mutex.lock(); From 54dc293177272d31b00632fab7eb807ea4ed55f3 Mon Sep 17 00:00:00 2001 From: eidheim Date: Tue, 22 Mar 2016 23:59:20 +0100 Subject: [PATCH 27/30] Fixes to last commit --- src/directories.cc | 9 +++++---- src/directories.h | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/directories.cc b/src/directories.cc index 373e3b0..c73c004 100644 --- a/src/directories.cc +++ b/src/directories.cc @@ -185,11 +185,11 @@ Directories::Directories() : Gtk::TreeView(), stop_update_thread(false) { if(!ec) { if(last_write_time!=now && it->second.second(it->first); - dispatcher.post([this, path] { + dispatcher.post([this, path, last_write_time] { update_mutex.lock(); auto it=last_write_times.find(*path); if(it!=last_write_times.end()) - add_path(*path, it->second.first); + add_path(*path, it->second.first, last_write_time); update_mutex.unlock(); }); } @@ -403,9 +403,10 @@ bool Directories::on_button_press_event(GdkEventButton* event) { return Gtk::TreeView::on_button_press_event(event); } -void Directories::add_path(const boost::filesystem::path &dir_path, const Gtk::TreeModel::Row &parent) { +void Directories::add_path(const boost::filesystem::path &dir_path, const Gtk::TreeModel::Row &parent, time_t last_write_time) { boost::system::error_code ec; - auto last_write_time=boost::filesystem::last_write_time(dir_path, ec); + if(last_write_time==0) + last_write_time=boost::filesystem::last_write_time(dir_path, ec); if(ec) return; last_write_times[dir_path.string()]={parent, last_write_time}; diff --git a/src/directories.h b/src/directories.h index f0b9202..61daccc 100644 --- a/src/directories.h +++ b/src/directories.h @@ -58,7 +58,7 @@ protected: bool on_button_press_event(GdkEventButton *event) override; private: - void add_path(const boost::filesystem::path &dir_path, const Gtk::TreeModel::Row &row); + void add_path(const boost::filesystem::path &dir_path, const Gtk::TreeModel::Row &row, time_t last_write_time=0); Glib::RefPtr tree_store; TreeStore::ColumnRecord column_record; From 3885bc7147337ab44a87b62965c6b777db5d5895 Mon Sep 17 00:00:00 2001 From: eidheim Date: Wed, 23 Mar 2016 10:17:05 +0100 Subject: [PATCH 28/30] Fix for TextView::on_key_press_event workaround --- src/source.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/source.cc b/src/source.cc index 72d0c87..5eab55b 100644 --- a/src/source.cc +++ b/src/source.cc @@ -1288,7 +1288,7 @@ bool Source::View::on_key_press_event_basic(GdkEventKey* key) { //Have only experienced this on OS X //Note: valgrind reports issues on TextView::on_key_press_event as well auto unicode=gdk_keyval_to_unicode(key->keyval); - if(unicode>=32 && unicode!=127) { + if((key->state&(GDK_CONTROL_MASK|GDK_META_MASK))==0 && unicode>=32 && unicode!=127) { if(get_buffer()->get_has_selection()) { Gtk::TextIter selection_start, selection_end; get_buffer()->get_selection_bounds(selection_start, selection_end); From a0b401672129de037e831967fae23a0a0009bb42 Mon Sep 17 00:00:00 2001 From: eidheim Date: Wed, 23 Mar 2016 13:18:52 +0100 Subject: [PATCH 29/30] TextView::on_key_press_event workaround fix for dead keys --- src/source.cc | 4 +++- src/source.h | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/source.cc b/src/source.cc index 5eab55b..c4c6c5c 100644 --- a/src/source.cc +++ b/src/source.cc @@ -1058,6 +1058,7 @@ bool Source::View::on_key_press_event(GdkEventKey* key) { return true; } + previous_keyval=last_keyval; last_keyval=key->keyval; if(get_buffer()->get_has_selection()) @@ -1288,7 +1289,8 @@ bool Source::View::on_key_press_event_basic(GdkEventKey* key) { //Have only experienced this on OS X //Note: valgrind reports issues on TextView::on_key_press_event as well auto unicode=gdk_keyval_to_unicode(key->keyval); - if((key->state&(GDK_CONTROL_MASK|GDK_META_MASK))==0 && unicode>=32 && unicode!=127) { + if((key->state&(GDK_CONTROL_MASK|GDK_META_MASK))==0 && unicode>=32 && unicode!=127 && + (previous_keyvalGDK_KEY_dead_greek)) { if(get_buffer()->get_has_selection()) { Gtk::TextIter selection_start, selection_end; get_buffer()->get_selection_bounds(selection_start, selection_end); diff --git a/src/source.h b/src/source.h index 1e0a3b0..93c8adb 100644 --- a/src/source.h +++ b/src/source.h @@ -154,6 +154,7 @@ namespace Source { bool spellcheck_all=false; std::unique_ptr spellcheck_suggestions_dialog; + guint previous_keyval=0; guint last_keyval=0; private: GtkSourceSearchContext *search_context; From febf786cd2dbc098b565dfd776bf4310deb10eaf Mon Sep 17 00:00:00 2001 From: eidheim Date: Wed, 23 Mar 2016 13:42:15 +0100 Subject: [PATCH 30/30] TextView::on_key_press_event workaround: another fix for dead keys --- src/source.cc | 5 +++-- src/source.h | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/source.cc b/src/source.cc index c4c6c5c..cb90111 100644 --- a/src/source.cc +++ b/src/source.cc @@ -1058,7 +1058,8 @@ bool Source::View::on_key_press_event(GdkEventKey* key) { return true; } - previous_keyval=last_keyval; + if(last_keyvalGDK_KEY_Hyper_R) + previous_non_modifier_keyval=last_keyval; last_keyval=key->keyval; if(get_buffer()->get_has_selection()) @@ -1290,7 +1291,7 @@ bool Source::View::on_key_press_event_basic(GdkEventKey* key) { //Note: valgrind reports issues on TextView::on_key_press_event as well auto unicode=gdk_keyval_to_unicode(key->keyval); if((key->state&(GDK_CONTROL_MASK|GDK_META_MASK))==0 && unicode>=32 && unicode!=127 && - (previous_keyvalGDK_KEY_dead_greek)) { + (previous_non_modifier_keyvalGDK_KEY_dead_greek)) { if(get_buffer()->get_has_selection()) { Gtk::TextIter selection_start, selection_end; get_buffer()->get_selection_bounds(selection_start, selection_end); diff --git a/src/source.h b/src/source.h index 93c8adb..f9af6a3 100644 --- a/src/source.h +++ b/src/source.h @@ -154,7 +154,7 @@ namespace Source { bool spellcheck_all=false; std::unique_ptr spellcheck_suggestions_dialog; - guint previous_keyval=0; + guint previous_non_modifier_keyval=0; guint last_keyval=0; private: GtkSourceSearchContext *search_context;