diff --git a/juci/CMakeLists.txt b/juci/CMakeLists.txt index abe2d87..625d06a 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,10 @@ add_executable(${project_name} notebook.h entry.h entry.cc + directories.h + directories.cc + terminal.h + terminal.cc ) add_library(${module} SHARED diff --git a/juci/api.cc b/juci/api.cc index acee2cb..ae7534a 100644 --- a/juci/api.cc +++ b/juci/api.cc @@ -205,13 +205,13 @@ Glib::RefPtr libjuci::BufferFromNotebook() { // int i = 0; // while (!PluginApi::notebook_->source_vec_.at(i)->view().has_focus()) { // i++; - //while(!PluginApi::notebook_->CurrentTextView().has_focus()) { + // while(!PluginApi::notebook_->CurrentTextView().has_focus()) { // i++; // } return Glib::RefPtr(PluginApi::notebook_ // ->source_vec_.at(i) // ->view().get_buffer()); - ->CurrentTextView().get_buffer()); + ->CurrentTextView().get_buffer()); } Gtk::TextIter libjuci::IterFromNotebook() { diff --git a/juci/config.cc b/juci/config.cc index ff6440a..3e8a264 100644 --- a/juci/config.cc +++ b/juci/config.cc @@ -1,14 +1,14 @@ #include "config.h" - MainConfig::MainConfig() : -keybindings_cfg_(), source_cfg_() { + keybindings_cfg_(), source_cfg_() { boost::property_tree::json_parser::read_json("config.json", cfg_); GenerateSource(); GenerateKeybindings(); - // keybindings_cfg_ = cfg_.get_child("keybindings"); - // notebook_cfg_ = cfg_.get_child("notebook"); - // menu_cfg_ = cfg_.get_child("menu"); + GenerateDirectoryFilter(); + // keybindings_cfg_ = cfg_.get_child("keybindings"); + // notebook_cfg_ = cfg_.get_child("notebook"); + // menu_cfg_ = cfg_.get_child("menu"); } void MainConfig::GenerateSource() { @@ -37,9 +37,15 @@ void MainConfig::GenerateKeybindings() { for (auto &i : keys_json) keybindings_cfg_.key_map()[i.first] = i.second.get_value(); } -Keybindings::Config& MainConfig::keybindings_cfg() { - return keybindings_cfg_; -} -Source::Config& MainConfig::source_cfg() { - return source_cfg_; + +void MainConfig::GenerateDirectoryFilter() { + boost::property_tree::ptree dir_json = cfg_.get_child("directoryfilter"); + boost::property_tree::ptree ignore_json = dir_json.get_child("ignore"); + boost::property_tree::ptree except_json = dir_json.get_child("exceptions"); + for ( auto &i : except_json ) + dir_cfg_.AddException(i.second.get_value()); + for ( auto &i : ignore_json ) + dir_cfg_.AddIgnore(i.second.get_value()); } + + diff --git a/juci/config.h b/juci/config.h index ee49224..edcb5fc 100644 --- a/juci/config.h +++ b/juci/config.h @@ -4,18 +4,22 @@ #include #include "keybindings.h" #include "source.h" +#include "directories.h" class MainConfig { public: MainConfig(); - Source::Config& source_cfg(); - Keybindings::Config& keybindings_cfg(); + Source::Config& source_cfg() { return source_cfg_; } + Keybindings::Config& keybindings_cfg() { return keybindings_cfg_; } + Directories::Config& dir_cfg() { return dir_cfg_; } void PrintMenu(); void GenerateSource(); void GenerateKeybindings(); + void GenerateDirectoryFilter(); private: boost::property_tree::ptree cfg_; boost::property_tree::ptree key_tree_; Source::Config source_cfg_; Keybindings::Config keybindings_cfg_; + Directories::Config dir_cfg_; }; diff --git a/juci/config.json b/juci/config.json index 9f24e39..e4ff1f5 100644 --- a/juci/config.json +++ b/juci/config.json @@ -22,8 +22,22 @@ "split_window": "s", "new_h_file": "h", "new_cc_file": "c", - "close_tab": "w" + "close_tab": "w", + "open_folder": "o" }, + "directoryfilter": { + "ignore": [ + "cmake", + "#", + "~", + ".idea", + "in-lowercase.pls" + ], + "exceptions": [ + "cmakelists.txt", + "in-lowercase.pls" + ] + }, "example": { "key": "value", "key2": [ diff --git a/juci/directories.cc b/juci/directories.cc new file mode 100644 index 0000000..04aa9f8 --- /dev/null +++ b/juci/directories.cc @@ -0,0 +1,155 @@ +#include "directories.h" + +Directories::Controller::Controller(Directories::Config& cfg) : + config_(cfg) { + 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; + list_dirs(dir_path, row, row_id); + m_refTreeModel->set_sort_column(0, Gtk::SortType::SORT_ASCENDING); +} + +bool Directories::Controller::IsIgnored(std::string path) { + std::transform(path.begin(), path.end(), path.begin(), ::tolower); + // std::cout << "ignored?: " << path << std::endl; + if (config().IsException(path)) { + return false; + } + if (config().IsIgnored(path)) { + return true; + } + return false; +} +void 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 + for ( boost::filesystem::directory_iterator itr( dir_path ); + itr != end_itr; + ++itr ) { + if (!IsIgnored(itr->path().filename().string())) { + if (boost::filesystem::is_directory(itr->status())) { + if (count(itr->path().string()) > count(dir_path.string())) { // is child + 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 ) { + if (itr->path().filename().string() == "CMakeLists.txt") { + 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 ) { + 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); + boost::algorithm::trim(project_name_var); + if (variabel_start == std::string::npos) { // not a variabel + variabel_start = line.find("(", 0); + variabel_end = line.find(")", variabel_start); + return line.substr(variabel_start+1, + (variabel_end)-variabel_start-1); + } + break; + } + } + std::ifstream ifs2(itr->path().string()); + while (std::getline(ifs2, line)) { + if (line.find("set(", 0) != std::string::npos + || line.find("set (", 0) != std::string::npos) { + if( line.find(project_name_var, 0) != std::string::npos) { + 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+1, + variabel_end-variabel_start-1); + boost::algorithm::trim(project_name); + return project_name; + } + } + } + break; + } + } + return "no project name"; +} + +Directories::Config::Config() { +} +Directories::Config::Config(Directories::Config& cfg) : + ignore_list_(cfg.ignore_list()), exception_list_(cfg.exception_list()) { +} + +void Directories::Config::AddIgnore(std::string filter) { + ignore_list_.push_back(filter); +} + +void Directories::Config::AddException(std::string filter) { + exception_list_.push_back(filter); +} + +bool Directories::Config::IsIgnored(std::string str) { + for ( auto &i : ignore_list() ) + if (str.find(i, 0) != std::string::npos) + return true; + return false; +} + +bool Directories::Config::IsException(std::string str) { + for ( std::string &i : exception_list() ) + if (i == str) + return true; + return false; +} diff --git a/juci/directories.h b/juci/directories.h new file mode 100644 index 0000000..47b56e2 --- /dev/null +++ b/juci/directories.h @@ -0,0 +1,75 @@ +#ifndef JUCI_DIRECTORIES_H_ +#define JUCI_DIRECTORIES_H_ + +#include +#include +#include "boost/filesystem.hpp" +#include "boost/algorithm/string.hpp" +#include +#include +#include +#include + +namespace Directories { + + class Config { + public: + Config(Config &original); + Config(); + std::vector ignore_list() { return ignore_list_; } + std::vector exception_list() { return exception_list_; } + void AddIgnore(std::string filter); + void AddException(std::string filter); + bool IsException(std::string path); + bool IsIgnored(std::string path); + private: + std::vector ignore_list_; + std::vector exception_list_; + }; + 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(); + Controller(Directories::Config& cfg); + View& view() { return view_;} + Model& model() { return model_;} + Directories::Config& config() { return config_;} + Gtk::ScrolledWindow& widget() {return m_ScrolledWindow;} + bool open_folder(const boost::filesystem::path& dir_path); + void 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; + bool IsIgnored(std::string path); + + private: + View view_; + Model model_; + Directories::Config config_; + + protected: + void on_treeview_row_activated(const Gtk::TreeModel::Path& path, + Gtk::TreeViewColumn* column); + }; +} // namespace Directories + +#endif // JUCI_DIRECTORIES_H_ diff --git a/juci/juci.cc b/juci/juci.cc index 84b1e6f..b2afc98 100644 --- a/juci/juci.cc +++ b/juci/juci.cc @@ -1,11 +1,11 @@ #include "window.h" - int main(int argc, char *argv[]) { Glib::RefPtr app = Gtk::Application::create( argc, argv, "no.sout.juci"); + Window window; //api::LoadPlugin("juci_api_test"); diff --git a/juci/keybindings.cc b/juci/keybindings.cc index b7b8a36..2408155 100644 --- a/juci/keybindings.cc +++ b/juci/keybindings.cc @@ -50,8 +50,7 @@ Keybindings::Config::Config(Keybindings::Config &original) { Keybindings::Config::Config() { menu_xml_ = ""; - std::unordered_map key_map(); -} + } void Keybindings::Config::AppendXml(std::string &child) { menu_xml_ += child; 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 e1485d2..695591b 100644 --- a/juci/notebook.cc +++ b/juci/notebook.cc @@ -1,117 +1,187 @@ - #include "notebook.h" Notebook::Model::Model() { cc_extension_ = ".cc"; h_extension_ = ".h"; - scrollvalue_ = 20; + scrollvalue_ = 50; } -Notebook::View::View(){ - view_.pack_start(notebook_); + +Notebook::View::View() { + view_.pack2(notebook_); + view_.set_position(120); } Notebook::Controller::Controller(Keybindings::Controller& keybindings, - Source::Config& source_cfg) : -source_config_(source_cfg) { + Source::Config& source_cfg, + Directories::Config& dir_cfg) : + source_config_(source_cfg), + directories_(dir_cfg) { OnNewPage("juCi++"); refClipboard_ = Gtk::Clipboard::get(); - keybindings.action_group_menu()->add(Gtk::Action::create("FileMenu", - Gtk::Stock::FILE)); - /* File->New files */ + view().pack1(directories_.widget(), true, true); + CreateKeybindings(keybindings); + } // Constructor + +void Notebook::Controller::CreateKeybindings(Keybindings::Controller + &keybindings) { + directories().m_TreeView.signal_row_activated() + .connect(sigc::mem_fun(*this, + &Notebook::Controller::OnDirectoryNavigation)); + + keybindings.action_group_menu()-> + add(Gtk::Action::create("FileMenu", + Gtk::Stock::FILE)); - keybindings.action_group_menu()->add(Gtk::Action::create("FileNewStandard", - Gtk::Stock::NEW, - "New empty file", - "Create a new file"), - [this]() { - is_new_file_ = true; - OnFileNewEmptyfile(); - }); - keybindings.action_group_menu()->add(Gtk::Action::create("FileNewCC", - "New cc file"), - Gtk::AccelKey(keybindings.config_ - .key_map()["new_cc_file"]), - [this]() { - is_new_file_ = true; - // OnFileNewCCFile(); - OnOpenFile("/home/zalox/bachelor/juci/juci/source.cc"); - }); - keybindings.action_group_menu()->add(Gtk::Action::create("FileNewH", - "New h file"), - Gtk::AccelKey(keybindings.config_ - .key_map()["new_h_file"]), - [this]() { - is_new_file_ = true; - OnFileNewHeaderFile(); - }); - keybindings.action_group_menu()->add(Gtk::Action::create("WindowCloseTab", - "Close tab"), - Gtk::AccelKey(keybindings.config_ - .key_map()["close_tab"]), - [this]() { - OnCloseCurrentPage(); - }); - keybindings.action_group_menu()->add(Gtk::Action::create("EditFind", - Gtk::Stock::FIND), - [this]() { - is_new_file_ = false; - OnEditSearch(); - //TODO(Oyvang, Zalox, Forgi)Create function OnEditFind(); - }); - keybindings.action_group_menu()->add(Gtk::Action::create("EditCopy", - Gtk::Stock::COPY), - [this]() { - OnEditCopy(); - }); - keybindings.action_group_menu()->add(Gtk::Action::create("EditCut", - Gtk::Stock::CUT), - [this]() { - OnEditCut(); - }); - keybindings.action_group_menu()->add(Gtk::Action::create("EditPaste", - Gtk::Stock::PASTE), - [this]() { - OnEditPaste(); - }); - entry_.view_.entry().signal_activate().connect( - [this]() { - if(is_new_file_){ - OnNewPage(entry_.text()); - entry_.OnHideEntries(is_new_file_); - }else{ - Search(true); - } - }); - entry_.button_apply().signal_clicked().connect( - [this]() { - OnNewPage(entry_.text()); - entry_.OnHideEntries(is_new_file_); - }); - entry_.button_close().signal_clicked().connect( - [this]() { - entry_.OnHideEntries(is_new_file_); - }); - entry_.button_next().signal_clicked().connect( - [this]() { - Search(true); - }); - entry_.button_prev().signal_clicked().connect( - [this]() { - Search(false); - }); + keybindings.action_group_menu()-> + add(Gtk::Action::create("FileNewStandard", + Gtk::Stock::NEW, + "New empty file", + "Create a new file"), + [this]() { + is_new_file_ = true; + OnFileNewEmptyfile(); + }); + keybindings.action_group_menu()-> + add(Gtk::Action::create("FileNewCC", + "New cc file"), + Gtk::AccelKey(keybindings.config_ + .key_map()["new_cc_file"]), + [this]() { + is_new_file_ = true; + OnFileNewCCFile(); + }); + keybindings.action_group_menu()-> + add(Gtk::Action::create("FileNewH", + "New h file"), + Gtk::AccelKey(keybindings.config_ + .key_map()["new_h_file"]), + [this]() { + is_new_file_ = true; + OnFileNewHeaderFile(); + }); + keybindings.action_group_menu()-> + add(Gtk::Action::create("WindowCloseTab", + "Close tab"), + Gtk::AccelKey(keybindings.config_ + .key_map()["close_tab"]), + [this]() { + OnCloseCurrentPage(); + }); + keybindings.action_group_menu()-> + add(Gtk::Action::create("EditFind", + Gtk::Stock::FIND), + [this]() { + is_new_file_ = false; + OnEditSearch(); + // TODO(Oyvang) Zalox, Forgi)Create function OnEditFind(); + }); + keybindings.action_group_menu()-> + add(Gtk::Action::create("EditCopy", + Gtk::Stock::COPY), + [this]() { + OnEditCopy(); + }); + keybindings.action_group_menu()-> + add(Gtk::Action::create("EditCut", + Gtk::Stock::CUT), + [this]() { + OnEditCut(); + }); + keybindings.action_group_menu()-> + add(Gtk::Action::create("EditPaste", + Gtk::Stock::PASTE), + [this]() { + OnEditPaste(); + }); + keybindings.action_group_hidden()-> + add(Gtk::Action::create("EditPaste", + Gtk::Stock::PASTE), + [this]() { + OnEditPaste(); + }); + entry_.view_.entry().signal_activate(). + connect( + [this]() { + if (is_new_file_) { + OnNewPage(entry_.text()); + entry_.OnHideEntries(is_new_file_); + } else { + Search(true); + } + }); + entry_.button_apply().signal_clicked(). + connect( + [this]() { + OnNewPage(entry_.text()); + entry_.OnHideEntries(is_new_file_); + }); + entry_.button_close().signal_clicked(). + connect( + [this]() { + entry_.OnHideEntries(is_new_file_); + }); + entry_.button_next().signal_clicked(). + connect( + [this]() { + Search(true); + }); + entry_.button_prev().signal_clicked(). + connect( + [this]() { + Search(false); + }); +} + +void Notebook::Controller::GeneratePopup(std::vector items) { + Gtk::ScrolledWindow popup_scroll_; + Gtk::ListViewText listview_(1, false, Gtk::SelectionMode::SELECTION_SINGLE); + Gtk::Dialog popup_("", true); + listview_.set_enable_search(false); + listview_.set_hscroll_policy(Gtk::ScrollablePolicy::SCROLL_NATURAL); + listview_.set_activate_on_single_click(true); + listview_.signal_row_activated(). + connect([this, &listview_, &popup_](const Gtk::TreeModel::Path& path, + Gtk::TreeViewColumn*) { + std::string t = listview_.get_text(listview_.get_selected()[0]); + CurrentTextView().get_buffer()->insert_at_cursor(t); + popup_.response(Gtk::RESPONSE_DELETE_EVENT); + }); + for (auto &i : items) listview_.append(i); + listview_.set_headers_visible(false); + popup_scroll_.add(listview_); + popup_.get_vbox()->pack_start(popup_scroll_); + popup_.set_size_request(80, 80); + popup_.show_all(); + Gdk::Rectangle temp1, temp2; + CurrentTextView(). + get_cursor_locations( + CurrentTextView(). + get_buffer()->get_insert()-> + get_iter(), temp1, temp2); - text_vec_.back()->view(). - signal_scroll_event().connect(sigc::mem_fun( - this, - &Notebook::Controller:: - scroll_event_callback)); - - -}//Constructor + int x = temp1.get_x(); + int y = temp1.get_y(); + text_vec_.at(CurrentPage())-> + view().buffer_to_window_coords( + Gtk::TextWindowType::TEXT_WINDOW_WIDGET, + temp2.get_x(), + temp2.get_y(), + x, y); -bool Notebook::Controller::scroll_event_callback(GdkEventScroll* scroll_event) { + int widht = Notebook().get_width()-88; + int height = Notebook().get_height()-180; + if (x > widht) { + x = widht; } + if (y > height) { + y = height; + } + popup_.move(x, y+88); + popup_.run(); +} + +bool Notebook::Controller::ScrollEventCallback(GdkEventScroll* scroll_event) { int page = CurrentPage(); int direction_y = scroll_event->delta_y; int direction_x = scroll_event->delta_x; @@ -119,21 +189,14 @@ bool Notebook::Controller::scroll_event_callback(GdkEventScroll* scroll_event) { Glib::RefPtr adj = scrolledtext_vec_.at(page)-> get_vscrollbar()->get_adjustment(); - if ( direction_y != 0 ) { - int dir_val = direction_y==-1?-model_.scrollvalue_:+model_.scrollvalue_; + int dir_val = direction_y == -1 ? -model_.scrollvalue_:+model_.scrollvalue_; adj->set_value(adj->get_value()+dir_val); text_vec_.at(page)->view().set_vadjustment(adj); linenumbers_vec_.at(page)->view().set_vadjustment(adj); } - if ( direction_x != 0 ) { - int dir_val = direction_x==-1?-model_.scrollvalue_:+model_.scrollvalue_; - adj->set_value(adj->get_value()+dir_val); - text_vec_.at(page)->view().set_hadjustment(adj); - } return true; } - Notebook::Controller::~Controller() { for (auto &i : text_vec_) delete i; for (auto &i : linenumbers_vec_) delete i; @@ -142,22 +205,20 @@ 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() { return entry_.view(); } - void Notebook::Controller::OnNewPage(std::string name) { OnCreatePage(); - std::cout << "oppretta pages" << std::endl; text_vec_.back()->OnNewEmptyFile(); Notebook().append_page(*editor_vec_.back(), name); Notebook().show_all_children(); Notebook().set_current_page(Pages()-1); - Notebook().set_focus_child(text_vec_.at(Pages()-1)->view()); + Notebook().set_focus_child(text_vec_.at(Pages()-1)->view()); } void Notebook::Controller::OnOpenFile(std::string path) { @@ -166,34 +227,37 @@ 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(); } -void Notebook::Controller::OnCreatePage(){ - text_vec_.push_back(new Source::Controller(source_config())); // add arguments - linenumbers_vec_.push_back(new Source::Controller(source_config())); // add arguments +void Notebook::Controller::OnCreatePage() { + text_vec_.push_back(new Source::Controller(source_config())); + linenumbers_vec_.push_back(new Source::Controller(source_config())); scrolledline_vec_.push_back(new Gtk::ScrolledWindow()); scrolledtext_vec_.push_back(new Gtk::ScrolledWindow()); editor_vec_.push_back(new Gtk::HBox()); scrolledtext_vec_.back()->add(text_vec_.back()->view()); scrolledline_vec_.back()->add(linenumbers_vec_.back()->view()); - linenumbers_vec_.back()->view().get_buffer()->set_text("1 \n"); + linenumbers_vec_.back()->view().get_buffer()->set_text("1 "); linenumbers_vec_.back()->view().override_color(Gdk::RGBA("Black")); linenumbers_vec_.back()-> view().set_justification(Gtk::Justification::JUSTIFY_RIGHT); scrolledline_vec_.back()->get_vscrollbar()->hide(); linenumbers_vec_.back()->view().set_editable(false); linenumbers_vec_.back()->view().set_sensitive(false); - editor_vec_.back()->pack_start(*scrolledline_vec_.back(),false,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()); } void Notebook::Controller::OnCloseCurrentPage() { - //TODO (oyvang, zalox, forgi) Save a temp file, in case you close one you dont want to close? - if(Pages()!=0){ + // TODO(oyvang) zalox, forgi) + // Save a temp file, in case you close one you dont want to close? + if (Pages() != 0) { int page = CurrentPage(); Notebook().remove_page(page); delete text_vec_.at(page); @@ -207,7 +271,6 @@ void Notebook::Controller::OnCloseCurrentPage() { scrolledline_vec_.erase(scrolledline_vec_.begin()+page); editor_vec_.erase(editor_vec_.begin()+page); } - } void Notebook::Controller::OnFileNewEmptyfile() { entry_.OnShowSetFilenName(""); @@ -234,24 +297,24 @@ void Notebook::Controller::OnEditCut() { } } -std::string Notebook::Controller::GetCursorWord(){ +std::string Notebook::Controller::GetCursorWord() { int page = CurrentPage(); std::string word; - Gtk::TextIter start,end; + Gtk::TextIter start, end; start = Buffer(text_vec_.at(page))->get_insert()->get_iter(); end = Buffer(text_vec_.at(page))->get_insert()->get_iter(); - if(!end.ends_line()) { - while(!end.ends_word()){ + if (!end.ends_line()) { + while (!end.ends_word()) { end.forward_char(); } } - if(!start.starts_line()) { - while(!start.starts_word()){ + if (!start.starts_line()) { + while (!start.starts_word()) { start.backward_char(); } } - word = Buffer(text_vec_.at(page))->get_text(start,end); - //TODO(Oyvang)fix selected text + word = Buffer(text_vec_.at(page))->get_text(start, end); + // TODO(Oyvang) fix selected text return word; } @@ -261,7 +324,7 @@ void Notebook::Controller::OnEditSearch() { entry_.OnShowSearch(GetCursorWord()); } -void Notebook::Controller::Search(bool forward){ +void Notebook::Controller::Search(bool forward) { int page = CurrentPage(); std::string search_word; search_word = entry_.text(); @@ -269,65 +332,93 @@ void Notebook::Controller::Search(bool forward){ if ( !forward ) { if ( search_match_start_ == 0 || - search_match_start_.get_line_offset() == 0) { - search_match_start_= Buffer(text_vec_.at(CurrentPage()))->end(); + search_match_start_.get_line_offset() == 0) { + search_match_start_ = Buffer(text_vec_.at(CurrentPage()))->end(); } search_match_start_. backward_search(search_word, - Gtk::TextSearchFlags::TEXT_SEARCH_TEXT_ONLY | - Gtk::TextSearchFlags::TEXT_SEARCH_VISIBLE_ONLY, - search_match_start_, - search_match_end_); + Gtk::TextSearchFlags::TEXT_SEARCH_TEXT_ONLY | + Gtk::TextSearchFlags::TEXT_SEARCH_VISIBLE_ONLY, + search_match_start_, + search_match_end_); } else { if ( search_match_end_ == 0 ) { - search_match_end_= Buffer(text_vec_.at(CurrentPage()))->begin(); + search_match_end_ = Buffer(text_vec_.at(CurrentPage()))->begin(); } search_match_end_. forward_search(search_word, - Gtk::TextSearchFlags::TEXT_SEARCH_TEXT_ONLY | - Gtk::TextSearchFlags::TEXT_SEARCH_VISIBLE_ONLY, - search_match_start_, - search_match_end_); + Gtk::TextSearchFlags::TEXT_SEARCH_TEXT_ONLY | + Gtk::TextSearchFlags::TEXT_SEARCH_VISIBLE_ONLY, + search_match_start_, + search_match_end_); } } -void Notebook::Controller::OnBufferChange() { - int page = CurrentPage(); - int line_nr = Buffer(text_vec_.at(page))->get_line_count(); - Glib::RefPtr - mark = Gtk::TextBuffer::Mark::create(); - Glib::RefPtr - mark_lines = Gtk::TextBuffer::Mark::create(); - - if(Buffer(text_vec_.at(page))->get_insert()->get_iter().starts_line() && +void Notebook::Controller::OnBufferChange() { + int page = CurrentPage(); + int text_nr = Buffer(text_vec_.at(page))->get_line_count(); + int line_nr = Buffer(linenumbers_vec_.at(page))->get_line_count(); + while (line_nr < text_nr) { + line_nr++; + Buffer(linenumbers_vec_.at(page))-> + insert(Buffer(linenumbers_vec_.at(page))->end(), + "\n"+std::to_string(line_nr)+" "); + } + while (line_nr > text_nr) { + Gtk::TextIter iter = + Buffer(linenumbers_vec_.at(page))->get_iter_at_line(line_nr); + iter.backward_char(); + line_nr--; + Buffer(linenumbers_vec_.at(page))-> + erase(iter, + Buffer(linenumbers_vec_.at(page))->end()); + } + if (Buffer(text_vec_.at(page))->get_insert()->get_iter().starts_line() && Buffer(text_vec_.at(page))->get_insert()->get_iter().get_line() == Buffer(text_vec_.at(page))->end().get_line()) { - std::string lines ="1 "; - for ( int it = 2; it <= line_nr; ++it ) { - lines.append("\n"+ std::to_string(it)+" "); - } - Buffer(linenumbers_vec_.at(page))->set_text(lines); - - Buffer(text_vec_.at(page))-> - add_mark( - mark, - Buffer(text_vec_.at(page))->end()); - Buffer(linenumbers_vec_.at(page))-> - add_mark( - mark_lines, - Buffer(linenumbers_vec_.at(page))->end()); - - text_vec_.at(page)->view().scroll_to(mark); - linenumbers_vec_.at(page)->view().scroll_to(mark_lines); - }else{ - Buffer(text_vec_.at(page))-> - add_mark( - mark, - Buffer(text_vec_.at(page))-> - get_insert()->get_iter()); - } + GdkEventScroll* scroll = new GdkEventScroll; + scroll->delta_y = 1.0; + scroll->delta_x = 0.0; + ScrollEventCallback(scroll); + delete scroll; + } + Gtk::TextIter start, end; + std::string word; + start = Buffer(text_vec_.at(page))->get_insert()->get_iter(); + end = Buffer(text_vec_.at(page))->get_insert()->get_iter(); + start.backward_char(); + word = Buffer(text_vec_.at(page))->get_text(start, end); + if (word == ".") { + // TODO(Forgie) Zalox,Forgie) Remove TEST + std::vector TEST; + TEST.push_back("toString()"); + TEST.push_back("toLower()"); + TEST.push_back("toUpper()"); + TEST.push_back("fuckOFF()"); + TEST.push_back("fuckOFF()"); + GeneratePopup(TEST); + } +} +void Notebook::Controller +::OnDirectoryNavigation(const Gtk::TreeModel::Path& path, + Gtk::TreeViewColumn* column) { + Gtk::TreeModel::iterator iter = directories().m_refTreeModel->get_iter(path); + if (iter) { + Gtk::TreeModel::Row row = *iter; + std::string upath = Glib::ustring(row[directories().view().m_col_path]); + boost::filesystem::path fs_path(upath); + if (boost::filesystem::is_directory(fs_path)) { + directories().m_TreeView.row_expanded(path) ? + directories().m_TreeView.collapse_row(path) : + directories().m_TreeView.expand_row(path, false); + } else { + std::stringstream sstm; + sstm << row[directories().view().m_col_path]; + std::string file = sstm.str(); + OnOpenFile(file); + } + } } - Gtk::TextView& Notebook::Controller::CurrentTextView() { return text_vec_.at(CurrentPage())->view(); @@ -338,7 +429,7 @@ int Notebook::Controller::CurrentPage() { } Glib::RefPtr -Notebook::Controller::Buffer( Source::Controller *source ) { +Notebook::Controller::Buffer(Source::Controller *source) { return source->view().get_buffer(); } @@ -350,9 +441,10 @@ Gtk::Notebook& Notebook::Controller::Notebook() { } void Notebook::Controller::BufferChangeHandler(Glib::RefPtr - buffer) { + buffer) { buffer->signal_changed().connect( - [this]() { - OnBufferChange(); - }); + [this]() { + OnBufferChange(); + }); } + diff --git a/juci/notebook.h b/juci/notebook.h index cddf18a..4a657fe 100644 --- a/juci/notebook.h +++ b/juci/notebook.h @@ -5,6 +5,10 @@ #include "gtkmm.h" #include "entry.h" #include "source.h" +#include "directories.h" +#include +#include +#include namespace Notebook { class Model { @@ -17,19 +21,19 @@ 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 { public: - Controller(Keybindings::Controller& keybindings, - Source::Config& config); + Source::Config& config, + Directories::Config& dir_cfg); ~Controller(); - Glib::RefPtr Buffer( Source::Controller *source); + Glib::RefPtr Buffer(Source::Controller *source); Gtk::TextView& CurrentTextView(); int CurrentPage(); Gtk::Box& entry_view(); @@ -44,18 +48,33 @@ namespace Notebook { void OnFileNewCCFile(); void OnFileNewEmptyfile(); void OnFileNewHeaderFile(); + void OnFileOpenFolder(); + void OnDirectoryNavigation(const Gtk::TreeModel::Path& path, + Gtk::TreeViewColumn* column); void OnNewPage(std::string name); void OnOpenFile(std::string filename); void OnCreatePage(); - bool scroll_event_callback(GdkEventScroll* scroll_event); + bool ScrollEventCallback(GdkEventScroll* scroll_event); int Pages(); - Gtk::HBox& view(); + + Directories::Controller& directories() { return directories_; } + Gtk::Paned& view(); + + void GeneratePopup(std::vector items); + // Gtk::HBox& view(); + void Search(bool forward); const Source::Config& source_config() { return source_config_; } + protected: void BufferChangeHandler(Glib::RefPtr buffer); + private: + void CreateKeybindings(Keybindings::Controller& keybindings); + Glib::RefPtr m_refBuilder; + Glib::RefPtr refActionGroup; Source::Config source_config_; + Directories::Controller directories_; View view_; Model model_; bool is_new_file_; diff --git a/juci/terminal.cc b/juci/terminal.cc new file mode 100644 index 0000000..e96a21a --- /dev/null +++ b/juci/terminal.cc @@ -0,0 +1,6 @@ +#include "terminal.h" + + + + + diff --git a/juci/terminal.h b/juci/terminal.h new file mode 100644 index 0000000..83d0738 --- /dev/null +++ b/juci/terminal.h @@ -0,0 +1,27 @@ + +#ifndef JUCI_NOTEBOOK_H_ +#define JUCI_NOTEBOOK_H_ + +#include +#include "gtkmm.h" + +namespace Terminal { + + class View { + public: + View(); + //Gtk::HBox view() {return view_;} + private: + Gtk::HBox view_; + Gtk::TextBuffer buffer_; + Gtk::TextView textview_; + }; // class view + + class Controller { + public: + + + }; // class controller +} // namespace Terminal + +#endif // JUCI_NOTEBOOK_H_ diff --git a/juci/window.cc b/juci/window.cc index 8e96e9c..1097e52 100644 --- a/juci/window.cc +++ b/juci/window.cc @@ -4,12 +4,11 @@ Window::Window() : window_box_(Gtk::ORIENTATION_VERTICAL), main_config_(), keybindings_(main_config_.keybindings_cfg()), - notebook_(keybindings(), main_config_.source_cfg()), + notebook_(keybindings(), main_config_.source_cfg(), main_config_.dir_cfg()), menu_(keybindings()) { 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,13 @@ 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(); + }); PluginApi::menu_ = &menu_; PluginApi::notebook_ = ¬ebook_; PluginApi::InitPlugins(); @@ -37,6 +43,40 @@ Window::Window() : 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::OnOpenFile() { Gtk::FileChooserDialog dialog("Please choose a file", diff --git a/juci/window.h b/juci/window.h index c95e632..a0b810f 100644 --- a/juci/window.h +++ b/juci/window.h @@ -11,17 +11,24 @@ 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(); + }; #endif // JUCI_WINDOW_H