diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 954e2ac..82e9cfe 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -88,13 +88,18 @@ set(source_files juci.h if(MSYS) list(APPEND source_files terminal_win.cc) + list(APPEND source_files dialogs_win.cc) + message("MSYS detected") else() list(APPEND source_files terminal.cc) + list(APPEND source_files dialogs.h) + list(APPEND source_files dialogs.cc) + message("UNIX detected") endif() if(${validation}) add_executable(${project_name} ${source_files}) - + # add_library(${module} SHARED # api # api_ext) @@ -122,7 +127,6 @@ if(${validation}) # target_link_libraries(${module} ${PYTHON_LIBRARIES} ${Boost_LIBRARIES}) # target_link_libraries(${module} ${Boost_LIBRARIES}) - target_link_libraries(${project_name} ${LIBCLANG_LIBRARIES} ${LCL_LIBRARIES} diff --git a/src/config.cc b/src/config.cc index 13cc842..ca52e43 100644 --- a/src/config.cc +++ b/src/config.cc @@ -138,7 +138,7 @@ void MainConfig::GenerateSource() { void MainConfig::GenerateDirectoryFilter() { auto dir_cfg=Singleton::Config::directories(); - DEBUG("Fetching directory filter"); + JDEBUG("Fetching directory filter"); 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"); @@ -146,5 +146,5 @@ void MainConfig::GenerateDirectoryFilter() { dir_cfg->exceptions.emplace_back(i.second.get_value()); for ( auto &i : ignore_json ) dir_cfg->ignored.emplace_back(i.second.get_value()); - DEBUG("Directory filter fetched"); + JDEBUG("Directory filter fetched"); } diff --git a/src/dialogs.cc b/src/dialogs.cc new file mode 100644 index 0000000..8ff3882 --- /dev/null +++ b/src/dialogs.cc @@ -0,0 +1,50 @@ +#include "dialogs.h" +#include "singletons.h" +#include +#include + +std::string open_dialog(const std::string &title, + const std::vector> buttons, + Gtk::FileChooserAction gtk_options) { + Gtk::FileChooserDialog dialog(title, gtk_options); + if(Singleton::directories()->current_path!="") + gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), Singleton::directories()->current_path.string().c_str()); + else + gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), boost::filesystem::current_path().string().c_str()); + dialog.set_position(Gtk::WindowPosition::WIN_POS_CENTER_ALWAYS); + // dialog.set_transient_for(parent); TODO add parent + for (auto &button : buttons) + dialog.add_button(button.first, button.second); + return dialog.run() == Gtk::RESPONSE_OK ? dialog.get_filename() : ""; +} + + +std::string Dialog::select_folder() { + return open_dialog("Please choose a folder", + {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL),std::make_pair("Open", Gtk::RESPONSE_OK)}, + Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER); +} + +std::string Dialog::new_file() { + return open_dialog("Please create a new file", + {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL), std::make_pair("Save", Gtk::RESPONSE_OK)}, + Gtk::FILE_CHOOSER_ACTION_SAVE); +} + +std::string Dialog::new_folder() { + return open_dialog("Please create a new folder", + {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL),std::make_pair("Create", Gtk::RESPONSE_OK)}, + Gtk::FILE_CHOOSER_ACTION_CREATE_FOLDER); +} + +std::string Dialog::select_file() { + return open_dialog("Please choose a folder", + {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL),std::make_pair("Select", Gtk::RESPONSE_OK)}, + Gtk::FILE_CHOOSER_ACTION_OPEN); +} + +std::string Dialog::save_file() { + return open_dialog("Please choose a file", + {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL),std::make_pair("Save", Gtk::RESPONSE_OK)}, + Gtk::FILE_CHOOSER_ACTION_OPEN); +} \ No newline at end of file diff --git a/src/dialogs.h b/src/dialogs.h new file mode 100644 index 0000000..5acf6ea --- /dev/null +++ b/src/dialogs.h @@ -0,0 +1,14 @@ +#ifndef JUCI_DIALOG_H_ +#define JUCI_DIALOG_H_ +#include + +class Dialog { + public: + static std::string select_folder(); + static std::string select_file(); + static std::string new_file(); + static std::string new_folder(); + static std::string save_file(); +}; // namespace Dialog + +#endif // JUCI_DIALOG_H_ \ No newline at end of file diff --git a/src/dialogs_win.cc b/src/dialogs_win.cc new file mode 100644 index 0000000..24133b1 --- /dev/null +++ b/src/dialogs_win.cc @@ -0,0 +1,22 @@ +#include "dialogs.h" +#include + +std::string Dialog::select_folder() { + return c_select_folder(); +} + +std::string Dialog::new_file() { + return c_new_file(); +} + +std::string Dialog::new_folder() { + return c_new_folder(); +} + +std::string Dialog::select_file() { + return c_select_file(); +} + +std::string Dialog::save_file() { + return c_save_file(); +} \ No newline at end of file diff --git a/src/directories.cc b/src/directories.cc index cbda763..0a269cc 100644 --- a/src/directories.cc +++ b/src/directories.cc @@ -23,7 +23,7 @@ namespace sigc { } Directories::Directories() : stop_update_thread(false) { - DEBUG("start"); + JDEBUG("start"); add(tree_view); set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); tree_store = Gtk::TreeStore::create(column_record); @@ -120,7 +120,7 @@ Directories::~Directories() { } void Directories::open(const boost::filesystem::path& dir_path) { - DEBUG("start"); + JDEBUG("start"); if(dir_path=="") return; @@ -142,21 +142,21 @@ void Directories::open(const boost::filesystem::path& dir_path) { current_path=dir_path; - DEBUG("end"); + JDEBUG("end"); } void Directories::update() { - DEBUG("start"); + JDEBUG("start"); update_mutex.lock(); for(auto &last_write_time: last_write_times) { add_path(last_write_time.first, last_write_time.second.first); } update_mutex.unlock(); - DEBUG("end"); + JDEBUG("end"); } void Directories::select(const boost::filesystem::path &path) { - DEBUG("start"); + JDEBUG("start"); if(current_path=="") return; @@ -196,7 +196,7 @@ void Directories::select(const boost::filesystem::path &path) { } return false; }); - DEBUG("end"); + JDEBUG("end"); } bool Directories::ignored(std::string path) { diff --git a/src/juci.cc b/src/juci.cc index b4c6b67..a7d5cb7 100644 --- a/src/juci.cc +++ b/src/juci.cc @@ -8,7 +8,7 @@ void init_logging() { boost::log::add_common_attributes(); boost::log::add_file_log(boost::log::keywords::file_name = Singleton::log_dir() + "juci.log", boost::log::keywords::auto_flush = true); - INFO("Logging initalized"); + JINFO("Logging initalized"); } int app::on_command_line(const Glib::RefPtr &cmd) { @@ -44,7 +44,7 @@ void app::on_activate() { bool first_directory=true; for(auto &directory: directories) { if(first_directory) { - window->directories.open(directory); + Singleton::directories()->open(directory); first_directory=false; } else { diff --git a/src/logging.h b/src/logging.h index fbd9f89..7fd780b 100644 --- a/src/logging.h +++ b/src/logging.h @@ -15,12 +15,12 @@ #define INFO_VAR(x) BOOST_LOG_TRIVIAL(info) << "** Info: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): " << #x << "=<" << x << ">"; #define WARNING_VAR(x) BOOST_LOG_TRIVIAL(warning) << "** Warning: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): " << #x << "=<" << x << ">"; #define FATAL_VAR(x) BOOST_LOG_TRIVIAL(fatal) << "** Fatal: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): " << #x << "=<" << x << ">"; -#define ERROR_VAR(x) BOOST_LOG_TRIVIAL(error) << "** Error: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): " << #x << "=<" << x << ">"; -#define TRACE(x) BOOST_LOG_TRIVIAL(trace) << "** Trace: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): \"" << x << "\""; -#define DEBUG(x) BOOST_LOG_TRIVIAL(debug) << "** Debug: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): \"" << x << "\""; -#define INFO(x) BOOST_LOG_TRIVIAL(info) << "** Info: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): \"" << x << "\""; -#define WARNING(x) BOOST_LOG_TRIVIAL(warning) << "** Warning: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): \"" << x << "\""; -#define FATAL(x) BOOST_LOG_TRIVIAL(fatal) << "** Fatal: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): \"" << x << "\""; -#define ERROR(x) BOOST_LOG_TRIVIAL(error) << "** Error: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): \"" << x << "\""; +#define JERROR_VAR(x) BOOST_LOG_TRIVIAL(error) << "** Error: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): " << #x << "=<" << x << ">"; +#define JTRACE(x) BOOST_LOG_TRIVIAL(trace) << "** Trace: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): \"" << x << "\""; +#define JDEBUG(x) BOOST_LOG_TRIVIAL(debug) << "** Debug: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): \"" << x << "\""; +#define JINFO(x) BOOST_LOG_TRIVIAL(info) << "** Info: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): \"" << x << "\""; +#define JWARNING(x) BOOST_LOG_TRIVIAL(warning) << "** Warning: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): \"" << x << "\""; +#define JFATAL(x) BOOST_LOG_TRIVIAL(fatal) << "** Fatal: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): \"" << x << "\""; +#define JERROR(x) BOOST_LOG_TRIVIAL(error) << "** Error: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): \"" << x << "\""; #endif // JUCI_LOGGING_H_ diff --git a/src/notebook.cc b/src/notebook.cc index 5b09708..ecfc771 100644 --- a/src/notebook.cc +++ b/src/notebook.cc @@ -52,7 +52,7 @@ Source::View* Notebook::get_current_view() { } void Notebook::open(const boost::filesystem::path &file_path) { - DEBUG("start"); + JDEBUG("start"); for(int c=0;cfile_path) { set_current_page(c); @@ -138,7 +138,7 @@ void Notebook::open(const boost::filesystem::path &file_path) { set_tab_label_text(*(get_nth_page(page)), title); }); - DEBUG("end"); + JDEBUG("end"); } void Notebook::configure(int view_nr) { @@ -154,9 +154,9 @@ void Notebook::configure(int view_nr) { } bool Notebook::save(int page, bool reparse_needed) { - DEBUG("start"); + JDEBUG("start"); if(page>=size()) { - DEBUG("end false"); + JDEBUG("end false"); return false; } auto view=get_view(page); @@ -192,12 +192,12 @@ bool Notebook::save(int page, bool reparse_needed) { } } } - DEBUG("end true"); + JDEBUG("end true"); return true; } Singleton::terminal()->print("Error: could not save file " +view->file_path.string()+"\n"); } - DEBUG("end false"); + JDEBUG("end false"); return false; } @@ -208,11 +208,11 @@ bool Notebook::save_current() { } bool Notebook::close_current_page() { - DEBUG("start"); + JDEBUG("start"); if (get_current_page()!=-1) { if(get_current_view()->get_buffer()->get_modified()){ if(!save_modified_dialog()) { - DEBUG("end false"); + JDEBUG("end false"); return false; } } @@ -231,7 +231,7 @@ bool Notebook::close_current_page() { scrolled_windows.erase(scrolled_windows.begin()+index); hboxes.erase(hboxes.begin()+index); } - DEBUG("end true"); + JDEBUG("end true"); return true; } diff --git a/src/singletons.cc b/src/singletons.cc index 4633763..9040d55 100644 --- a/src/singletons.cc +++ b/src/singletons.cc @@ -5,12 +5,19 @@ std::unique_ptr Singleton::Config::directories_=std::unique std::unique_ptr Singleton::Config::terminal_=std::unique_ptr(new Terminal::Config()); std::unique_ptr Singleton::Config::window_ = std::unique_ptr(new Window::Config()); std::unique_ptr Singleton::terminal_=std::unique_ptr(); +std::unique_ptr Singleton::directories_=std::unique_ptr(); Terminal *Singleton::terminal() { if(!terminal_) terminal_=std::unique_ptr(new Terminal()); return terminal_.get(); } + +Directories *Singleton::directories() { + if(!directories_) + directories_=std::unique_ptr(new Directories()); + return directories_.get(); +} std::unique_ptr Singleton::status_=std::unique_ptr(); Gtk::Label *Singleton::status() { if(!status_) diff --git a/src/singletons.h b/src/singletons.h index 8fa6a86..ed0d82d 100644 --- a/src/singletons.h +++ b/src/singletons.h @@ -11,6 +11,12 @@ #include #include +#ifdef _WIN32 +#define HOME "AppData" +#else +#define HOME "HOME" +#endif + class Singleton { public: class Config { @@ -26,16 +32,18 @@ public: static std::unique_ptr directories_; static std::unique_ptr terminal_; }; - static std::string config_dir() { return std::string(getenv("HOME")) + "/.juci/config/"; } - static std::string log_dir() { return std::string(getenv("HOME")) + "/.juci/log/"; } - static std::string style_dir() { return std::string(getenv("HOME")) + "/.juci/styles/"; } + static std::string config_dir() { return std::string(getenv(HOME)) + "/.juci/config/"; } + static std::string log_dir() { return std::string(getenv(HOME)) + "/.juci/log/"; } + static std::string style_dir() { return std::string(getenv(HOME)) + "/.juci/styles/"; } static Terminal *terminal(); + static Directories *directories(); static Gtk::Label *status(); static Gtk::Label *info(); private: static std::unique_ptr terminal_; static std::unique_ptr status_; static std::unique_ptr info_; + static std::unique_ptr directories_; }; #endif // JUCI_SINGLETONS_H_ diff --git a/src/source.cc b/src/source.cc index 76e4a41..c5006be 100644 --- a/src/source.cc +++ b/src/source.cc @@ -1238,14 +1238,13 @@ clang::Index Source::ClangViewParse::clang_index(0, 0); Source::ClangViewParse::ClangViewParse(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path, Glib::RefPtr language): Source::View(file_path, language), project_path(project_path), parse_error(false) { - DEBUG("start"); - auto tag_table=get_buffer()->get_tag_table(); for (auto &item : Singleton::Config::source()->clang_types) { if(!tag_table->lookup(item.second)) { get_buffer()->create_tag(item.second); } } + configure(); parsing_in_progress=Singleton::terminal()->print_in_progress("Parsing "+file_path.string()); @@ -1287,8 +1286,6 @@ Source::View(file_path, language), project_path(project_path), parse_error(false type_tooltips.hide(); diagnostic_tooltips.hide(); }); - - DEBUG("end"); } void Source::ClangViewParse::configure() { @@ -1312,7 +1309,7 @@ void Source::ClangViewParse::configure() { // // if (style->property_line_background_set()) tag->property_line_background() = style->property_line_background(); // // if (style->property_underline_set()) tag->property_underline() = style->property_underline(); } else - INFO("Style " + item.second + " not found in " + scheme->get_name()); + JINFO("Style " + item.second + " not found in " + scheme->get_name()); } } diff --git a/src/terminal.cc b/src/terminal.cc index 4a3ecc6..8d3caad 100644 --- a/src/terminal.cc +++ b/src/terminal.cc @@ -145,7 +145,7 @@ Terminal::Terminal() { } int Terminal::execute(const std::string &command, const boost::filesystem::path &path) { - DEBUG("start"); + JDEBUG("start"); int stdin_fd, stdout_fd, stderr_fd; auto pid=popen3(command, path.string(), &stdin_fd, &stdout_fd, &stderr_fd); @@ -183,14 +183,14 @@ int Terminal::execute(const std::string &command, const boost::filesystem::path close(stdout_fd); close(stderr_fd); - DEBUG("end"); + JDEBUG("end"); return exit_code; } } void Terminal::async_execute(const std::string &command, const boost::filesystem::path &path, std::function callback) { std::thread async_execute_thread([this, command, path, callback](){ - DEBUG("start"); + JDEBUG("start"); int stdin_fd, stdout_fd, stderr_fd; async_executes_mutex.lock(); stdin_buffer.clear(); @@ -245,7 +245,7 @@ void Terminal::async_execute(const std::string &command, const boost::filesystem if(callback) callback(exit_code); - DEBUG("end"); + JDEBUG("end"); } }); async_execute_thread.detach(); diff --git a/src/window.cc b/src/window.cc index 8d2ca5c..485c1bd 100644 --- a/src/window.cc +++ b/src/window.cc @@ -4,6 +4,7 @@ #include "sourcefile.h" #include "config.h" //#include "api.h" +#include "dialogs.h" #include //TODO: remove using namespace std; //TODO: remove @@ -29,8 +30,8 @@ void Window::generate_keybindings() { } } -Window::Window() : box(Gtk::ORIENTATION_VERTICAL), notebook(directories), compiling(false) { - DEBUG("start"); +Window::Window() : box(Gtk::ORIENTATION_VERTICAL), notebook(*Singleton::directories()), compiling(false) { + JDEBUG("start"); set_title("juCi++"); set_events(Gdk::POINTER_MOTION_MASK|Gdk::FOCUS_CHANGE_MASK|Gdk::SCROLL_MASK); configure(); @@ -39,7 +40,7 @@ Window::Window() : box(Gtk::ORIENTATION_VERTICAL), notebook(directories), compil //PluginApi(&this->notebook, &this->menu); add(box); - + //TODO: Do not use deprecated ui_manager? And make menu shortcuts update when config.json is saved (in configure()) generate_keybindings(); create_menu(); @@ -47,7 +48,7 @@ Window::Window() : box(Gtk::ORIENTATION_VERTICAL), notebook(directories), compil add_accel_group(menu.ui_manager->get_accel_group()); box.pack_start(menu.get_widget(), Gtk::PACK_SHRINK); - directory_and_notebook_panes.pack1(directories, Gtk::SHRINK); + directory_and_notebook_panes.pack1(*Singleton::directories(), Gtk::SHRINK); notebook_vbox.pack_start(notebook); notebook_vbox.pack_end(entry_box, Gtk::PACK_SHRINK); directory_and_notebook_panes.pack2(notebook_vbox, Gtk::SHRINK); @@ -66,7 +67,7 @@ Window::Window() : box(Gtk::ORIENTATION_VERTICAL), notebook(directories), compil box.pack_end(vpaned); show_all_children(); - directories.on_row_activated=[this](const std::string &file) { + Singleton::directories()->on_row_activated=[this](const std::string &file) { notebook.open(file); }; @@ -116,7 +117,7 @@ Window::Window() : box(Gtk::ORIENTATION_VERTICAL), notebook(directories), compil if(auto menu_item=dynamic_cast(menu.ui_manager->get_widget("/MenuBar/SourceMenu/SourceGotoNextDiagnostic"))) menu_item->set_sensitive((bool)notebook.get_current_view()->goto_next_diagnostic); - directories.select(notebook.get_current_view()->file_path); + Singleton::directories()->select(notebook.get_current_view()->file_path); if(auto source_view=dynamic_cast(notebook.get_current_view())) { if(source_view->reparse_needed) { @@ -148,7 +149,7 @@ Window::Window() : box(Gtk::ORIENTATION_VERTICAL), notebook(directories), compil about.set_comments("This is an open source IDE with high-end features to make your programming experience juicy"); about.set_license_type(Gtk::License::LICENSE_MIT_X11); about.set_transient_for(*this); - DEBUG("end"); + JDEBUG("end"); } // Window constructor void Window::configure() { @@ -165,23 +166,94 @@ void Window::create_menu() { hide(); }); menu.action_group->add(Gtk::Action::create("FileNewFile", "New File"), Gtk::AccelKey(menu.key_map["new_file"]), [this]() { - new_file_dialog(); + boost::filesystem::path path = Dialog::new_file(); + if(path!="") { + if(boost::filesystem::exists(path)) { + Singleton::terminal()->print("Error: "+path.string()+" already exists.\n"); + } + else { + if(juci::filesystem::write(path)) { + if(Singleton::directories()->current_path!="") + Singleton::directories()->update(); + notebook.open(path.string()); + Singleton::terminal()->print("New file "+path.string()+" created.\n"); + } + else + Singleton::terminal()->print("Error: could not create new file "+path.string()+".\n"); + } + } }); menu.action_group->add(Gtk::Action::create("FileNewFolder", "New Folder"), Gtk::AccelKey(menu.key_map["new_folder"]), [this]() { - new_folder_dialog(); + auto time_now=std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); + boost::filesystem::path path = Dialog::new_folder(); + if(boost::filesystem::exists(path)) { + if(boost::filesystem::last_write_time(path)>=time_now) { + if(Singleton::directories()->current_path!="") + Singleton::directories()->update(); + Singleton::terminal()->print("New folder "+path.string()+" created.\n"); + } + else + Singleton::terminal()->print("Error: "+path.string()+" already exists.\n"); + } else { + Singleton::terminal()->print("Cancel \n"); + } + Singleton::directories()->select(path); }); menu.action_group->add(Gtk::Action::create("FileNewProject", "New Project")); menu.action_group->add(Gtk::Action::create("FileNewProjectCpp", "C++"), [this]() { - new_cpp_project_dialog(); + boost::filesystem::path project_path = Dialog::new_folder(); + auto project_name=project_path.filename().string(); + for(size_t c=0;cprint("Error: "+cmakelists_path.string()+" already exists.\n"); + return; + } + if(boost::filesystem::exists(cpp_main_path)) { + Singleton::terminal()->print("Error: "+cpp_main_path.string()+" already exists.\n"); + return; + } + std::string cmakelists="cmake_minimum_required(VERSION 2.8)\n\nproject("+project_name+")\n\nset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -std=c++1y -Wall\")\n\nadd_executable("+project_name+" main.cpp)\n"; + std::string cpp_main="#include \n\nusing namespace std;\n\nint main() {\n cout << \"Hello World!\" << endl;\n\n return 0;\n}\n"; + if(juci::filesystem::write(cmakelists_path, cmakelists) && juci::filesystem::write(cpp_main_path, cpp_main)) { + Singleton::directories()->open(project_path); + notebook.open(cpp_main_path); + Singleton::terminal()->print("C++ project "+project_name+" created.\n"); + } + else + Singleton::terminal()->print("Error: Could not create project "+project_path.string()+"\n"); }); menu.action_group->add(Gtk::Action::create("FileOpenFile", "Open File"), Gtk::AccelKey(menu.key_map["open_file"]), [this]() { - open_file_dialog(); + notebook.open(Dialog::select_file()); }); menu.action_group->add(Gtk::Action::create("FileOpenFolder", "Open Folder"), Gtk::AccelKey(menu.key_map["open_folder"]), [this]() { - open_folder_dialog(); + auto path = Dialog::select_folder(); + if (boost::filesystem::exists(path)) + Singleton::directories()->open(path); + else + Singleton::terminal()->print("Cancel \n"); }); menu.action_group->add(Gtk::Action::create("FileSaveAs", "Save As"), Gtk::AccelKey(menu.key_map["save_as"]), [this]() { - save_file_dialog(); + auto path = Dialog::save_file(); + if(path.size()>0) { + std::ofstream file(path); + if(file) { + file << notebook.get_current_view()->get_buffer()->get_text(); + file.close(); + if(Singleton::directories()->current_path!="") + Singleton::directories()->update(); + notebook.open(path); + Singleton::terminal()->print("File saved to: " + notebook.get_current_view()->file_path.string()+"\n"); + } + else + Singleton::terminal()->print("Error saving file\n"); + } }); menu.action_group->add(Gtk::Action::create("Preferences", "Preferences..."), Gtk::AccelKey(menu.key_map["preferences"]), [this]() { notebook.open(Singleton::config_dir()+"config.json"); @@ -359,8 +431,8 @@ void Window::create_menu() { if(content!="") { last_run_command=content; Singleton::terminal()->async_print("Running: "+content+'\n'); - Singleton::terminal()->async_execute(content, directories.current_path, [this, content](int exit_code){ - Singleton::terminal()->async_print(content+" returned: "+std::to_string(exit_code)+'\n'); + Singleton::terminal()->async_execute(content, Singleton::directories()->current_path, [this, content](int exit_code) { + Singleton::terminal()->async_print(content + " returned: " + std::to_string(exit_code)+'\n'); }); } entry_box.hide(); @@ -457,178 +529,6 @@ void Window::hide() { Gtk::Window::hide(); } -void Window::new_file_dialog() { - Gtk::FileChooserDialog dialog("Please create a new file", Gtk::FILE_CHOOSER_ACTION_SAVE); - if(directories.current_path!="") - gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), directories.current_path.string().c_str()); - else - gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), boost::filesystem::current_path().string().c_str()); - dialog.set_transient_for(*this); - dialog.set_position(Gtk::WindowPosition::WIN_POS_CENTER_ALWAYS); - dialog.add_button("Cancel", Gtk::RESPONSE_CANCEL); - dialog.add_button("Save", Gtk::RESPONSE_OK); - - int result = dialog.run(); - if(result==Gtk::RESPONSE_OK) { - boost::filesystem::path path = dialog.get_filename(); - if(path!="") { - if(boost::filesystem::exists(path)) { - Singleton::terminal()->print("Error: "+path.string()+" already exists.\n"); - } - else { - if(juci::filesystem::write(path)) { - if(directories.current_path!="") - directories.update(); - notebook.open(path.string()); - Singleton::terminal()->print("New file "+path.string()+" created.\n"); - } - else - Singleton::terminal()->print("Error: could not create new file "+path.string()+".\n"); - } - } - } -} - -void Window::new_folder_dialog() { - auto time_now=std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); - Gtk::FileChooserDialog dialog("Please create a new folder", Gtk::FILE_CHOOSER_ACTION_CREATE_FOLDER); - if(directories.current_path!="") - gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), directories.current_path.string().c_str()); - else - gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), boost::filesystem::current_path().string().c_str()); - dialog.set_transient_for(*this); - dialog.set_position(Gtk::WindowPosition::WIN_POS_CENTER_ALWAYS); - dialog.add_button("Cancel", Gtk::RESPONSE_CANCEL); - dialog.add_button("Create", Gtk::RESPONSE_OK); - - int result = dialog.run(); - if(result==Gtk::RESPONSE_OK) { - boost::filesystem::path path=dialog.get_filename(); - if(boost::filesystem::last_write_time(path)>=time_now) { - if(directories.current_path!="") - directories.update(); - Singleton::terminal()->print("New folder "+path.string()+" created.\n"); - } - else - Singleton::terminal()->print("Error: "+path.string()+" already exists.\n"); - directories.select(path); - } -} - -void Window::new_cpp_project_dialog() { - Gtk::FileChooserDialog dialog("Please create and/or choose a folder", Gtk::FILE_CHOOSER_ACTION_CREATE_FOLDER); - if(directories.current_path!="") - gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), directories.current_path.string().c_str()); - else - gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), boost::filesystem::current_path().string().c_str()); - dialog.set_transient_for(*this); - dialog.set_position(Gtk::WindowPosition::WIN_POS_CENTER_ALWAYS); - dialog.add_button("Cancel", Gtk::RESPONSE_CANCEL); - dialog.add_button("Create", Gtk::RESPONSE_OK); - - int result = dialog.run(); - if(result==Gtk::RESPONSE_OK) { - boost::filesystem::path project_path=dialog.get_filename(); - auto project_name=project_path.filename().string(); - for(size_t c=0;cprint("Error: "+cmakelists_path.string()+" already exists.\n"); - return; - } - if(boost::filesystem::exists(cpp_main_path)) { - Singleton::terminal()->print("Error: "+cpp_main_path.string()+" already exists.\n"); - return; - } - auto tab_char=Singleton::Config::source()->default_tab_char; - auto tab_size=Singleton::Config::source()->default_tab_size; - std::string tab; - for(unsigned c=0;cprint("C++ project "+project_name+" created.\n"); - } - else - Singleton::terminal()->print("Error: Could not create project "+project_path.string()+"\n"); - } -} - -void Window::open_folder_dialog() { - Gtk::FileChooserDialog dialog("Please choose a folder", Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER); - if(directories.current_path!="") - gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), directories.current_path.string().c_str()); - else - gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), boost::filesystem::current_path().string().c_str()); - dialog.set_transient_for(*this); - dialog.set_position(Gtk::WindowPosition::WIN_POS_CENTER_ALWAYS); - dialog.add_button("Cancel", Gtk::RESPONSE_CANCEL); - dialog.add_button("Open", Gtk::RESPONSE_OK); - - int result = dialog.run(); - - if(result==Gtk::RESPONSE_OK) { - std::string project_path=dialog.get_filename(); - directories.open(project_path); - } -} - -void Window::open_file_dialog() { - Gtk::FileChooserDialog dialog("Please choose a file", Gtk::FILE_CHOOSER_ACTION_OPEN); - if(directories.current_path!="") - gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), directories.current_path.string().c_str()); - else - gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), boost::filesystem::current_path().string().c_str()); - dialog.set_transient_for(*this); - dialog.set_position(Gtk::WindowPosition::WIN_POS_CENTER_ALWAYS); - dialog.add_button("Cancel", Gtk::RESPONSE_CANCEL); - dialog.add_button("Open", Gtk::RESPONSE_OK); - - int result = dialog.run(); - - if(result==Gtk::RESPONSE_OK) { - std::string path = dialog.get_filename(); - notebook.open(path); - } -} - -void Window::save_file_dialog() { - if(notebook.get_current_page()==-1) - return; - Gtk::FileChooserDialog dialog(*this, "Please choose a file", Gtk::FILE_CHOOSER_ACTION_SAVE); - gtk_file_chooser_set_filename((GtkFileChooser*)dialog.gobj(), notebook.get_current_view()->file_path.string().c_str()); - dialog.set_position(Gtk::WindowPosition::WIN_POS_CENTER_ALWAYS); - dialog.add_button("Cancel", Gtk::RESPONSE_CANCEL); - dialog.add_button("Save", Gtk::RESPONSE_OK); - - int result = dialog.run(); - if(result==Gtk::RESPONSE_OK) { - auto path = dialog.get_filename(); - if(path.size()>0) { - std::ofstream file(path); - if(file) { - file << notebook.get_current_view()->get_buffer()->get_text(); - file.close(); - if(directories.current_path!="") - directories.update(); - notebook.open(path); - Singleton::terminal()->print("File saved to: " + notebook.get_current_view()->file_path.string()+"\n"); - } - else - Singleton::terminal()->print("Error saving file\n"); - } - } -} - void Window::search_and_replace_entry() { entry_box.clear(); entry_box.labels.emplace_back(); diff --git a/src/window.h b/src/window.h index 095e949..a0c13ea 100644 --- a/src/window.h +++ b/src/window.h @@ -12,7 +12,6 @@ class Window : public Gtk::Window { public: Window(); - Directories directories; Notebook notebook; class Config { public: @@ -43,12 +42,6 @@ private: void configure(); void create_menu(); void hide(); - void new_file_dialog(); - void new_folder_dialog(); - void new_cpp_project_dialog(); - void open_folder_dialog(); - void open_file_dialog(); - void save_file_dialog(); void search_and_replace_entry(); void goto_line_entry(); void rename_token_entry();