Browse Source

Cleanup of sourcefile

merge-requests/365/head
Jørgen Lien Sellæg 11 years ago
parent
commit
3045c728cc
  1. 3
      src/api.cc
  2. 61
      src/config.cc
  3. 148
      src/directories.cc
  4. 77
      src/directories.h
  5. 68
      src/files.h
  6. 2
      src/juci.cc
  7. 2
      src/juci.h
  8. 6
      src/menu.cc
  9. 1
      src/menu.h
  10. 146
      src/notebook.cc
  11. 16
      src/notebook.h
  12. 73
      src/source.cc
  13. 15
      src/source.h
  14. 106
      src/sourcefile.cc
  15. 31
      src/sourcefile.h
  16. 356
      src/window.cc
  17. 11
      src/window.h

3
src/api.cc

@ -205,8 +205,7 @@ void libjuci::IterToWordEnd(Gtk::TextIter &iter) {
} }
Glib::RefPtr<Gtk::TextBuffer> libjuci::BufferFromNotebook() { Glib::RefPtr<Gtk::TextBuffer> libjuci::BufferFromNotebook() {
return Glib::RefPtr<Gtk::TextBuffer>(PluginApi::notebook return Glib::RefPtr<Gtk::TextBuffer>(PluginApi::notebook->get_current_view()->get_buffer());
->CurrentSourceView()->get_buffer());
} }
Gtk::TextIter libjuci::IterFromNotebook() { Gtk::TextIter libjuci::IterFromNotebook() {

61
src/config.cc

@ -1,11 +1,9 @@
#include "singletons.h" #include "singletons.h"
#include "config.h" #include "config.h"
#include "logging.h" #include "logging.h"
#include <fstream>
#include <string>
#include <vector>
#include <exception> #include <exception>
#include "files.h" #include "files.h"
#include "sourcefile.h"
MainConfig::MainConfig() { MainConfig::MainConfig() {
find_or_create_config_files(); find_or_create_config_files();
@ -22,12 +20,9 @@ void MainConfig::find_or_create_config_files() {
for (auto &file : files) { for (auto &file : files) {
auto path = boost::filesystem::path(Singleton::config_dir() + file); auto path = boost::filesystem::path(Singleton::config_dir() + file);
if (!boost::filesystem::is_regular_file(path)) { if (!boost::filesystem::is_regular_file(path)) {
std::ofstream output; if (file == "config.json") juci::filesystem::save(path, configjson);
output.open(path.string()); if (file == "plugins.py") juci::filesystem::save(path, pluginspy);
if (file == "config.json") output << configjson; if (file == "menu.xml") juci::filesystem::save(path, menuxml);
if (file == "plugins.py") output << pluginspy;
if (file == "menu.xml") output << menuxml;
output.close();
} }
} }
} }
@ -39,41 +34,28 @@ void MainConfig::GenerateSource() {
auto source_json = cfg.get_child("source"); auto source_json = cfg.get_child("source");
auto syntax_json = source_json.get_child("syntax"); auto syntax_json = source_json.get_child("syntax");
auto colors_json = source_json.get_child("colors"); auto colors_json = source_json.get_child("colors");
auto extensions_json = source_json.get_child("extensions");
auto visual_json = source_json.get_child("visual"); auto visual_json = source_json.get_child("visual");
for (auto &i : visual_json) { for (auto &i : visual_json) {
if (i.first == "background") { if (i.first == "background")
source_cfg->background = i.second.get_value<std::string>(); source_cfg->background = i.second.get_value<std::string>();
} else if (i.first == "background_selected")
else if (i.first == "background_selected") {
source_cfg->background_selected = i.second.get_value<std::string>(); source_cfg->background_selected = i.second.get_value<std::string>();
} else if (i.first == "background_tooltips")
else if (i.first == "background_tooltips") {
source_cfg->background_tooltips = i.second.get_value<std::string>(); source_cfg->background_tooltips = i.second.get_value<std::string>();
} else if (i.first == "show_line_numbers")
else if (i.first == "show_line_numbers") {
source_cfg->show_line_numbers = i.second.get_value<std::string>() == "1" ? true : false; source_cfg->show_line_numbers = i.second.get_value<std::string>() == "1" ? true : false;
} else if (i.first == "highlight_current_line")
else if (i.first == "highlight_current_line") {
source_cfg->highlight_current_line = i.second.get_value<std::string>() == "1" ? true : false; source_cfg->highlight_current_line = i.second.get_value<std::string>() == "1" ? true : false;
} else if (i.first == "font")
else if (i.first == "font") {
source_cfg->font = i.second.get_value<std::string>(); source_cfg->font = i.second.get_value<std::string>();
} }
}
source_cfg->tab_size = source_json.get<unsigned>("tab_size"); source_cfg->tab_size = source_json.get<unsigned>("tab_size");
for (unsigned c = 0; c < source_cfg->tab_size; c++) { for (unsigned c = 0; c < source_cfg->tab_size; c++)
source_cfg->tab+=" "; source_cfg->tab+=" ";
} for (auto &i : colors_json)
for (auto &i : colors_json) {
source_cfg->tags[i.first]=i.second.get_value<std::string>(); source_cfg->tags[i.first]=i.second.get_value<std::string>();
} for (auto &i : syntax_json)
for (auto &i : syntax_json) {
source_cfg->types[i.first]=i.second.get_value<std::string>(); source_cfg->types[i.first]=i.second.get_value<std::string>();
}
for (auto &i : extensions_json) {
source_cfg->extensions.emplace_back(i.second.get_value<std::string>());
}
DEBUG("Source cfg fetched"); DEBUG("Source cfg fetched");
} }
@ -82,12 +64,10 @@ void MainConfig::GenerateTerminalCommands() {
boost::property_tree::ptree source_json = cfg.get_child("project"); boost::property_tree::ptree source_json = cfg.get_child("project");
boost::property_tree::ptree compile_commands_json = source_json.get_child("compile_commands"); boost::property_tree::ptree compile_commands_json = source_json.get_child("compile_commands");
boost::property_tree::ptree run_commands_json = source_json.get_child("run_commands"); boost::property_tree::ptree run_commands_json = source_json.get_child("run_commands");
for (auto &i : compile_commands_json) { for (auto &i : compile_commands_json)
terminal_cfg->compile_commands.emplace_back(i.second.get_value<std::string>()); terminal_cfg->compile_commands.emplace_back(i.second.get_value<std::string>());
} for (auto &i : run_commands_json)
for (auto &i : run_commands_json) {
terminal_cfg->run_command=(i.second.get_value<std::string>()); //TODO: run_commands array->one run_command? terminal_cfg->run_command=(i.second.get_value<std::string>()); //TODO: run_commands array->one run_command?
}
} }
void MainConfig::GenerateKeybindings() { void MainConfig::GenerateKeybindings() {
@ -97,12 +77,7 @@ void MainConfig::GenerateKeybindings() {
std::cerr << "menu.xml not found" << std::endl; std::cerr << "menu.xml not found" << std::endl;
throw; throw;
} }
std::ifstream input(path.string()); menu->ui = juci::filesystem::open(path);
std::string line;
if (input.is_open()) {
while (getline(input, line))
menu->ui += line;
}
boost::property_tree::ptree keys_json = cfg.get_child("keybindings"); boost::property_tree::ptree keys_json = cfg.get_child("keybindings");
for (auto &i : keys_json) { for (auto &i : keys_json) {
auto key=i.second.get_value<std::string>(); auto key=i.second.get_value<std::string>();
@ -118,8 +93,8 @@ void MainConfig::GenerateDirectoryFilter() {
boost::property_tree::ptree ignore_json = dir_json.get_child("ignore"); boost::property_tree::ptree ignore_json = dir_json.get_child("ignore");
boost::property_tree::ptree except_json = dir_json.get_child("exceptions"); boost::property_tree::ptree except_json = dir_json.get_child("exceptions");
for ( auto &i : except_json ) for ( auto &i : except_json )
dir_cfg->AddException(i.second.get_value<std::string>()); dir_cfg->exceptions.emplace_back(i.second.get_value<std::string>());
for ( auto &i : ignore_json ) for ( auto &i : ignore_json )
dir_cfg->AddIgnore(i.second.get_value<std::string>()); dir_cfg->ignored.emplace_back(i.second.get_value<std::string>());
DEBUG("Directory filter fetched"); DEBUG("Directory filter fetched");
} }

148
src/directories.cc

@ -1,104 +1,109 @@
#include "directories.h" #include "directories.h"
#include "sourcefile.h"
#include "logging.h" #include "logging.h"
#include "singletons.h" #include "singletons.h"
#include <algorithm>
#include "boost/algorithm/string.hpp"
Directories::Controller::Controller() { namespace sigc {
SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE
}
Directories::Directories() {
DEBUG("adding treeview to scrolledwindow"); DEBUG("adding treeview to scrolledwindow");
m_ScrolledWindow.add(m_TreeView); add(tree_view);
m_ScrolledWindow.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); 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(0, 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) {
Gtk::TreeModel::Row row = *iter;
std::string upath = Glib::ustring(row[column_record.path]);
boost::filesystem::path fs_path(upath);
if (boost::filesystem::is_directory(fs_path)) {
tree_view.row_expanded(path) ? tree_view.collapse_row(path) : tree_view.expand_row(path, false);
} else {
std::stringstream sstm;
sstm << row[column_record.path];
if(on_row_activated)
on_row_activated(sstm.str());
}
}
});
} }
void Directories::Controller:: void Directories::open_folder(const boost::filesystem::path& dir_path) {
open_folder(const boost::filesystem::path& dir_path) {
INFO("Open folder"); INFO("Open folder");
m_refTreeModel = Gtk::TreeStore::create(view()); tree_store->clear();
m_TreeView.set_model(m_refTreeModel); tree_view.get_column(0)->set_title(get_cmakelists_variable(dir_path, "project"));
m_TreeView.remove_all_columns(); add_paths(dir_path, Gtk::TreeModel::Row(), 0);
DEBUG("Getting project name from CMakeLists.txt");
std::string project_name = GetCmakeVarValue(dir_path, "project");
m_TreeView.append_column(project_name, view().m_col_name);
int row_id = 0;
Gtk::TreeModel::Row row;
DEBUG("Listing directories");
list_dirs(dir_path, row, row_id);
DEBUG("Sorting directories");
m_refTreeModel->set_sort_column(0, Gtk::SortType::SORT_ASCENDING);
DEBUG("Folder opened"); DEBUG("Folder opened");
} }
bool Directories::Controller::IsIgnored(std::string path) { bool Directories::ignored(std::string path) {
DEBUG("Checking if file-/directory is filtered"); DEBUG("Checking if file-/directory is filtered");
std::transform(path.begin(), path.end(), path.begin(), ::tolower); std::transform(path.begin(), path.end(), path.begin(), ::tolower);
if (Singleton::Config::directories()->IsException(path)) {
for(std::string &i : Singleton::Config::directories()->exceptions) {
if(i == path)
return false; return false;
} }
if (Singleton::Config::directories()->IsIgnored(path)) { for(auto &i : Singleton::Config::directories()->ignored) {
if(path.find(i, 0) != std::string::npos)
return true; return true;
} }
return false; return false;
} }
void Directories::Controller::
list_dirs(const boost::filesystem::path& dir_path,
Gtk::TreeModel::Row &parent,
unsigned row_id) {
void Directories::add_paths(const boost::filesystem::path& dir_path, const Gtk::TreeModel::Row &parent, unsigned row_id) {
boost::filesystem::directory_iterator end_itr; boost::filesystem::directory_iterator end_itr;
Gtk::TreeModel::Row child; Gtk::TreeModel::Row child;
Gtk::TreeModel::Row row; Gtk::TreeModel::Row row;
DEBUG(""); DEBUG("");
// Fill the treeview // Fill the treeview
for ( boost::filesystem::directory_iterator itr( dir_path ); for(boost::filesystem::directory_iterator itr(dir_path);itr != end_itr;++itr) {
itr != end_itr; if (!ignored(itr->path().filename().string())) {
++itr ) {
if (!IsIgnored(itr->path().filename().string())) {
if (boost::filesystem::is_directory(itr->status())) { if (boost::filesystem::is_directory(itr->status())) {
if (count(itr->path().string()) > count(dir_path.string())) { // is child if (boost::filesystem::canonical(itr->path()) > boost::filesystem::canonical(dir_path)) { // is child
child = *(m_refTreeModel->append(parent.children())); child = *(tree_store->append(parent.children()));
std::string col_id("a"+itr->path().filename().string()); std::string col_id("a"+itr->path().filename().string());
child[view().m_col_id] = col_id; child[column_record.id] = col_id;
child[view().m_col_name] = itr->path().filename().string(); child[column_record.name] = itr->path().filename().string();
child[view().m_col_path] = itr->path().string(); child[column_record.path] = itr->path().string();
list_dirs(itr->path(), child, row_id); add_paths(itr->path(), child, row_id);
} else { } else {
row = *(m_refTreeModel->append()); row = *(tree_store->append());
std::string col_id("a"+itr->path().filename().string()); std::string col_id("a"+itr->path().filename().string());
row[view().m_col_path] = itr->path().string(); row[column_record.path] = itr->path().string();
row[view().m_col_id] = col_id; row[column_record.id] = col_id;
row[view().m_col_name] = itr->path().filename().string(); row[column_record.name] = itr->path().filename().string();
list_dirs(itr->path(), parent, row_id); add_paths(itr->path(), parent, row_id);
} }
} else { // is a file } else { // is a file
child = *(m_refTreeModel->append(parent.children())); child = *(tree_store->append(parent.children()));
std::string col_id("b"+itr->path().filename().string()); std::string col_id("b"+itr->path().filename().string());
child[view().m_col_id] = col_id; child[column_record.id] = col_id;
child[view().m_col_name] = itr->path().filename().string(); child[column_record.name] = itr->path().filename().string();
child[view().m_col_path] = itr->path().string(); child[column_record.path] = itr->path().string();
} }
} }
} }
} }
int Directories::Controller::count(const std::string path) { std::string Directories::get_cmakelists_variable(const boost::filesystem::path& dir_path, std::string command_name) {
int count = 0;
for (size_t i = 0; i < path.size(); i++)
if (path[i] == '/')
count++;
return count;
}
std::string Directories::Controller::
GetCmakeVarValue(const boost::filesystem::path& dir_path, std::string command_name) {
INFO("fetches cmake variable value for: "+command_name); INFO("fetches cmake variable value for: "+command_name);
std::string project_name; std::string project_name;
std::string project_name_var; std::string project_name_var;
boost::filesystem::directory_iterator end_itr; boost::filesystem::directory_iterator end_itr;
for (boost::filesystem::directory_iterator itr( dir_path ); for (boost::filesystem::directory_iterator itr( dir_path );itr != end_itr;++itr ) {
itr != end_itr;
++itr ) {
if (itr->path().filename().string() == "CMakeLists.txt") { if (itr->path().filename().string() == "CMakeLists.txt") {
std::ifstream ifs(itr->path().string()); for (auto &line : juci::filesystem::lines(itr->path())) {
std::string line;
while (std::getline(ifs, line)) {
if (line.find(command_name+"(", 0) != std::string::npos if (line.find(command_name+"(", 0) != std::string::npos
|| line.find(command_name+" (", 0) != std::string::npos ) { || line.find(command_name+" (", 0) != std::string::npos ) {
size_t variable_start = line.find("{", 0); size_t variable_start = line.find("{", 0);
@ -133,8 +138,7 @@ GetCmakeVarValue(const boost::filesystem::path& dir_path, std::string command_na
} }
} }
} }
std::ifstream ifs2(itr->path().string()); for (auto &line : juci::filesystem::lines(itr->path())) {
while (std::getline(ifs2, line)) {
if (line.find("set(", 0) != std::string::npos if (line.find("set(", 0) != std::string::npos
|| line.find("set (", 0) != std::string::npos) { || line.find("set (", 0) != std::string::npos) {
if( line.find(project_name_var, 0) != std::string::npos) { if( line.find(project_name_var, 0) != std::string::npos) {
@ -155,25 +159,3 @@ GetCmakeVarValue(const boost::filesystem::path& dir_path, std::string command_na
INFO("Couldn't find value in CMakeLists.txt"); INFO("Couldn't find value in CMakeLists.txt");
return "no project name"; return "no project name";
} }
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;
}

77
src/directories.h

@ -2,69 +2,42 @@
#define JUCI_DIRECTORIES_H_ #define JUCI_DIRECTORIES_H_
#include <gtkmm.h> #include <gtkmm.h>
#include <glib.h> #include <vector>
#include <string>
#include "boost/filesystem.hpp" #include "boost/filesystem.hpp"
#include "boost/algorithm/string.hpp"
#include <utility>
#include <algorithm>
#include <iostream>
#include <fstream>
namespace Directories {
class Directories : public Gtk::ScrolledWindow {
public:
class Config { class Config {
public: public:
std::vector<std::string> ignore_list() { return ignore_list_; } std::vector<std::string> ignored;
std::vector<std::string> exception_list() { return exception_list_; } std::vector<std::string> exceptions;
void AddIgnore(std::string filter);
void AddException(std::string filter);
bool IsException(std::string path);
bool IsIgnored(std::string path);
private:
std::vector<std::string> ignore_list_;
std::vector<std::string> exception_list_;
}; };
class View : public Gtk::TreeModel::ColumnRecord {
class ColumnRecord : public Gtk::TreeModel::ColumnRecord {
public: public:
View() { ColumnRecord() {
add(m_col_id); add(id);
add(m_col_name); add(name);
add(m_col_path); add(path);
} }
Gtk::TreeModelColumn<Glib::ustring> m_col_id; Gtk::TreeModelColumn<Glib::ustring> id;
Gtk::TreeModelColumn<Glib::ustring> m_col_name; Gtk::TreeModelColumn<Glib::ustring> name;
Gtk::TreeModelColumn<Glib::ustring> m_col_path; Gtk::TreeModelColumn<Glib::ustring> path;
}; };
class Model { }; Directories();
class Controller {
public:
Controller();
View& view() { return view_;}
Model& model() { return model_;}
Gtk::ScrolledWindow& widget() {return m_ScrolledWindow;}
void open_folder(const boost::filesystem::path& dir_path); void open_folder(const boost::filesystem::path& dir_path);
void list_dirs(const boost::filesystem::path& dir_path, std::string get_cmakelists_variable(const boost::filesystem::path& dir_path, std::string command_name);
Gtk::TreeModel::Row &row, unsigned depth);
std::string GetCmakeVarValue(const boost::filesystem::path& dir_path, std::string command_name);
int count(const std::string path);
// Child widgets:
Gtk::Box m_VBox;
Gtk::ScrolledWindow m_ScrolledWindow;
Gtk::TreeView m_TreeView;
Glib::RefPtr<Gtk::TreeStore> m_refTreeModel;
bool IsIgnored(std::string path);
private: std::function<void(const std::string &file)> on_row_activated;
View view_;
Model model_;
protected: private:
void on_treeview_row_activated(const Gtk::TreeModel::Path& path, void add_paths(const boost::filesystem::path& dir_path, const Gtk::TreeModel::Row &row, unsigned depth);
Gtk::TreeViewColumn* column); Gtk::TreeView tree_view;
}; Glib::RefPtr<Gtk::TreeStore> tree_store;
} // namespace Directories ColumnRecord column_record;
bool ignored(std::string path);
};
#endif // JUCI_DIRECTORIES_H_ #endif // JUCI_DIRECTORIES_H_

68
src/files.h

@ -155,3 +155,71 @@ const std::string pluginspy =
" juci.initPlugin(current_file) \n" " juci.initPlugin(current_file) \n"
"loadplugins() \n"; "loadplugins() \n";
const std::string snippetpy =
"#!/usr/bin/python \n"
"#snippet plugin \n"
"import juci_to_python_api as juci, inspect \n"
" \n"
"def initPlugin(): \n"
" juci.addMenuElement(\"Snippet\") \n"
" juci.addSubMenuElement(\"SnippetMenu\", #name of parent menu \n"
" \"Insert snippet\", #menu description \n"
" \"insertSnippet()\", #function to execute \n"
" inspect.getfile(inspect.currentframe()), #plugin path \n"
" \"<control><alt>space\") \n"
"snippets = {} \n"
" \n"
"snippets[\"for\"] = \"\"\"\ \n"
"for(int i=0; i<v.size(); i++) { \n"
" // std::cout << v[i] << std::endl; \n"
" // Write code here \n"
"} \n"
"\"\"\" \n"
" \n"
"snippets[\"if\"] = \"\"\"\ \n"
"if(true) { \n"
" // Write code here \n"
"} \n"
"\"\"\" \n"
" \n"
"snippets[\"ifelse\"] = \"\"\"\ \n"
"if(false) { \n"
" // Write code here \n"
"} else { \n"
" // Write code here \n"
"} \n"
"\"\"\" \n"
" \n"
"snippets[\"while\"] = \"\"\"\ \n"
"while(condition) { \n"
" // Write code here \n"
"} \n"
"\"\"\" \n"
" \n"
"snippets[\"main\"] = \"\"\"\ \n"
"int main(int argc, char *argv[]) { \n"
" //Do something \n"
"} \n"
"\"\"\" \n"
" \n"
"snippets[\"hello\"] = \"\"\"\ \n"
"#include <iostream> \n"
" \n"
"int main(int argc, char *argv[]) { \n"
" std::cout << \"Hello, world! << std::endl; \n"
"} \n"
"\"\"\" \n"
" \n"
"def getSnippet(word): \n"
" try: \n"
" output = snippets[word] \n"
" except KeyError: \n"
" output = word \n"
" return output \n"
" \n"
"def insertSnippet(): \n"
" theWord=juci.getWord() \n"
" output=getSnippet(theWord) \n"
" juci.replaceWord(output) \n";

2
src/juci.cc

@ -40,7 +40,7 @@ void Juci::on_activate() {
window->directories.open_folder(directory); window->directories.open_folder(directory);
} }
for(auto &f: files) for(auto &f: files)
window->notebook.open_file(f); window->notebook.open(f);
} }
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {

2
src/juci.h

@ -1,7 +1,6 @@
#ifndef JUCI_JUCI_H_ #ifndef JUCI_JUCI_H_
#define JUCI_JUCI_H_ #define JUCI_JUCI_H_
#include "config.h"
#include "window.h" #include "window.h"
#include "logging.h" #include "logging.h"
@ -13,7 +12,6 @@ public:
void on_activate(); void on_activate();
private: private:
MainConfig main_config;
std::unique_ptr<Window> window; std::unique_ptr<Window> window;
std::string directory; std::string directory;
std::vector<std::string> files; std::vector<std::string> files;

6
src/menu.cc

@ -7,7 +7,7 @@ Menu::Menu() : box(Gtk::ORIENTATION_VERTICAL) {
action_group = Gtk::ActionGroup::create(); action_group = Gtk::ActionGroup::create();
ui_manager = Gtk::UIManager::create(); ui_manager = Gtk::UIManager::create();
action_group->add(Gtk::Action::create("FileNew", "New File")); action_group->add(Gtk::Action::create("FileMenu", "File"));
action_group->add(Gtk::Action::create("EditMenu", "Edit")); action_group->add(Gtk::Action::create("EditMenu", "Edit"));
action_group->add(Gtk::Action::create("WindowMenu", "_Window")); action_group->add(Gtk::Action::create("WindowMenu", "_Window"));
action_group->add(Gtk::Action::create("WindowSplitWindow", "Split window"), Gtk::AccelKey(key_map["split_window"]), [this]() { action_group->add(Gtk::Action::create("WindowSplitWindow", "Split window"), Gtk::AccelKey(key_map["split_window"]), [this]() {
@ -25,10 +25,6 @@ Gtk::Widget& Menu::get_widget() {
return *ui_manager->get_widget("/MenuBar"); return *ui_manager->get_widget("/MenuBar");
} }
Gtk::Menu& Menu::get_source_menu() {
return *(Gtk::Menu*)ui_manager->get_widget("/MenuBar/SourceMenu");
}
void Menu::build() { void Menu::build() {
try { try {
ui_manager->add_ui_from_string(ui); ui_manager->add_ui_from_string(ui);

1
src/menu.h

@ -9,7 +9,6 @@ class Menu {
public: public:
Menu(); Menu();
Gtk::Widget& get_widget(); Gtk::Widget& get_widget();
Gtk::Menu& get_source_menu();
void build(); void build();
Gtk::Box box; Gtk::Box box;

146
src/notebook.cc

@ -1,8 +1,7 @@
#include <fstream>
#include "notebook.h" #include "notebook.h"
#include "logging.h" #include "logging.h"
#include "sourcefile.h"
#include "singletons.h" #include "singletons.h"
#include <iostream> //TODO: remove
using namespace std; //TODO: remove using namespace std; //TODO: remove
namespace sigc { namespace sigc {
@ -10,92 +9,68 @@ namespace sigc {
} }
Notebook::Notebook() : Gtk::Notebook() { Notebook::Notebook() : Gtk::Notebook() {
INFO("Create notebook");
Gsv::init(); Gsv::init();
}
auto menu=Singleton::menu(); int Notebook::size() {
INFO("Notebook create signal handlers"); return get_n_pages();
menu->action_group->add(Gtk::Action::create("FileMenu", "File")); }
menu->action_group->add(Gtk::Action::create("WindowCloseTab", "Close tab"), Gtk::AccelKey(menu->key_map["close_tab"]), [this]() {
close_current_page();
});
menu->action_group->add(Gtk::Action::create("EditUndo", "Undo"), Gtk::AccelKey(menu->key_map["edit_undo"]), [this]() {
INFO("On undo");
Glib::RefPtr<Gsv::UndoManager> undo_manager = CurrentSourceView()->get_source_buffer()->get_undo_manager();
if (Pages() != 0 && undo_manager->can_undo()) {
undo_manager->undo();
}
INFO("Done undo");
});
menu->action_group->add(Gtk::Action::create("EditRedo", "Redo"), Gtk::AccelKey(menu->key_map["edit_redo"]), [this]() {
INFO("On Redo");
Glib::RefPtr<Gsv::UndoManager> undo_manager =
CurrentSourceView()->get_source_buffer()->get_undo_manager();
if (Pages() != 0 && undo_manager->can_redo()) {
undo_manager->redo();
}
INFO("Done Redo");
});
menu->action_group->add(Gtk::Action::create("SourceGotoDeclaration", "Go to declaration"), Gtk::AccelKey(menu->key_map["source_goto_declaration"]), [this]() { Source::View* Notebook::get_view(int page) {
if(CurrentPage()!=-1) { if(page>=size())
if(CurrentSourceView()->get_declaration_location) { return nullptr;
auto location=CurrentSourceView()->get_declaration_location(); return source_views.at(page).get();
if(location.first.size()>0) { }
open_file(location.first);
CurrentSourceView()->get_buffer()->place_cursor(CurrentSourceView()->get_buffer()->get_iter_at_offset(location.second));
while(gtk_events_pending())
gtk_main_iteration();
CurrentSourceView()->scroll_to(CurrentSourceView()->get_buffer()->get_insert(), 0.0, 1.0, 0.5);
}
}
}
});
menu->action_group->add(Gtk::Action::create("SourceGotoMethod", "Go to method"), Gtk::AccelKey(menu->key_map["source_goto_method"]), [this]() { Source::View* Notebook::get_current_view() {
if(CurrentPage()!=-1) { INFO("Getting sourceview");
if(CurrentSourceView()->goto_method) { if(get_current_page()==-1)
CurrentSourceView()->goto_method(); return nullptr;
} return get_view(get_current_page());
}
});
} }
void Notebook::open_file(std::string path) { void Notebook::open(std::string path) {
INFO("Notebook open file"); INFO("Notebook open file");
INFO("Notebook create page"); INFO("Notebook create page");
for(int c=0;c<Pages();c++) { for(int c=0;c<size();c++) {
if(path==source_views.at(c)->view->file_path) { if(path==get_view(c)->file_path) {
set_current_page(c); set_current_page(c);
return; return;
} }
} }
source_views.emplace_back(new Source(path, project_path));
auto tmp_project_path=project_path;
if(tmp_project_path=="") {
tmp_project_path=boost::filesystem::path(path).parent_path().string();
}
auto language=Source::guess_language(path);
if(language && (language->get_id()=="chdr" || language->get_id()=="c" || language->get_id()=="cpp" || language->get_id()=="objc"))
source_views.emplace_back(new Source::ClangView(path, tmp_project_path));
else
source_views.emplace_back(new Source::GenericView(path, tmp_project_path, language));
scrolled_windows.emplace_back(new Gtk::ScrolledWindow()); scrolled_windows.emplace_back(new Gtk::ScrolledWindow());
hboxes.emplace_back(new Gtk::HBox()); hboxes.emplace_back(new Gtk::HBox());
scrolled_windows.back()->add(*source_views.back()->view); scrolled_windows.back()->add(*source_views.back());
hboxes.back()->pack_start(*scrolled_windows.back(), true, true); hboxes.back()->pack_start(*scrolled_windows.back(), true, true);
boost::filesystem::path file_path(source_views.back()->view->file_path); boost::filesystem::path file_path(source_views.back()->file_path);
std::string title=file_path.filename().string(); std::string title=file_path.filename().string();
append_page(*hboxes.back(), title); append_page(*hboxes.back(), title);
show_all_children(); show_all_children();
set_current_page(Pages()-1); set_current_page(size()-1);
set_focus_child(*source_views.back()->view); set_focus_child(*source_views.back());
CurrentSourceView()->get_buffer()->set_modified(false); get_current_view()->get_buffer()->set_modified(false);
//Add star on tab label when the page is not saved: //Add star on tab label when the page is not saved:
auto source_view=CurrentSourceView(); auto source_view=get_current_view();
CurrentSourceView()->get_buffer()->signal_modified_changed().connect([this, source_view]() { get_current_view()->get_buffer()->signal_modified_changed().connect([this, source_view]() {
boost::filesystem::path file_path(source_view->file_path); boost::filesystem::path file_path(source_view->file_path);
std::string title=file_path.filename().string(); std::string title=file_path.filename().string();
if(source_view->get_buffer()->get_modified()) if(source_view->get_buffer()->get_modified())
title+="*"; title+="*";
int page=-1; int page=-1;
for(int c=0;c<Pages();c++) { for(int c=0;c<size();c++) {
if(source_views.at(c)->view.get()==source_view) { if(get_view(c)==source_view) {
page=c; page=c;
break; break;
} }
@ -105,14 +80,34 @@ void Notebook::open_file(std::string path) {
}); });
} }
bool Notebook::save(int page) {
if(page>=size())
return false;
auto view=get_view(page);
if (view->file_path != "" && view->get_buffer()->get_modified()) {
juci::filesystem::save(view->file_path, view->get_buffer()->get_text());
view->get_buffer()->set_modified(false);
Singleton::terminal()->print("File saved to: " +view->file_path+"\n");
return true;
}
return false;
}
bool Notebook::save_current() {
INFO("Notebook save current file");
if(get_current_page()==-1)
return false;
return save(get_current_page());
}
bool Notebook::close_current_page() { bool Notebook::close_current_page() {
INFO("Notebook close page"); INFO("Notebook close page");
if (Pages() != 0) { if (size() != 0) {
if(CurrentSourceView()->get_buffer()->get_modified()){ if(get_current_view()->get_buffer()->get_modified()){
if(!save_modified_dialog()) if(!save_modified_dialog())
return false; return false;
} }
int page = CurrentPage(); int page = get_current_page();
remove_page(page); remove_page(page);
source_views.erase(source_views.begin()+ page); source_views.erase(source_views.begin()+ page);
scrolled_windows.erase(scrolled_windows.begin()+page); scrolled_windows.erase(scrolled_windows.begin()+page);
@ -121,26 +116,13 @@ bool Notebook::close_current_page() {
return true; return true;
} }
Source::View* Notebook::CurrentSourceView() {
INFO("Getting sourceview");
return source_views.at(CurrentPage())->view.get();
}
int Notebook::CurrentPage() {
return get_current_page();
}
int Notebook::Pages() {
return get_n_pages();
}
bool Notebook::save_modified_dialog() { bool Notebook::save_modified_dialog() {
INFO("Notebook::save_dialog"); INFO("Notebook::save_modified_dialog");
Gtk::MessageDialog dialog((Gtk::Window&)(*get_toplevel()), "Save file!", false, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO); Gtk::MessageDialog dialog((Gtk::Window&)(*get_toplevel()), "Save file!", false, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO);
dialog.set_secondary_text("Do you want to save: " + CurrentSourceView()->file_path+" ?"); dialog.set_secondary_text("Do you want to save: " + get_current_view()->file_path+" ?");
int result = dialog.run(); int result = dialog.run();
if(result==Gtk::RESPONSE_YES) { if(result==Gtk::RESPONSE_YES) {
CurrentSourceView()->save(); save_current();
return true; return true;
} }
else if(result==Gtk::RESPONSE_NO) { else if(result==Gtk::RESPONSE_NO) {

16
src/notebook.h

@ -3,29 +3,27 @@
#include <iostream> #include <iostream>
#include "gtkmm.h" #include "gtkmm.h"
#include "entrybox.h"
#include "source.h" #include "source.h"
#include "directories.h"
#include <boost/algorithm/string/case_conv.hpp> #include <boost/algorithm/string/case_conv.hpp>
#include <type_traits> #include <type_traits>
#include <map> #include <map>
#include <sigc++/sigc++.h> #include <sigc++/sigc++.h>
#include "clangmm.h"
class Notebook : public Gtk::Notebook { class Notebook : public Gtk::Notebook {
public: public:
Notebook(); Notebook();
Source::View* CurrentSourceView(); Source::View* get_view(int page);
int CurrentPage(); int size();
Source::View* get_current_view();
bool close_current_page(); bool close_current_page();
void open_file(std::string filename); void open(std::string filename);
int Pages(); bool save(int page);
bool save_current();
std::string project_path; std::string project_path;
std::vector<std::unique_ptr<Source> > source_views;
private: private:
bool save_modified_dialog(); bool save_modified_dialog();
std::vector<std::unique_ptr<Source::View> > source_views;
std::vector<std::unique_ptr<Gtk::ScrolledWindow> > scrolled_windows; std::vector<std::unique_ptr<Gtk::ScrolledWindow> > scrolled_windows;
std::vector<std::unique_ptr<Gtk::HBox> > hboxes; std::vector<std::unique_ptr<Gtk::HBox> > hboxes;
}; };

73
src/source.cc

@ -1,7 +1,6 @@
#include "source.h" #include "source.h"
#include "sourcefile.h" #include "sourcefile.h"
#include <boost/property_tree/json_parser.hpp> #include <boost/property_tree/json_parser.hpp>
#include <fstream>
#include <boost/timer/timer.hpp> #include <boost/timer/timer.hpp>
#include "logging.h" #include "logging.h"
#include <algorithm> #include <algorithm>
@ -16,14 +15,22 @@ namespace sigc {
SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE
} }
bool Source::Config::legal_extension(std::string e) const { Glib::RefPtr<Gsv::Language> Source::guess_language(const std::string &file_path) {
std::transform(e.begin(), e.end(),e.begin(), ::tolower); auto language_manager=Gsv::LanguageManager::get_default();
if (find(extensions.begin(), extensions.end(), e) != extensions.end()) { bool result_uncertain = false;
DEBUG("Legal extension"); auto content_type = Gio::content_type_guess(file_path, NULL, 0, result_uncertain);
return true; if(result_uncertain) {
content_type.clear();
} }
DEBUG("Ilegal extension"); auto language=language_manager->guess_language(file_path, content_type);
return false; if(!language) {
auto path=boost::filesystem::path(file_path);
auto filename=path.filename().string();
auto extension=path.extension();
if(filename=="CMakeLists.txt")
language=language_manager->get_language("cmake");
}
return language;
} }
////////////// //////////////
@ -34,13 +41,10 @@ file_path(file_path), project_path(project_path) {
set_smart_home_end(Gsv::SMART_HOME_END_BEFORE); set_smart_home_end(Gsv::SMART_HOME_END_BEFORE);
set_show_line_numbers(Singleton::Config::source()->show_line_numbers); set_show_line_numbers(Singleton::Config::source()->show_line_numbers);
set_highlight_current_line(Singleton::Config::source()->highlight_current_line); set_highlight_current_line(Singleton::Config::source()->highlight_current_line);
sourcefile s(file_path);
get_source_buffer()->get_undo_manager()->begin_not_undoable_action(); get_source_buffer()->get_undo_manager()->begin_not_undoable_action();
get_source_buffer()->set_text(s.get_content()); get_source_buffer()->set_text(juci::filesystem::open(file_path));
get_source_buffer()->get_undo_manager()->end_not_undoable_action(); get_source_buffer()->get_undo_manager()->end_not_undoable_action();
get_buffer()->place_cursor(get_buffer()->get_iter_at_offset(0)); get_buffer()->place_cursor(get_buffer()->get_iter_at_offset(0));
search_settings = gtk_source_search_settings_new(); search_settings = gtk_source_search_settings_new();
gtk_source_search_settings_set_wrap_around(search_settings, true); gtk_source_search_settings_set_wrap_around(search_settings, true);
search_context = gtk_source_search_context_new(get_source_buffer()->gobj(), search_settings); search_context = gtk_source_search_context_new(get_source_buffer()->gobj(), search_settings);
@ -56,20 +60,6 @@ file_path(file_path), project_path(project_path) {
g_signal_connect(search_context, "notify::occurrences-count", G_CALLBACK(search_occurrences_updated), this); g_signal_connect(search_context, "notify::occurrences-count", G_CALLBACK(search_occurrences_updated), this);
} }
bool Source::View::save() {
INFO("Source save file");
if (file_path != "" && get_buffer()->get_modified()) {
std::ofstream file;
file.open (file_path);
file << get_buffer()->get_text();
file.close();
get_buffer()->set_modified(false);
Singleton::terminal()->print("File saved to: " +file_path+"\n");
return true;
}
return false;
}
void Source::View::search_occurrences_updated(GtkWidget* widget, GParamSpec* property, gpointer data) { void Source::View::search_occurrences_updated(GtkWidget* widget, GParamSpec* property, gpointer data) {
auto view=(Source::View*)data; auto view=(Source::View*)data;
if(view->update_search_occurrences) if(view->update_search_occurrences)
@ -241,7 +231,7 @@ bool Source::View::on_key_press_event(GdkEventKey* key) {
///////////////////// /////////////////////
//// GenericView //// //// GenericView ////
///////////////////// /////////////////////
Source::GenericView::GenericView(const std::string& file_path, const std::string& project_path) : View(file_path, project_path) { Source::GenericView::GenericView(const std::string& file_path, const std::string& project_path, Glib::RefPtr<Gsv::Language> language) : View(file_path, project_path) {
auto style_scheme_manager=Gsv::StyleSchemeManager::get_default(); auto style_scheme_manager=Gsv::StyleSchemeManager::get_default();
//TODO: add?: style_scheme_manager->prepend_search_path("~/.juci/"); //TODO: add?: style_scheme_manager->prepend_search_path("~/.juci/");
auto scheme=style_scheme_manager->get_scheme("classic"); auto scheme=style_scheme_manager->get_scheme("classic");
@ -252,20 +242,6 @@ Source::GenericView::GenericView(const std::string& file_path, const std::string
cout << "TODO, in progress: def:comment in scheme " << scheme->get_name() << " has color " << style->property_foreground() << endl; cout << "TODO, in progress: def:comment in scheme " << scheme->get_name() << " has color " << style->property_foreground() << endl;
} }
auto language_manager=Gsv::LanguageManager::get_default();
bool result_uncertain = false;
auto content_type = Gio::content_type_guess(file_path, get_buffer()->get_text(), result_uncertain);
if(result_uncertain) {
content_type.clear();
}
auto language=language_manager->guess_language(file_path, content_type);
if(!language) {
auto path=boost::filesystem::path(file_path);
auto filename=path.filename().string();
auto extension=path.extension();
if(filename=="CMakeLists.txt")
language=language_manager->get_language("cmake");
}
if(language) { if(language) {
get_source_buffer()->set_language(language); get_source_buffer()->set_language(language);
Singleton::terminal()->print("Language for file "+file_path+" set to "+language->get_name()+".\n"); Singleton::terminal()->print("Language for file "+file_path+" set to "+language->get_name()+".\n");
@ -1038,18 +1014,3 @@ Source::ClangViewAutocomplete(file_path, project_path) {
} }
}; };
} }
////////////////
//// Source ////
////////////////
Source::Source(const std::string& file_path, std::string project_path) {
if(project_path=="") {
project_path=boost::filesystem::path(file_path).parent_path().string();
}
if (Singleton::Config::source()->legal_extension(file_path.substr(file_path.find_last_of(".") + 1)))
view=std::unique_ptr<View>(new ClangView(file_path, project_path));
else
view=std::unique_ptr<View>(new GenericView(file_path, project_path));
INFO("Source Controller with childs constructed");
}

15
src/source.h

@ -15,16 +15,15 @@
#include "selectiondialog.h" #include "selectiondialog.h"
#include <set> #include <set>
class Source { namespace Source {
public: Glib::RefPtr<Gsv::Language> guess_language(const std::string &file_path);
class Config { class Config {
public: public:
bool legal_extension(std::string e) const ;
unsigned tab_size; unsigned tab_size;
bool show_line_numbers, highlight_current_line; bool show_line_numbers, highlight_current_line;
std::string tab, background, background_selected, background_tooltips, font; std::string tab, background, background_selected, background_tooltips, font;
char tab_char=' '; char tab_char=' ';
std::vector<std::string> extensions;
std::unordered_map<std::string, std::string> tags, types; std::unordered_map<std::string, std::string> tags, types;
}; // class Config }; // class Config
@ -50,8 +49,6 @@ public:
View(const std::string& file_path, const std::string& project_path); View(const std::string& file_path, const std::string& project_path);
~View(); ~View();
bool save();
void search_highlight(const std::string &text, bool case_sensitive, bool regex); void search_highlight(const std::string &text, bool case_sensitive, bool regex);
std::function<void(int number)> update_search_occurrences; std::function<void(int number)> update_search_occurrences;
void search_forward(); void search_forward();
@ -82,7 +79,7 @@ public:
class GenericView : public View { class GenericView : public View {
public: public:
GenericView(const std::string& file_path, const std::string& project_path); GenericView(const std::string& file_path, const std::string& project_path, Glib::RefPtr<Gsv::Language> language);
}; };
class ClangViewParse : public View { class ClangViewParse : public View {
@ -167,9 +164,5 @@ public:
ClangView(const std::string& file_path, const std::string& project_path): ClangView(const std::string& file_path, const std::string& project_path):
ClangViewRefactor(file_path, project_path) {} ClangViewRefactor(file_path, project_path) {}
}; };
Source(const std::string& file_path, std::string project_path);
std::unique_ptr<Source::View> view;
}; // class Source }; // class Source
#endif // JUCI_SOURCE_H_ #endif // JUCI_SOURCE_H_

106
src/sourcefile.cc

@ -1,92 +1,32 @@
#include "sourcefile.h" #include "sourcefile.h"
#include <giomm.h> #include <fstream>
#include <string>
#include <iostream>
#include <vector>
using namespace std; std::string juci::filesystem::open(std::string path) {
std::string res;
sourcefile::sourcefile(const string &input_filename) for (auto &line : lines(path)) {
: lines(), filename(input_filename) { res += line;
open(input_filename);
}
/**
*
*/
void sourcefile::open(const string &filename) {
Gio::init();
// Creates/Opens a file specified by the input string.
Glib::RefPtr<Gio::File> file = Gio::File::create_for_path(filename);
if (!file) // Gio::File has overloaded operator
cerr << "Was not able to open file: " << filename << endl;
// Creates pointer for filestream
if (!file->query_exists()) {
file->create_file()->close();
} }
return res;
Glib::RefPtr<Gio::FileInputStream> stream = file->read();
if (!stream) // error message on stream failure
cerr << filename << " returned an empty stream" << endl;
Glib::RefPtr<Gio::DataInputStream>
datainput = Gio::DataInputStream::create(stream);
string line;
while (datainput->read_line(line)) {
lines.push_back(line);
}
datainput->close();
stream->close();
}
vector<string> sourcefile::get_lines() {
return lines;
}
string sourcefile::get_line(int line_number) {
return lines[line_number];
}
int sourcefile::save(const string &text) {
Gio::init();
// Creates/Opens a file specified by the input string.
Glib::RefPtr<Gio::File> file = Gio::File::create_for_path(filename);
if (!file) // Gio::File has overloaded operator
cerr << "Was not able to open file: " << filename << endl;
// Creates
Glib::RefPtr<Gio::FileOutputStream> stream =
file->query_exists() ? file->replace() : file->create_file();
if (!stream) // error message on stream failure
cerr << filename << " returned an empty stream" << endl;
Glib::RefPtr<Gio::DataOutputStream>
output = Gio::DataOutputStream::create(stream);
output->put_string(text);
output->close();
stream->close();
return 0;
} }
string sourcefile::get_content() { std::vector<std::string> juci::filesystem::lines(std::string path) {
string res; std::vector<std::string> res;
for (auto line : lines) { std::ifstream input(path);
res.append(line).append("\n"); if (input.is_open()) {
do { res.emplace_back(); } while(getline(input, res.back()));
} }
input.close();
return res; return res;
} }
int juci::filesystem::save(std::string path, std::string new_content) {
std::ofstream output(path);
if(output.is_open()) {
output << new_content;
} else {
output.close();
return 1;
}
output.close();
return 0;
}

31
src/sourcefile.h

@ -1,21 +1,20 @@
#ifndef JUCI_SOURCEFILE_H_ #ifndef JUCI_SOURCEFILE_H_
#define JUCI_SOURCEFILE_H_ #define JUCI_SOURCEFILE_H_
#include <string>
#include <vector> #include <vector>
#include <string>
#include <boost/filesystem.hpp>
class sourcefile { namespace juci {
public: class filesystem {
explicit sourcefile(const std::string &filename); public:
std::vector<std::string> get_lines(); static std::string open(std::string);
std::string get_content(); static std::string open(boost::filesystem::path path) { return open(path.string()); }
std::string get_line(int line_number); static std::vector<std::string> lines(std::string);
int save(const std::string &text); static std::vector<std::string> lines(boost::filesystem::path path) { return lines(path.string()); };
static int save(std::string, std::string);
private: static int save(boost::filesystem::path path, std::string new_content) { return save(path.string(), new_content); }
void open(const std::string &filename); static int save(std::string path) { return save(path, ""); };
std::vector<std::string> lines; static int save(boost::filesystem::path path) { return save(path, ""); };
std::string filename; };
}; } // namepace juci
#endif // JUCI_SOURCEFILE_H_ #endif // JUCI_SOURCEFILE_H_

356
src/window.cc

@ -1,19 +1,78 @@
#include "window.h" #include "window.h"
#include "logging.h" #include "logging.h"
#include "singletons.h" #include "singletons.h"
#include "sourcefile.h"
#include "config.h"
#include "api.h"
namespace sigc { namespace sigc {
SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE
} }
Window::Window() : notebook(), plugin_api(&notebook), box(Gtk::ORIENTATION_VERTICAL) { Window::Window() : box(Gtk::ORIENTATION_VERTICAL) {
INFO("Create Window"); INFO("Create Window");
set_title("juCi++"); set_title("juCi++");
set_default_size(600, 400); set_default_size(600, 400);
set_events(Gdk::POINTER_MOTION_MASK|Gdk::FOCUS_CHANGE_MASK|Gdk::SCROLL_MASK); set_events(Gdk::POINTER_MOTION_MASK|Gdk::FOCUS_CHANGE_MASK|Gdk::SCROLL_MASK);
add(box); add(box);
//TODO: see TODO Window::on_directory_navigation
directories.m_TreeView.signal_row_activated().connect(sigc::mem_fun(*this, &Window::on_directory_navigation)); MainConfig(); //Read the configs here
PluginApi(&this->notebook); //Initialise plugins
add_menu();
box.pack_start(entry_box, Gtk::PACK_SHRINK);
directory_and_notebook_panes.pack1(directories, true, true); //TODO: should be pack1(directories, ...) Clean up directories.*
directory_and_notebook_panes.pack2(notebook);
directory_and_notebook_panes.set_position(120);
vpaned.set_position(300);
vpaned.pack1(directory_and_notebook_panes, true, false);
vpaned.pack2(Singleton::terminal()->view, true, true);
box.pack_end(vpaned);
show_all_children();
directories.on_row_activated=[this](const std::string &file) {
notebook.open(file);
};
entry_box.signal_show().connect([this](){
std::vector<Gtk::Widget*> focus_chain;
focus_chain.emplace_back(&entry_box);
box.set_focus_chain(focus_chain);
});
entry_box.signal_hide().connect([this](){
box.unset_focus_chain();
});
entry_box.signal_hide().connect([this]() {
if(notebook.get_current_page()!=-1) {
notebook.get_current_view()->grab_focus();
}
});
notebook.signal_switch_page().connect([this](Gtk::Widget* page, guint page_num) {
if(search_entry_shown && entry_box.labels.size()>0 && notebook.get_current_page()!=-1) {
notebook.get_current_view()->update_search_occurrences=[this](int number){
entry_box.labels.begin()->update(0, std::to_string(number));
};
notebook.get_current_view()->search_highlight(last_search, case_sensitive_search, regex_search);
}
if(notebook.get_current_page()!=-1) {
if(auto menu_item=dynamic_cast<Gtk::MenuItem*>(Singleton::menu()->ui_manager->get_widget("/MenuBar/SourceMenu/SourceGotoDeclaration")))
menu_item->set_sensitive((bool)notebook.get_current_view()->get_declaration_location);
if(auto menu_item=dynamic_cast<Gtk::MenuItem*>(Singleton::menu()->ui_manager->get_widget("/MenuBar/SourceMenu/SourceGotoMethod")))
menu_item->set_sensitive((bool)notebook.get_current_view()->goto_method);
if(auto menu_item=dynamic_cast<Gtk::MenuItem*>(Singleton::menu()->ui_manager->get_widget("/MenuBar/SourceMenu/SourceRename")))
menu_item->set_sensitive((bool)notebook.get_current_view()->rename_similar_tokens);
}
});
INFO("Window created");
} // Window constructor
void Window::add_menu() {
auto menu=Singleton::menu(); auto menu=Singleton::menu();
INFO("Adding actions to menu"); INFO("Adding actions to menu");
menu->action_group->add(Gtk::Action::create("FileQuit", "Quit juCi++"), Gtk::AccelKey(menu->key_map["quit"]), [this]() { menu->action_group->add(Gtk::Action::create("FileQuit", "Quit juCi++"), Gtk::AccelKey(menu->key_map["quit"]), [this]() {
@ -33,7 +92,7 @@ Window::Window() : notebook(), plugin_api(&notebook), box(Gtk::ORIENTATION_VERTI
}); });
menu->action_group->add(Gtk::Action::create("FileSave", "Save"), Gtk::AccelKey(menu->key_map["save"]), [this]() { menu->action_group->add(Gtk::Action::create("FileSave", "Save"), Gtk::AccelKey(menu->key_map["save"]), [this]() {
notebook.CurrentSourceView()->save(); notebook.save_current();
}); });
menu->action_group->add(Gtk::Action::create("EditCopy", "Copy"), Gtk::AccelKey(menu->key_map["edit_copy"]), [this]() { menu->action_group->add(Gtk::Action::create("EditCopy", "Copy"), Gtk::AccelKey(menu->key_map["edit_copy"]), [this]() {
@ -47,94 +106,92 @@ Window::Window() : notebook(), plugin_api(&notebook), box(Gtk::ORIENTATION_VERTI
auto widget=get_focus(); auto widget=get_focus();
if(auto entry=dynamic_cast<Gtk::Entry*>(widget)) if(auto entry=dynamic_cast<Gtk::Entry*>(widget))
entry->cut_clipboard(); entry->cut_clipboard();
else { else if(notebook.get_current_page()!=-1)
if (notebook.Pages() != 0) notebook.get_current_view()->get_buffer()->cut_clipboard(Gtk::Clipboard::get());
notebook.CurrentSourceView()->get_buffer()->cut_clipboard(Gtk::Clipboard::get());
}
}); });
menu->action_group->add(Gtk::Action::create("EditPaste", "Paste"), Gtk::AccelKey(menu->key_map["edit_paste"]), [this]() { menu->action_group->add(Gtk::Action::create("EditPaste", "Paste"), Gtk::AccelKey(menu->key_map["edit_paste"]), [this]() {
auto widget=get_focus(); auto widget=get_focus();
if(auto entry=dynamic_cast<Gtk::Entry*>(widget)) if(auto entry=dynamic_cast<Gtk::Entry*>(widget))
entry->paste_clipboard(); entry->paste_clipboard();
else { else if(notebook.get_current_page()!=-1)
if (notebook.Pages() != 0) notebook.get_current_view()->get_buffer()->paste_clipboard(Gtk::Clipboard::get());
notebook.CurrentSourceView()->get_buffer()->paste_clipboard(Gtk::Clipboard::get());
}
}); });
menu->action_group->add(Gtk::Action::create("EditFind", "Find"), Gtk::AccelKey(menu->key_map["edit_find"]), [this]() { menu->action_group->add(Gtk::Action::create("EditFind", "Find"), Gtk::AccelKey(menu->key_map["edit_find"]), [this]() {
search_and_replace_entry(); search_and_replace_entry();
}); });
menu->action_group->add(Gtk::Action::create("EditUndo", "Undo"), Gtk::AccelKey(menu->key_map["edit_undo"]), [this]() {
menu->action_group->add(Gtk::Action::create("SourceRename", "Rename function/variable"), Gtk::AccelKey(menu->key_map["source_rename"]), [this]() { INFO("On undo");
entry_box.clear(); if(notebook.get_current_page()!=-1) {
if(notebook.CurrentPage()!=-1) { auto undo_manager = notebook.get_current_view()->get_source_buffer()->get_undo_manager();
if(notebook.CurrentSourceView()->get_token && notebook.CurrentSourceView()->get_token_name) { if (undo_manager->can_undo()) {
auto token=std::make_shared<std::string>(notebook.CurrentSourceView()->get_token()); undo_manager->undo();
if(token->size()>0 && notebook.CurrentSourceView()->get_token_name) {
auto token_name=std::make_shared<std::string>(notebook.CurrentSourceView()->get_token_name());
for(int c=0;c<notebook.Pages();c++) {
if(notebook.source_views.at(c)->view->tag_similar_tokens) {
notebook.source_views.at(c)->view->tag_similar_tokens(*token);
} }
} }
entry_box.labels.emplace_back(); INFO("Done undo");
auto label_it=entry_box.labels.begin(); });
label_it->update=[label_it](int state, const std::string& message){ menu->action_group->add(Gtk::Action::create("EditRedo", "Redo"), Gtk::AccelKey(menu->key_map["edit_redo"]), [this]() {
label_it->set_text("Warning: only opened and parsed tabs will have its content renamed, and modified files will be saved."); INFO("On Redo");
}; if(notebook.get_current_page()!=-1) {
label_it->update(0, ""); auto undo_manager = notebook.get_current_view()->get_source_buffer()->get_undo_manager();
entry_box.entries.emplace_back(*token_name, [this, token_name, token](const std::string& content){ if(undo_manager->can_redo()) {
if(notebook.CurrentPage()!=-1 && content!=*token_name) { undo_manager->redo();
for(int c=0;c<notebook.Pages();c++) {
if(notebook.source_views.at(c)->view->rename_similar_tokens) {
auto number=notebook.source_views.at(c)->view->rename_similar_tokens(*token, content);
if(number>0) {
Singleton::terminal()->print("Replaced "+std::to_string(number)+" occurrences in file "+notebook.source_views.at(c)->view->file_path+"\n");
notebook.source_views.at(c)->view->save();
} }
} }
INFO("Done Redo");
});
menu->action_group->add(Gtk::Action::create("SourceGotoDeclaration", "Go to declaration"), Gtk::AccelKey(menu->key_map["source_goto_declaration"]), [this]() {
if(notebook.get_current_page()!=-1) {
if(notebook.get_current_view()->get_declaration_location) {
auto location=notebook.get_current_view()->get_declaration_location();
if(location.first.size()>0) {
notebook.open(location.first);
notebook.get_current_view()->get_buffer()->place_cursor(notebook.get_current_view()->get_buffer()->get_iter_at_offset(location.second));
while(gtk_events_pending())
gtk_main_iteration();
notebook.get_current_view()->scroll_to(notebook.get_current_view()->get_buffer()->get_insert(), 0.0, 1.0, 0.5);
} }
entry_box.hide();
} }
});
auto entry_it=entry_box.entries.begin();
entry_box.buttons.emplace_back("Rename", [this, entry_it](){
entry_it->activate();
});
entry_box.show();
} }
});
menu->action_group->add(Gtk::Action::create("SourceGotoMethod", "Go to method"), Gtk::AccelKey(menu->key_map["source_goto_method"]), [this]() {
if(notebook.get_current_page()!=-1) {
if(notebook.get_current_view()->goto_method) {
notebook.get_current_view()->goto_method();
} }
} }
}); });
menu->action_group->add(Gtk::Action::create("SourceRename", "Rename"), Gtk::AccelKey(menu->key_map["source_rename"]), [this]() {
rename_token_entry();
});
menu->action_group->add(Gtk::Action::create("ProjectCompileAndRun", "Compile And Run"), Gtk::AccelKey(menu->key_map["compile_and_run"]), [this]() { menu->action_group->add(Gtk::Action::create("ProjectCompileAndRun", "Compile And Run"), Gtk::AccelKey(menu->key_map["compile_and_run"]), [this]() {
if(notebook.CurrentPage()==-1) if(notebook.get_current_page()==-1)
return; return;
notebook.CurrentSourceView()->save(); notebook.save_current();
if (running.try_lock()) { if (running.try_lock()) {
std::thread execute([this]() { std::thread execute([this]() {
std::string path = notebook.CurrentSourceView()->file_path; std::string path = notebook.get_current_view()->file_path;
size_t pos = path.find_last_of("/\\"); size_t pos = path.find_last_of("/\\");
if(pos != std::string::npos) { if(pos != std::string::npos) {
path.erase(path.begin()+pos,path.end()); path.erase(path.begin()+pos,path.end());
Singleton::terminal()->SetFolderCommand(path); Singleton::terminal()->SetFolderCommand(path);
} }
Singleton::terminal()->Compile(); Singleton::terminal()->Compile();
std::string executable = directories.GetCmakeVarValue(path,"add_executable"); std::string executable = directories.get_cmakelists_variable(path,"add_executable");
Singleton::terminal()->Run(executable); Singleton::terminal()->Run(executable);
running.unlock(); running.unlock();
}); });
execute.detach(); execute.detach();
} }
}); });
menu->action_group->add(Gtk::Action::create("ProjectCompile", "Compile"), Gtk::AccelKey(menu->key_map["compile"]), [this]() { menu->action_group->add(Gtk::Action::create("ProjectCompile", "Compile"), Gtk::AccelKey(menu->key_map["compile"]), [this]() {
if(notebook.CurrentPage()==-1) if(notebook.get_current_page()==-1)
return; return;
notebook.CurrentSourceView()->save(); notebook.save_current();
if (running.try_lock()) { if (running.try_lock()) {
std::thread execute([this]() { std::thread execute([this]() {
std::string path = notebook.CurrentSourceView()->file_path; std::string path = notebook.get_current_view()->file_path;
size_t pos = path.find_last_of("/\\"); size_t pos = path.find_last_of("/\\");
if(pos != std::string::npos){ if(pos != std::string::npos){
path.erase(path.begin()+pos,path.end()); path.erase(path.begin()+pos,path.end());
@ -146,58 +203,15 @@ Window::Window() : notebook(), plugin_api(&notebook), box(Gtk::ORIENTATION_VERTI
execute.detach(); execute.detach();
} }
}); });
INFO("Done adding actions to menu, building menu:")
menu->action_group->add(Gtk::Action::create("WindowCloseTab", "Close tab"), Gtk::AccelKey(menu->key_map["close_tab"]), [this]() {
notebook.close_current_page();
});
add_accel_group(menu->ui_manager->get_accel_group()); add_accel_group(menu->ui_manager->get_accel_group());
menu->build(); menu->build();
INFO("Menu build") INFO("Menu build")
box.pack_start(menu->get_widget(), Gtk::PACK_SHRINK); box.pack_start(menu->get_widget(), Gtk::PACK_SHRINK);
box.pack_start(entry_box, Gtk::PACK_SHRINK); }
directory_and_notebook_panes.pack1(directories.widget(), true, true); //TODO: should be pack1(directories, ...) Clean up directories.*
directory_and_notebook_panes.pack2(notebook);
directory_and_notebook_panes.set_position(120);
vpaned.set_position(300);
vpaned.pack1(directory_and_notebook_panes, true, false);
vpaned.pack2(Singleton::terminal()->view, true, true);
box.pack_end(vpaned);
show_all_children();
entry_box.signal_show().connect([this](){
std::vector<Gtk::Widget*> focus_chain;
focus_chain.emplace_back(&entry_box);
box.set_focus_chain(focus_chain);
});
entry_box.signal_hide().connect([this](){
box.unset_focus_chain();
});
entry_box.signal_hide().connect([this]() {
if(notebook.CurrentPage()!=-1) {
notebook.CurrentSourceView()->grab_focus();
}
});
notebook.signal_switch_page().connect([this](Gtk::Widget* page, guint page_num) {
if(search_entry_shown && entry_box.labels.size()>0 && notebook.CurrentPage()!=-1) {
notebook.CurrentSourceView()->update_search_occurrences=[this](int number){
entry_box.labels.begin()->update(0, std::to_string(number));
};
notebook.CurrentSourceView()->search_highlight(last_search, case_sensitive_search, regex_search);
}
if(notebook.CurrentPage()!=-1) {
if(auto menu_item=dynamic_cast<Gtk::MenuItem*>(Singleton::menu()->ui_manager->get_widget("/MenuBar/SourceMenu/SourceGotoDeclaration")))
menu_item->set_sensitive((bool)notebook.CurrentSourceView()->get_declaration_location);
if(auto menu_item=dynamic_cast<Gtk::MenuItem*>(Singleton::menu()->ui_manager->get_widget("/MenuBar/SourceMenu/SourceGotoMethod")))
menu_item->set_sensitive((bool)notebook.CurrentSourceView()->goto_method);
if(auto menu_item=dynamic_cast<Gtk::MenuItem*>(Singleton::menu()->ui_manager->get_widget("/MenuBar/SourceMenu/SourceRename")))
menu_item->set_sensitive((bool)notebook.CurrentSourceView()->rename_similar_tokens);
}
});
INFO("Window created");
} // Window constructor
bool Window::on_key_press_event(GdkEventKey *event) { bool Window::on_key_press_event(GdkEventKey *event) {
if(event->keyval==GDK_KEY_Escape) if(event->keyval==GDK_KEY_Escape)
@ -246,8 +260,8 @@ bool Window::on_delete_event (GdkEventAny *event) {
} }
void Window::hide() { void Window::hide() {
auto size=notebook.source_views.size(); auto size=notebook.size();
for(size_t c=0;c<size;c++) { for(int c=0;c<size;c++) {
if(!notebook.close_current_page()) if(!notebook.close_current_page())
return; return;
} }
@ -266,18 +280,12 @@ void Window::new_file_entry() {
Singleton::terminal()->print("Error: "+p.string()+" already exists.\n"); Singleton::terminal()->print("Error: "+p.string()+" already exists.\n");
} }
else { else {
std::ofstream f(p.string().c_str()); juci::filesystem::save(p);
if(f) { notebook.open(boost::filesystem::canonical(p).string());
notebook.open_file(boost::filesystem::canonical(p).string());
Singleton::terminal()->print("New file "+p.string()+" created.\n"); Singleton::terminal()->print("New file "+p.string()+" created.\n");
if(notebook.project_path!="") if(notebook.project_path!="")
directories.open_folder(notebook.project_path); //TODO: Do refresh instead directories.open_folder(notebook.project_path); //TODO: Do refresh instead
} }
else {
Singleton::terminal()->print("Error: could not create new file "+p.string()+".\n");
}
f.close();
}
} }
entry_box.hide(); entry_box.hide();
}); });
@ -310,7 +318,6 @@ void Window::open_file_dialog() {
Gtk::FileChooserDialog dialog("Please choose a file", Gtk::FILE_CHOOSER_ACTION_OPEN); Gtk::FileChooserDialog dialog("Please choose a file", Gtk::FILE_CHOOSER_ACTION_OPEN);
if(notebook.project_path.size()>0) if(notebook.project_path.size()>0)
gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), notebook.project_path.c_str()); gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), notebook.project_path.c_str());
std::cout << notebook.project_path << std::endl;
dialog.set_transient_for(*this); dialog.set_transient_for(*this);
dialog.set_position(Gtk::WindowPosition::WIN_POS_CENTER_ALWAYS); dialog.set_position(Gtk::WindowPosition::WIN_POS_CENTER_ALWAYS);
@ -340,14 +347,16 @@ void Window::open_file_dialog() {
if(result==Gtk::RESPONSE_OK) { if(result==Gtk::RESPONSE_OK) {
std::string path = dialog.get_filename(); std::string path = dialog.get_filename();
notebook.open_file(path); notebook.open(path);
} }
} }
void Window::save_file_dialog() { void Window::save_file_dialog() {
if(notebook.get_current_page()==-1)
return;
INFO("Save file dialog"); INFO("Save file dialog");
Gtk::FileChooserDialog dialog(*this, "Please choose a file", Gtk::FILE_CHOOSER_ACTION_SAVE); Gtk::FileChooserDialog dialog(*this, "Please choose a file", Gtk::FILE_CHOOSER_ACTION_SAVE);
gtk_file_chooser_set_filename((GtkFileChooser*)dialog.gobj(), notebook.CurrentSourceView()->file_path.c_str()); gtk_file_chooser_set_filename((GtkFileChooser*)dialog.gobj(), notebook.get_current_view()->file_path.c_str());
dialog.set_position(Gtk::WindowPosition::WIN_POS_CENTER_ALWAYS); dialog.set_position(Gtk::WindowPosition::WIN_POS_CENTER_ALWAYS);
dialog.add_button("_Cancel", Gtk::RESPONSE_CANCEL); dialog.add_button("_Cancel", Gtk::RESPONSE_CANCEL);
dialog.add_button("_Save", Gtk::RESPONSE_OK); dialog.add_button("_Save", Gtk::RESPONSE_OK);
@ -358,10 +367,10 @@ void Window::save_file_dialog() {
if(path.size()>0) { if(path.size()>0) {
std::ofstream file(path); std::ofstream file(path);
if(file) { if(file) {
file << notebook.CurrentSourceView()->get_buffer()->get_text(); file << notebook.get_current_view()->get_buffer()->get_text();
file.close(); file.close();
notebook.open_file(path); notebook.open(path);
Singleton::terminal()->print("File saved to: " + notebook.CurrentSourceView()->file_path+"\n"); Singleton::terminal()->print("File saved to: " + notebook.get_current_view()->file_path+"\n");
if(notebook.project_path!="") if(notebook.project_path!="")
directories.open_folder(notebook.project_path); //TODO: Do refresh instead directories.open_folder(notebook.project_path); //TODO: Do refresh instead
} }
@ -371,27 +380,6 @@ void Window::save_file_dialog() {
} }
} }
//TODO: move most of it to Directories
void Window::on_directory_navigation(const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* column) {
INFO("Directory navigation");
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();
notebook.open_file(file);
}
}
}
void Window::search_and_replace_entry() { void Window::search_and_replace_entry() {
entry_box.clear(); entry_box.clear();
entry_box.labels.emplace_back(); entry_box.labels.emplace_back();
@ -408,41 +396,41 @@ void Window::search_and_replace_entry() {
} }
}; };
entry_box.entries.emplace_back(last_search, [this](const std::string& content){ entry_box.entries.emplace_back(last_search, [this](const std::string& content){
if(notebook.CurrentPage()!=-1) if(notebook.get_current_page()!=-1)
notebook.CurrentSourceView()->search_forward(); notebook.get_current_view()->search_forward();
}); });
auto search_entry_it=entry_box.entries.begin(); auto search_entry_it=entry_box.entries.begin();
search_entry_it->set_placeholder_text("Find"); search_entry_it->set_placeholder_text("Find");
if(notebook.CurrentPage()!=-1) { if(notebook.get_current_page()!=-1) {
notebook.CurrentSourceView()->update_search_occurrences=[label_it](int number){ notebook.get_current_view()->update_search_occurrences=[label_it](int number){
label_it->update(0, std::to_string(number)); label_it->update(0, std::to_string(number));
}; };
notebook.CurrentSourceView()->search_highlight(search_entry_it->get_text(), case_sensitive_search, regex_search); notebook.get_current_view()->search_highlight(search_entry_it->get_text(), case_sensitive_search, regex_search);
} }
search_entry_it->signal_key_press_event().connect([this](GdkEventKey* event){ search_entry_it->signal_key_press_event().connect([this](GdkEventKey* event){
if(event->keyval==GDK_KEY_Return && event->state==GDK_SHIFT_MASK) { if(event->keyval==GDK_KEY_Return && event->state==GDK_SHIFT_MASK) {
if(notebook.CurrentPage()!=-1) if(notebook.get_current_page()!=-1)
notebook.CurrentSourceView()->search_backward(); notebook.get_current_view()->search_backward();
} }
return false; return false;
}); });
search_entry_it->signal_changed().connect([this, search_entry_it](){ search_entry_it->signal_changed().connect([this, search_entry_it](){
last_search=search_entry_it->get_text(); last_search=search_entry_it->get_text();
if(notebook.CurrentPage()!=-1) if(notebook.get_current_page()!=-1)
notebook.CurrentSourceView()->search_highlight(search_entry_it->get_text(), case_sensitive_search, regex_search); 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){ entry_box.entries.emplace_back(last_replace, [this](const std::string &content){
if(notebook.CurrentPage()!=-1) if(notebook.get_current_page()!=-1)
notebook.CurrentSourceView()->replace_forward(content); notebook.get_current_view()->replace_forward(content);
}); });
auto replace_entry_it=entry_box.entries.begin(); auto replace_entry_it=entry_box.entries.begin();
replace_entry_it++; replace_entry_it++;
replace_entry_it->set_placeholder_text("Replace"); replace_entry_it->set_placeholder_text("Replace");
replace_entry_it->signal_key_press_event().connect([this, replace_entry_it](GdkEventKey* event){ replace_entry_it->signal_key_press_event().connect([this, replace_entry_it](GdkEventKey* event){
if(event->keyval==GDK_KEY_Return && event->state==GDK_SHIFT_MASK) { if(event->keyval==GDK_KEY_Return && event->state==GDK_SHIFT_MASK) {
if(notebook.CurrentPage()!=-1) if(notebook.get_current_page()!=-1)
notebook.CurrentSourceView()->replace_backward(replace_entry_it->get_text()); notebook.get_current_view()->replace_backward(replace_entry_it->get_text());
} }
return false; return false;
}); });
@ -451,38 +439,80 @@ void Window::search_and_replace_entry() {
}); });
entry_box.buttons.emplace_back("Find", [this](){ entry_box.buttons.emplace_back("Find", [this](){
if(notebook.CurrentPage()!=-1) if(notebook.get_current_page()!=-1)
notebook.CurrentSourceView()->search_forward(); notebook.get_current_view()->search_forward();
}); });
entry_box.buttons.emplace_back("Replace", [this, replace_entry_it](){ entry_box.buttons.emplace_back("Replace", [this, replace_entry_it](){
if(notebook.CurrentPage()!=-1) if(notebook.get_current_page()!=-1)
notebook.CurrentSourceView()->replace_forward(replace_entry_it->get_text()); notebook.get_current_view()->replace_forward(replace_entry_it->get_text());
}); });
entry_box.buttons.emplace_back("Replace all", [this, replace_entry_it](){ entry_box.buttons.emplace_back("Replace all", [this, replace_entry_it](){
if(notebook.CurrentPage()!=-1) if(notebook.get_current_page()!=-1)
notebook.CurrentSourceView()->replace_all(replace_entry_it->get_text()); notebook.get_current_view()->replace_all(replace_entry_it->get_text());
}); });
entry_box.toggle_buttons.emplace_back("Match case"); entry_box.toggle_buttons.emplace_back("Match case");
entry_box.toggle_buttons.back().set_active(case_sensitive_search); entry_box.toggle_buttons.back().set_active(case_sensitive_search);
entry_box.toggle_buttons.back().on_activate=[this, search_entry_it](){ entry_box.toggle_buttons.back().on_activate=[this, search_entry_it](){
case_sensitive_search=!case_sensitive_search; case_sensitive_search=!case_sensitive_search;
if(notebook.CurrentPage()!=-1) if(notebook.get_current_page()!=-1)
notebook.CurrentSourceView()->search_highlight(search_entry_it->get_text(), case_sensitive_search, regex_search); 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.emplace_back("Use regex");
entry_box.toggle_buttons.back().set_active(regex_search); entry_box.toggle_buttons.back().set_active(regex_search);
entry_box.toggle_buttons.back().on_activate=[this, search_entry_it](){ entry_box.toggle_buttons.back().on_activate=[this, search_entry_it](){
regex_search=!regex_search; regex_search=!regex_search;
if(notebook.CurrentPage()!=-1) if(notebook.get_current_page()!=-1)
notebook.CurrentSourceView()->search_highlight(search_entry_it->get_text(), case_sensitive_search, regex_search); notebook.get_current_view()->search_highlight(search_entry_it->get_text(), case_sensitive_search, regex_search);
}; };
entry_box.signal_hide().connect([this]() { entry_box.signal_hide().connect([this]() {
for(int c=0;c<notebook.Pages();c++) { for(int c=0;c<notebook.size();c++) {
notebook.source_views.at(c)->view->update_search_occurrences=nullptr; notebook.get_view(c)->update_search_occurrences=nullptr;
notebook.source_views.at(c)->view->search_highlight("", case_sensitive_search, regex_search); notebook.get_view(c)->search_highlight("", case_sensitive_search, regex_search);
} }
search_entry_shown=false; search_entry_shown=false;
}); });
search_entry_shown=true; search_entry_shown=true;
entry_box.show(); entry_box.show();
} }
void Window::rename_token_entry() {
entry_box.clear();
if(notebook.get_current_page()!=-1) {
if(notebook.get_current_view()->get_token && notebook.get_current_view()->get_token_name) {
auto token=std::make_shared<std::string>(notebook.get_current_view()->get_token());
if(token->size()>0 && notebook.get_current_view()->get_token_name) {
auto token_name=std::make_shared<std::string>(notebook.get_current_view()->get_token_name());
for(int c=0;c<notebook.size();c++) {
if(notebook.get_view(c)->tag_similar_tokens) {
notebook.get_view(c)->tag_similar_tokens(*token);
}
}
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("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_name, [this, token_name, token](const std::string& content){
if(notebook.get_current_page()!=-1 && content!=*token_name) {
for(int c=0;c<notebook.size();c++) {
if(notebook.get_view(c)->rename_similar_tokens) {
auto number=notebook.get_view(c)->rename_similar_tokens(*token, content);
if(number>0) {
Singleton::terminal()->print("Replaced "+std::to_string(number)+" occurrences in file "+notebook.get_view(c)->file_path+"\n");
notebook.save(c);
}
}
}
entry_box.hide();
}
});
auto entry_it=entry_box.entries.begin();
entry_box.buttons.emplace_back("Rename", [this, entry_it](){
entry_it->activate();
});
entry_box.show();
}
}
}
}

11
src/window.h

@ -1,15 +1,16 @@
#ifndef JUCI_WINDOW_H_ #ifndef JUCI_WINDOW_H_
#define JUCI_WINDOW_H_ #define JUCI_WINDOW_H_
#include "api.h"
#include <cstddef> #include <cstddef>
#include "directories.h"
#include "entrybox.h"
#include "notebook.h"
class Window : public Gtk::Window { class Window : public Gtk::Window {
public: public:
Window(); Window();
Notebook notebook; Notebook notebook;
Directories::Controller directories; Directories directories;
protected: protected:
bool on_key_press_event(GdkEventKey *event); bool on_key_press_event(GdkEventKey *event);
bool on_delete_event (GdkEventAny *event); bool on_delete_event (GdkEventAny *event);
@ -18,17 +19,17 @@ private:
Gtk::VPaned vpaned; Gtk::VPaned vpaned;
Gtk::Paned directory_and_notebook_panes; Gtk::Paned directory_and_notebook_panes;
EntryBox entry_box; EntryBox entry_box;
PluginApi plugin_api;
std::mutex running; std::mutex running;
void add_menu();
void hide(); void hide();
void new_file_entry(); void new_file_entry();
void open_folder_dialog(); void open_folder_dialog();
void open_file_dialog(); void open_file_dialog();
void save_file_dialog(); void save_file_dialog();
void on_directory_navigation(const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* column);
void search_and_replace_entry(); void search_and_replace_entry();
void rename_token_entry();
std::string last_search; std::string last_search;
std::string last_replace; std::string last_replace;
bool case_sensitive_search=true; bool case_sensitive_search=true;

Loading…
Cancel
Save