#include "directories.h" #include "sourcefile.h" #include "logging.h" #include "singletons.h" #include #include #include //TODO: remove using namespace std; //TODO: remove namespace sigc { SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE } Directories::Directories() { DEBUG("adding treeview to scrolledwindow"); add(tree_view); set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); tree_store = Gtk::TreeStore::create(column_record); tree_view.set_model(tree_store); tree_view.append_column("", column_record.name); tree_store->set_sort_column(column_record.id, Gtk::SortType::SORT_ASCENDING); tree_view.signal_row_activated().connect([this](const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* column){ INFO("Directory navigation"); auto iter = tree_store->get_iter(path); if (iter) { auto path_str=iter->get_value(column_record.path); if (boost::filesystem::is_directory(boost::filesystem::path(path_str))) { tree_view.row_expanded(path) ? tree_view.collapse_row(path) : tree_view.expand_row(path, false); } else { if(on_row_activated) on_row_activated(path_str); } } }); tree_view.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)=="") { add_path(iter->get_value(column_record.path), *iter); } return false; }); tree_view.signal_row_collapsed().connect([this](const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& path){ auto children=iter->children(); if(children) { while(children) { tree_store->erase(children.begin()); } tree_store->append(iter->children()); } }); } void Directories::open_folder(const boost::filesystem::path& dir_path) { if(dir_path!="") tree_store->clear(); auto new_path=dir_path; INFO("Open folder"); if(dir_path=="") { if(current_path=="") return; new_path=current_path; } std::vector expanded_paths; if(current_path==new_path) { tree_view.map_expanded_rows([&expanded_paths](Gtk::TreeView* tree_view, const Gtk::TreeModel::Path& path){ expanded_paths.emplace_back(path); }); } if(dir_path!="") cmake=std::unique_ptr(new CMake(new_path)); auto project=cmake->get_functions_parameters("project"); if(project.size()>0 && project[0].second.size()>0) tree_view.get_column(0)->set_title(project[0].second[0]); else tree_view.get_column(0)->set_title(""); add_path(new_path, Gtk::TreeModel::Row()); for(auto &path: expanded_paths) tree_view.expand_row(path, false); current_path=new_path; DEBUG("Folder opened"); } void Directories::select_path(const boost::filesystem::path &path) { if(current_path=="") return; if(path.string().substr(0, current_path.string().size())!=current_path.string()) return; if(boost::filesystem::is_directory(path)) return; std::list paths; auto parent_path=path.parent_path(); paths.emplace_front(parent_path); while(parent_path!=current_path) { parent_path=parent_path.parent_path(); paths.emplace_front(parent_path); } for(auto &a_path: paths) { tree_store->foreach_iter([this, &a_path](const Gtk::TreeModel::iterator& iter){ if(iter->get_value(column_record.path)==a_path.string()) { add_path(a_path, *iter); return true; } return false; }); } tree_store->foreach_iter([this, &path](const Gtk::TreeModel::iterator& iter){ if(iter->get_value(column_record.path)==path.string()) { auto tree_path=Gtk::TreePath(iter); tree_view.expand_to_path(tree_path); tree_view.set_cursor(tree_path); selected_path=path; return true; } return false; }); } bool Directories::ignored(std::string path) { DEBUG("Checking if file-/directory is filtered"); std::transform(path.begin(), path.end(), path.begin(), ::tolower); for(std::string &i : Singleton::Config::directories()->exceptions) { if(i == path) return false; } for(auto &i : Singleton::Config::directories()->ignored) { if(path.find(i, 0) != std::string::npos) return true; } return false; } void Directories::add_path(const boost::filesystem::path& dir_path, const Gtk::TreeModel::Row &parent) { auto children=tree_store->children(); if(parent) children=parent.children(); if(children) { if(children.begin()->get_value(column_record.path)=="") { tree_store->erase(parent->children().begin()); } } std::unordered_set not_deleted; boost::filesystem::directory_iterator end_it; for(boost::filesystem::directory_iterator it(dir_path);it!=end_it;it++) { auto filename=it->path().filename().string(); if (!ignored(filename)) { bool already_added=false; if(children) { for(auto &child: children) { if(child.get_value(column_record.name)==filename) { not_deleted.emplace(filename); already_added=true; break; } } } if(!already_added) { auto child = tree_store->append(children); not_deleted.emplace(filename); child->set_value(column_record.name, filename); child->set_value(column_record.path, it->path().string()); if (boost::filesystem::is_directory(*it)) { child->set_value(column_record.id, "a"+filename); tree_store->append(child->children()); } else child->set_value(column_record.id, "b"+filename); } } } if(children) { auto last_it=children.begin(); for(auto it=children.begin();it!=children.end();it++) { if(not_deleted.count(it->get_value(column_record.name))==0) { tree_store->erase(it); it=last_it; } last_it=it; } } else tree_store->append(children); }