From df6cc6136d5b1c0d8f6395d2e902f93af974fe8c Mon Sep 17 00:00:00 2001 From: tedjk Date: Thu, 9 Apr 2015 15:55:45 +0200 Subject: [PATCH] added project structure box to the left of the window --- juci/CMakeLists.txt | 4 +- juci/config.json | 3 +- juci/directories.cc | 107 ++++++++++++++++++++++++++++++++++++++++++++ juci/directories.h | 57 +++++++++++++++++++++++ juci/menu.cc | 10 ----- juci/notebook.cc | 10 +++-- juci/notebook.h | 10 +++-- juci/window.cc | 66 ++++++++++++++++++++++++++- juci/window.h | 9 ++++ 9 files changed, 257 insertions(+), 19 deletions(-) create mode 100644 juci/directories.cc create mode 100644 juci/directories.h diff --git a/juci/CMakeLists.txt b/juci/CMakeLists.txt index d4f326d..2f3755a 100644 --- a/juci/CMakeLists.txt +++ b/juci/CMakeLists.txt @@ -52,7 +52,7 @@ endif() #Boost_INCLUDE_DIRS - Boost include directories #Boost_LIBRARY_DIRS - Link directories for Boost libraries #Boost_LIBRARIES - Boost component libraries to be linked -find_package(Boost 1.5 REQUIRED COMPONENTS python timer system) +find_package(Boost 1.5 REQUIRED COMPONENTS python timer system filesystem) #If boost is not found if(${Boost_FOUND}) @@ -104,6 +104,8 @@ add_executable(${project_name} notebook.h entry.h entry.cc + directories.h + directories.cc ) add_library(${module} SHARED diff --git a/juci/config.json b/juci/config.json index 9f24e39..afc983d 100644 --- a/juci/config.json +++ b/juci/config.json @@ -22,7 +22,8 @@ "split_window": "s", "new_h_file": "h", "new_cc_file": "c", - "close_tab": "w" + "close_tab": "w", + "open_folder": "o" }, "example": { "key": "value", diff --git a/juci/directories.cc b/juci/directories.cc new file mode 100644 index 0000000..3d40a0b --- /dev/null +++ b/juci/directories.cc @@ -0,0 +1,107 @@ +#include "directories.h" + +Directories::Controller::Controller() { + + m_ScrolledWindow.add(m_TreeView); + m_ScrolledWindow.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); +} + +bool Directories::Controller::open_folder(const boost::filesystem::path& dir_path) { + m_refTreeModel = Gtk::TreeStore::create(view()); + m_TreeView.set_model(m_refTreeModel); + m_TreeView.remove_all_columns(); + std::string project_name = get_project_name(dir_path); + m_TreeView.append_column(project_name, view().m_col_name); + int row_id = 0; + Gtk::TreeModel::Row row; + std::string col_id("a"+dir_path.filename().string()); + list_dirs(dir_path, row, row_id); + m_refTreeModel->set_sort_column(0, Gtk::SortType::SORT_ASCENDING); +} + +bool Directories::Controller::list_dirs( const boost::filesystem::path& dir_path, + Gtk::TreeModel::Row &parent, + unsigned row_id) { + boost::filesystem::directory_iterator end_itr; + unsigned dir_counter = row_id; + unsigned file_counter = 0; + Gtk::TreeModel::Row child; + Gtk::TreeModel::Row row; + + //Fill the TreeView's model + for ( boost::filesystem::directory_iterator itr( dir_path ); + itr != end_itr; + ++itr ) { + if (boost::filesystem::is_directory(itr->status()) ) { + if (count(itr->path().string()) > count(dir_path.string())) { + child = *(m_refTreeModel->append(parent.children())); + std::string col_id("a"+itr->path().filename().string()); + child[view().m_col_id] = col_id; + child[view().m_col_name] = itr->path().filename().string(); + child[view().m_col_path] = itr->path().string(); + list_dirs(itr->path(), child, row_id); + } else { + row = *(m_refTreeModel->append()); + std::string col_id("a"+itr->path().filename().string()); + row[view().m_col_path] = itr->path().string(); + row[view().m_col_id] = col_id; + row[view().m_col_name] = itr->path().filename().string(); + list_dirs(itr->path(), parent, row_id); + } + } else { // is a file + child = *(m_refTreeModel->append(parent.children())); + std::string col_id("b"+itr->path().filename().string()); + child[view().m_col_id] = col_id; + child[view().m_col_name] = itr->path().filename().string(); + child[view().m_col_path] = itr->path().string(); + } + } +} +int Directories::Controller::count(const std::string path) { + int count = 0; + + for (int i = 0; i < path.size(); i++) + if (path[i] == '/') count++; + return count; +} +std::string Directories::Controller::get_project_name(const boost::filesystem::path& dir_path) { + std::string project_name; + std::string project_name_var; + boost::filesystem::directory_iterator end_itr; + + + for (boost::filesystem::directory_iterator itr( dir_path ); + itr != end_itr; + ++itr ) { + std::cout << "not cmakelists.txt" << itr->path().string() << std::endl; + if(itr->path().filename().string() == "CMakeLists.txt"){ + std::cout << "found cmakeliksts.txt" << std::endl; + std::ifstream ifs(itr->path().string()); + std::string line; + while(std::getline(ifs, line)) { + if(line.find("project(", 0) != std::string::npos + || line.find("project (", 0) != std::string::npos ) { + std::cout << "found the variabel for project name: "<< line << std::endl; + size_t variabel_start = line.find("{",0 ); + size_t variabel_end = line.find("}",variabel_start); + project_name_var = line.substr(variabel_start+1, (variabel_end)-variabel_start-1); + std::cout << "it is: "<< project_name_var << std::endl; + break; + } + } + std::ifstream ifs2(itr->path().string()); + while(std::getline(ifs2, line)) { + if(line.find("set("+project_name_var, 0) != std::string::npos) { + std::cout << "the variabel value for project name: " << line << std::endl; + size_t variabel_start = line.find(project_name_var,0) +project_name_var.length(); + size_t variabel_end = line.find(")",variabel_start); + project_name = line.substr(variabel_start, variabel_end-variabel_start); + return project_name; + } + } + break; + } + } + return "no project name"; +} + diff --git a/juci/directories.h b/juci/directories.h new file mode 100644 index 0000000..0c7f9bc --- /dev/null +++ b/juci/directories.h @@ -0,0 +1,57 @@ +#ifndef JUCI_DIRECTIRIES_H_ +#define JUCI_DIRECTIRIES_H_ + +#include +#include +#include "boost/filesystem.hpp" +#include +#include + +namespace Directories { + class View : public Gtk::TreeModel::ColumnRecord { + public: + View() { + add(m_col_id); + add(m_col_name); + add(m_col_path); + } + Gtk::TreeModelColumn m_col_id; + Gtk::TreeModelColumn m_col_name; + Gtk::TreeModelColumn m_col_path; + }; + + class Model { + }; + class Controller { + + public: + Controller(); + View& view() { return view_;}; + Model& model() { return model_;}; + + Gtk::ScrolledWindow& widget() {return m_ScrolledWindow;}; + bool open_folder( const boost::filesystem::path& dir_path); + bool list_dirs( const boost::filesystem::path& dir_path, + Gtk::TreeModel::Row &row, unsigned depth); + std::string get_project_name(const boost::filesystem::path& dir_path); + int count( const std::string path); + + //Child widgets: + Gtk::Box m_VBox; + + Gtk::ScrolledWindow m_ScrolledWindow; + Gtk::TreeView m_TreeView; + Glib::RefPtr m_refTreeModel; + + + private: + View view_; + Model model_; + + protected: + void on_treeview_row_activated(const Gtk::TreeModel::Path& path, + Gtk::TreeViewColumn* column); + }; +} + +#endif // JUCI_DIRECTIRIES_H_ diff --git a/juci/menu.cc b/juci/menu.cc index e3e0368..880d7df 100644 --- a/juci/menu.cc +++ b/juci/menu.cc @@ -16,12 +16,6 @@ Menu::Controller::Controller(Keybindings::Controller& keybindings) : keybindings_(keybindings) { keybindings_.action_group_menu()->add(Gtk::Action::create("FileNew", Gtk::Stock::FILE)); - - keybindings_.action_group_menu()->add(Gtk::Action::create("FileOpenFolder", - "Open folder"), - [this]() { - OnFileOpenFolder(); - }); keybindings_.action_group_menu()->add(Gtk::Action::create("EditMenu", Gtk::Stock::EDIT)); keybindings_.action_group_menu()->add(Gtk::Action::create("WindowMenu", @@ -62,10 +56,6 @@ void Menu::Controller::OnFileOpenFile() { std::cout << "Open file clicked" << std::endl; //TODO(Oyvang) Legg til funksjon } -void Menu::Controller::OnFileOpenFolder() { - std::cout << "Open folder clicked" << std::endl; - //TODO(Oyvang) Legg til funksjon -} void Menu::Controller::OnEditCut() { std::cout << "Clicked cut" << std::endl; //TODO(Oyvang) Legg til funksjon diff --git a/juci/notebook.cc b/juci/notebook.cc index 675b8d4..7ae7bf5 100644 --- a/juci/notebook.cc +++ b/juci/notebook.cc @@ -10,7 +10,8 @@ Notebook::Model::Model() { }; Notebook::View::View(){ - view_.pack_start(notebook_); + view_.pack2(notebook_); + view_.set_position(120); } Notebook::Controller::Controller(Keybindings::Controller& keybindings, @@ -20,6 +21,7 @@ source_config_(source_cfg) { refClipboard_ = Gtk::Clipboard::get(); keybindings.action_group_menu()->add(Gtk::Action::create("FileMenu", Gtk::Stock::FILE)); + view_.view().pack1(directories_.widget(), true, true); /* File->New files */ keybindings.action_group_menu()->add(Gtk::Action::create("FileNewStandard", @@ -46,6 +48,7 @@ source_config_(source_cfg) { is_new_file_ = true; OnFileNewHeaderFile(); }); + keybindings.action_group_menu()->add(Gtk::Action::create("WindowCloseTab", "Close tab"), Gtk::AccelKey(keybindings.config_ @@ -132,7 +135,7 @@ Notebook::Controller::~Controller() { for (auto &i : scrolledline_vec_) delete i; } -Gtk::HBox& Notebook::Controller::view() { +Gtk::Paned& Notebook::Controller::view() { return view_.view(); } Gtk::Box& Notebook::Controller::entry_view() { @@ -156,7 +159,9 @@ void Notebook::Controller::OnOpenFile(std::string path) { unsigned pos = path.find_last_of("/\\"); Notebook().append_page(*editor_vec_.back(), path.substr(pos+1)); Notebook().show_all_children(); + std::cout << "setting current page"<< std::endl; Notebook().set_current_page(Pages()-1); + std::cout << "current page set" << std::endl; Notebook().set_focus_child(text_vec_.back()->view()); OnBufferChange(); } @@ -178,7 +183,6 @@ void Notebook::Controller::OnCreatePage(){ linenumbers_vec_.back()->view().set_sensitive(false); editor_vec_.back()->pack_start(*scrolledline_vec_.back(),false,false); editor_vec_.back()->pack_start(*scrolledtext_vec_.back(), true, true); - BufferChangeHandler(text_vec_.back()->view().get_buffer()); } diff --git a/juci/notebook.h b/juci/notebook.h index e05dfbc..84c2591 100644 --- a/juci/notebook.h +++ b/juci/notebook.h @@ -5,6 +5,7 @@ #include "gtkmm.h" #include "entry.h" #include "source.h" +#include "directories.h" namespace Notebook { class Model { @@ -17,10 +18,10 @@ namespace Notebook { class View { public: View(); - Gtk::HBox& view() {return view_;} + Gtk::Paned& view() {return view_;} Gtk::Notebook& notebook() {return notebook_; } protected: - Gtk::HBox view_; + Gtk::Paned view_; Gtk::Notebook notebook_; }; class Controller { @@ -44,18 +45,21 @@ namespace Notebook { void OnFileNewCCFile(); void OnFileNewEmptyfile(); void OnFileNewHeaderFile(); + void OnFileOpenFolder(); void OnNewPage(std::string name); void OnOpenFile(std::string filename); void OnCreatePage(); bool scroll_event_callback(GdkEventScroll* scroll_event); int Pages(); - Gtk::HBox& view(); + Directories::Controller& directories() { return directories_; } + Gtk::Paned& view(); void Search(bool forward); const Source::Config& source_config() { return source_config_; } protected: void BufferChangeHandler(Glib::RefPtr buffer); private: Source::Config source_config_; + Directories::Controller directories_; View view_; Model model_; bool is_new_file_; diff --git a/juci/window.cc b/juci/window.cc index 8e96e9c..a1fb705 100644 --- a/juci/window.cc +++ b/juci/window.cc @@ -9,7 +9,6 @@ Window::Window() : set_title("juCi++"); set_default_size(600, 400); add(window_box_); - keybindings_.action_group_menu()->add(Gtk::Action::create("FileQuit", Gtk::Stock::QUIT), [this]() { @@ -20,6 +19,17 @@ Window::Window() : [this]() { OnOpenFile(); }); + keybindings_.action_group_menu()->add(Gtk::Action::create("FileOpenFolder", + "Open folder"), + Gtk::AccelKey(keybindings_.config_ + .key_map()["open_folder"]), + [this]() { + OnFileOpenFolder(); + }); + + notebook_.directories().m_TreeView.signal_row_activated() + .connect(sigc::mem_fun(*this, + &Window::OnDirectoryNavigation)); PluginApi::menu_ = &menu_; PluginApi::notebook_ = ¬ebook_; PluginApi::InitPlugins(); @@ -31,13 +41,67 @@ Window::Window() : window_box_.pack_start(menu_.view(), Gtk::PACK_SHRINK); window_box_.pack_start(notebook_.entry_view(), Gtk::PACK_SHRINK); window_box_.pack_start(notebook_.view()); + show_all_children(); } // Window constructor void Window::OnWindowHide() { hide(); } +void Window::OnFileOpenFolder() { + Gtk::FileChooserDialog dialog("Please choose a folder", + Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER); + + dialog.set_transient_for(*this); + //Add response buttons the the dialog: + dialog.add_button("_Cancel", Gtk::RESPONSE_CANCEL); + dialog.add_button("Select", Gtk::RESPONSE_OK); + + int result = dialog.run(); + + //Handle the response: + switch(result) + { + case(Gtk::RESPONSE_OK): + { + std::cout << "Folder selected: " << dialog.get_filename() + << std::endl; + notebook_.directories().open_folder(dialog.get_filename()); + break; + } + case(Gtk::RESPONSE_CANCEL): + { + std::cout << "Cancel clicked." << std::endl; + break; + } + default: + { + std::cout << "Unexpected button clicked." << std::endl; + break; + } + } +} +void Window::OnDirectoryNavigation(const Gtk::TreeModel::Path& path, + Gtk::TreeViewColumn* column) { + Gtk::TreeModel::iterator iter = notebook_.directories().m_refTreeModel->get_iter(path); + if(iter) { + Gtk::TreeModel::Row row = *iter; + boost::filesystem::path fs_path(Glib::ustring(row[notebook_.directories().view().m_col_path])); + if(boost::filesystem::is_directory(fs_path)) { + std::cout << "Expand folder: " << row[notebook_.directories().view().m_col_path] << std::endl; + notebook_.directories().m_TreeView.row_expanded(path) ? + notebook_.directories().m_TreeView.collapse_row(path) : + notebook_.directories().m_TreeView.expand_row(path, false); + } else { + std::stringstream sstm; + sstm << row[notebook_.directories().view().m_col_path]; + std::string file = sstm.str(); + std::cout << "open file: "<< row[notebook_.directories().view().m_col_path] << std::endl; + notebook_.OnOpenFile(file); + } + } +} void Window::OnOpenFile() { Gtk::FileChooserDialog dialog("Please choose a file", Gtk::FILE_CHOOSER_ACTION_OPEN); diff --git a/juci/window.h b/juci/window.h index c95e632..f3a00fa 100644 --- a/juci/window.h +++ b/juci/window.h @@ -4,6 +4,7 @@ #include "api.h" #include "config.h" #include +#include "directories.h" class Window : public Gtk::Window { @@ -11,17 +12,25 @@ public: Window(); MainConfig& main_config() { return main_config_; } Gtk::Box window_box_; + + + //private: MainConfig main_config_; Keybindings::Controller keybindings_; Menu::Controller menu_; Notebook::Controller notebook_; + + Keybindings::Controller& keybindings() { return keybindings_; } private: //signal handlers void OnWindowHide(); void OnOpenFile(); + void OnFileOpenFolder(); + void OnDirectoryNavigation(const Gtk::TreeModel::Path& path, + Gtk::TreeViewColumn* column); }; #endif // JUCI_WINDOW_H