Browse Source

More project cleanup, getting there, soon done

merge-requests/365/head
eidheim 10 years ago
parent
commit
e9cc73471d
  1. 3
      src/dialogs.cc
  2. 3
      src/juci.cc
  3. 9
      src/notebook.h
  4. 230
      src/project.cc
  5. 179
      src/project.h
  6. 199
      src/window.cc
  7. 19
      src/window.h

3
src/dialogs.cc

@ -1,5 +1,6 @@
#include "dialogs.h"
#include "window.h"
#include "notebook.h"
#include <cmath>
namespace sigc {
@ -34,7 +35,7 @@ std::string Dialog::gtk_dialog(const std::string &title,
dialog.set_transient_for(Window::get());
auto current_path=Window::get().notebook.get_current_folder();
auto current_path=Notebook::get().get_current_folder();
boost::system::error_code ec;
if(current_path.empty())
current_path=boost::filesystem::current_path(ec);

3
src/juci.cc

@ -1,5 +1,6 @@
#include "juci.h"
#include "window.h"
#include "notebook.h"
#include "directories.h"
#include "menu.h"
#include "config.h"
@ -68,7 +69,7 @@ void Application::on_activate() {
}
for(auto &file: files)
Window::get().notebook.open(file);
Notebook::get().open(file);
for(auto &error: errors)
Terminal::get().print(error, true);

9
src/notebook.h

@ -16,8 +16,15 @@ class Notebook : public Gtk::Notebook {
Gtk::Label label;
Gtk::Button button;
};
public:
private:
Notebook();
public:
static Notebook &get() {
static Notebook singleton;
return singleton;
}
Source::View* get_view(int page);
size_t get_index(int page);
int size();

230
src/project.cc

@ -3,16 +3,98 @@
#include "terminal.h"
#include "filesystem.h"
#include <fstream>
#include "menu.h"
#ifdef JUCI_ENABLE_DEBUG
#include "debug.h"
#endif
std::unordered_map<std::string, std::string> Project::run_arguments;
std::unordered_map<std::string, std::string> Project::debug_run_arguments;
std::atomic<bool> Project::compiling(false);
std::atomic<bool> Project::debugging(false);
Project::Project() : notebook(Notebook::get()), compiling(false), debugging(false) {
debug_update_stop.connect([this](){
debug_stop_mutex.lock();
for(int c=0;c<notebook.size();c++) {
auto view=notebook.get_view(c);
if(view->file_path==debug_last_stop_file_path) {
view->get_source_buffer()->remove_source_marks(view->get_buffer()->begin(), view->get_buffer()->end(), "debug_stop");
break;
}
}
//Add debug stop source mark
for(int c=0;c<notebook.size();c++) {
auto view=notebook.get_view(c);
if(view->file_path==debug_stop.first) {
if(debug_stop.second.first-1<view->get_buffer()->get_line_count()) {
view->get_source_buffer()->create_source_mark("debug_stop", view->get_buffer()->get_iter_at_line(debug_stop.second.first-1));
debug_last_stop_file_path=debug_stop.first;
}
break;
}
}
if(notebook.get_current_page()!=-1)
notebook.get_current_view()->get_buffer()->place_cursor(notebook.get_current_view()->get_buffer()->get_insert()->get_iter());
debug_stop_mutex.unlock();
});
#ifdef JUCI_ENABLE_DEBUG
auto &menu=Menu::get();
menu.actions["debug_stop"]->set_enabled(false);
menu.actions["debug_kill"]->set_enabled(false);
menu.actions["debug_step_over"]->set_enabled(false);
menu.actions["debug_step_into"]->set_enabled(false);
menu.actions["debug_step_out"]->set_enabled(false);
menu.actions["debug_backtrace"]->set_enabled(false);
menu.actions["debug_show_variables"]->set_enabled(false);
menu.actions["debug_run_command"]->set_enabled(false);
menu.actions["debug_goto_stop"]->set_enabled(false);
#endif
debug_update_status.connect([this](){
debug_status_mutex.lock();
if(debug_status.empty()) {
debug_status_label.set_text("");
auto &menu=Menu::get();
menu.actions["debug_stop"]->set_enabled(false);
menu.actions["debug_kill"]->set_enabled(false);
menu.actions["debug_step_over"]->set_enabled(false);
menu.actions["debug_step_into"]->set_enabled(false);
menu.actions["debug_step_out"]->set_enabled(false);
menu.actions["debug_backtrace"]->set_enabled(false);
menu.actions["debug_show_variables"]->set_enabled(false);
menu.actions["debug_run_command"]->set_enabled(false);
menu.actions["debug_goto_stop"]->set_enabled(false);
}
else {
debug_status_label.set_text("debug: "+debug_status);
auto &menu=Menu::get();
menu.actions["debug_stop"]->set_enabled();
menu.actions["debug_kill"]->set_enabled();
menu.actions["debug_step_over"]->set_enabled();
menu.actions["debug_step_into"]->set_enabled();
menu.actions["debug_step_out"]->set_enabled();
menu.actions["debug_backtrace"]->set_enabled();
menu.actions["debug_show_variables"]->set_enabled();
menu.actions["debug_run_command"]->set_enabled();
menu.actions["debug_goto_stop"]->set_enabled();
}
debug_status_mutex.unlock();
});
}
std::unique_ptr<CMake> ProjectClang::get_cmake() {
std::unique_ptr<Project::Language> Project::get_language() {
if(notebook.get_current_page()!=-1) {
auto language_id=notebook.get_current_view()->language->get_id();
if(language_id=="markdown")
return std::unique_ptr<Project::Language>(new Project::Markdown());
if(language_id=="python")
return std::unique_ptr<Project::Language>(new Project::Python());
if(language_id=="js")
return std::unique_ptr<Project::Language>(new Project::JavaScript());
if(language_id=="html")
return std::unique_ptr<Project::Language>(new Project::HTML());
}
return std::unique_ptr<Project::Language>(new Project::Clang());
}
std::unique_ptr<CMake> Project::Clang::get_cmake() {
boost::filesystem::path path;
if(notebook.get_current_page()!=-1)
path=notebook.get_current_view()->file_path.parent_path();
@ -28,15 +110,15 @@ std::unique_ptr<CMake> ProjectClang::get_cmake() {
return cmake;
}
std::pair<std::string, std::string> ProjectClang::get_run_arguments() {
std::pair<std::string, std::string> Project::Clang::get_run_arguments() {
auto cmake=get_cmake();
if(!cmake)
return {"", ""};
auto project_path=cmake->project_path.string();
auto run_arguments_it=run_arguments.find(project_path);
auto run_arguments_it=Project::get().run_arguments.find(project_path);
std::string arguments;
if(run_arguments_it!=run_arguments.end())
if(run_arguments_it!=Project::get().run_arguments.end())
arguments=run_arguments_it->second;
if(arguments.empty()) {
@ -59,7 +141,7 @@ std::pair<std::string, std::string> ProjectClang::get_run_arguments() {
return {project_path, arguments};
}
void ProjectClang::compile() {
void Project::Clang::compile() {
auto cmake=get_cmake();
if(!cmake)
return;
@ -67,14 +149,14 @@ void ProjectClang::compile() {
auto default_build_path=CMake::get_default_build_path(cmake->project_path);
if(default_build_path.empty())
return;
compiling=true;
Project::get().compiling=true;
Terminal::get().print("Compiling project "+cmake->project_path.string()+"\n");
Terminal::get().async_process(Config::get().terminal.make_command, default_build_path, [this](int exit_status) {
compiling=false;
Project::get().compiling=false;
});
}
void ProjectClang::compile_and_run() {
void Project::Clang::compile_and_run() {
auto cmake=get_cmake();
if(!cmake)
return;
@ -84,9 +166,9 @@ void ProjectClang::compile_and_run() {
if(default_build_path.empty())
return;
auto run_arguments_it=run_arguments.find(project_path.string());
auto run_arguments_it=Project::get().run_arguments.find(project_path.string());
std::string arguments;
if(run_arguments_it!=run_arguments.end())
if(run_arguments_it!=Project::get().run_arguments.end())
arguments=run_arguments_it->second;
if(arguments.empty()) {
@ -104,10 +186,10 @@ void ProjectClang::compile_and_run() {
arguments=filesystem::escape_argument(arguments);
}
compiling=true;
Project::get().compiling=true;
Terminal::get().print("Compiling and running "+arguments+"\n");
Terminal::get().async_process(Config::get().terminal.make_command, default_build_path, [this, arguments, default_build_path](int exit_status){
compiling=false;
Project::get().compiling=false;
if(exit_status==EXIT_SUCCESS) {
Terminal::get().async_process(arguments, default_build_path, [this, arguments](int exit_status){
Terminal::get().async_print(arguments+" returned: "+std::to_string(exit_status)+'\n');
@ -117,15 +199,15 @@ void ProjectClang::compile_and_run() {
}
#ifdef JUCI_ENABLE_DEBUG
std::pair<std::string, std::string> ProjectClang::debug_get_run_arguments() {
std::pair<std::string, std::string> Project::Clang::debug_get_run_arguments() {
auto cmake=get_cmake();
if(!cmake)
return {"", ""};
auto project_path=cmake->project_path.string();
auto run_arguments_it=debug_run_arguments.find(project_path);
auto run_arguments_it=Project::get().debug_run_arguments.find(project_path);
std::string arguments;
if(run_arguments_it!=debug_run_arguments.end())
if(run_arguments_it!=Project::get().debug_run_arguments.end())
arguments=run_arguments_it->second;
if(arguments.empty()) {
@ -148,8 +230,7 @@ std::pair<std::string, std::string> ProjectClang::debug_get_run_arguments() {
return {project_path, arguments};
}
void ProjectClang::debug_start(std::function<void(const std::string &status)> status_callback,
std::function<void(const boost::filesystem::path &file_path, int line_nr, int line_index)> stop_callback) {
void Project::Clang::debug_start() {
auto cmake=get_cmake();
if(!cmake)
return;
@ -161,9 +242,9 @@ void ProjectClang::debug_start(std::function<void(const std::string &status)> st
if(!CMake::create_debug_build(project_path))
return;
auto run_arguments_it=debug_run_arguments.find(project_path.string());
auto run_arguments_it=Project::get().debug_run_arguments.find(project_path.string());
std::string run_arguments;
if(run_arguments_it!=debug_run_arguments.end())
if(run_arguments_it!=Project::get().debug_run_arguments.end())
run_arguments=run_arguments_it->second;
if(run_arguments.empty()) {
@ -193,53 +274,67 @@ void ProjectClang::debug_start(std::function<void(const std::string &status)> st
}
}
debugging=true;
Project::get().debugging=true;
Terminal::get().print("Compiling and debugging "+run_arguments+"\n");
Terminal::get().async_process(Config::get().terminal.make_command, debug_build_path, [this, breakpoints, run_arguments, debug_build_path, status_callback, stop_callback](int exit_status){
Terminal::get().async_process(Config::get().terminal.make_command, debug_build_path, [this, breakpoints, run_arguments, debug_build_path](int exit_status){
if(exit_status!=EXIT_SUCCESS)
debugging=false;
Project::get().debugging=false;
else {
debug_start_mutex.lock();
Debug::get().start(run_arguments, debug_build_path, *breakpoints, [this, run_arguments](int exit_status){
debugging=false;
Project::get().debugging=false;
Terminal::get().async_print(run_arguments+" returned: "+std::to_string(exit_status)+'\n');
}, status_callback, stop_callback);
}, [this](const std::string &status) {
auto &project=Project::get();
project.debug_status_mutex.lock();
project.debug_status=status;
project.debug_status_mutex.unlock();
project.debug_update_status();
}, [this](const boost::filesystem::path &file_path, int line_nr, int line_index) {
auto &project=Project::get();
project.debug_stop_mutex.lock();
project.debug_stop.first=file_path;
project.debug_stop.second.first=line_nr;
project.debug_stop.second.second=line_index;
project.debug_stop_mutex.unlock();
project.debug_update_stop();
});
debug_start_mutex.unlock();
}
});
}
void ProjectClang::debug_continue() {
void Project::Clang::debug_continue() {
Debug::get().continue_debug();
}
void ProjectClang::debug_stop() {
if(debugging)
void Project::Clang::debug_stop() {
if(Project::get().debugging)
Debug::get().stop();
}
void ProjectClang::debug_kill() {
if(debugging)
void Project::Clang::debug_kill() {
if(Project::get().debugging)
Debug::get().kill();
}
void ProjectClang::debug_step_over() {
if(debugging)
void Project::Clang::debug_step_over() {
if(Project::get().debugging)
Debug::get().step_over();
}
void ProjectClang::debug_step_into() {
if(debugging)
void Project::Clang::debug_step_into() {
if(Project::get().debugging)
Debug::get().step_into();
}
void ProjectClang::debug_step_out() {
if(debugging)
void Project::Clang::debug_step_out() {
if(Project::get().debugging)
Debug::get().step_out();
}
void ProjectClang::debug_backtrace() {
if(debugging && notebook.get_current_page()!=-1) {
void Project::Clang::debug_backtrace() {
if(Project::get().debugging && notebook.get_current_page()!=-1) {
auto backtrace=Debug::get().get_backtrace();
auto view=notebook.get_current_view();
@ -288,8 +383,8 @@ void ProjectClang::debug_backtrace() {
}
}
void ProjectClang::debug_show_variables() {
if(debugging && notebook.get_current_page()!=-1) {
void Project::Clang::debug_show_variables() {
if(Project::get().debugging && notebook.get_current_page()!=-1) {
auto variables=Debug::get().get_variables();
auto view=notebook.get_current_view();
@ -366,29 +461,62 @@ void ProjectClang::debug_show_variables() {
}
}
void ProjectClang::debug_run_command(const std::string &command) {
if(debugging) {
void Project::Clang::debug_run_command(const std::string &command) {
if(Project::get().debugging) {
auto command_return=Debug::get().run_command(command);
Terminal::get().async_print(command_return.first);
Terminal::get().async_print(command_return.second, true);
}
}
void ProjectClang::debug_delete() {
void Project::Clang::debug_goto_stop() {
if(Project::get().debugging) {
auto &project=Project::get();
project.debug_stop_mutex.lock();
auto debug_stop_copy=project.debug_stop;
project.debug_stop_mutex.unlock();
if(!debug_stop_copy.first.empty()) {
notebook.open(debug_stop_copy.first);
if(notebook.get_current_page()!=-1) {
auto view=notebook.get_current_view();
int line_nr=debug_stop_copy.second.first-1;
int line_index=debug_stop_copy.second.second-1;
if(line_nr<view->get_buffer()->get_line_count()) {
auto iter=view->get_buffer()->get_iter_at_line(line_nr);
auto end_line_iter=iter;
while(!iter.ends_line() && iter.forward_char()) {}
auto line=view->get_buffer()->get_text(iter, end_line_iter);
if(static_cast<size_t>(line_index)>=line.bytes())
line_index=0;
view->get_buffer()->place_cursor(view->get_buffer()->get_iter_at_line_index(line_nr, line_index));
while(g_main_context_pending(NULL))
g_main_context_iteration(NULL, false);
if(notebook.get_current_page()!=-1 && notebook.get_current_view()==view)
view->scroll_to(view->get_buffer()->get_insert(), 0.0, 1.0, 0.5);
}
project.debug_update_stop();
}
}
}
}
void Project::Clang::debug_delete() {
debug_start_mutex.lock();
Debug::get().delete_debug();
debug_start_mutex.unlock();
}
#endif
ProjectMarkdown::~ProjectMarkdown() {
Project::Markdown::~Markdown() {
if(!last_temp_path.empty()) {
boost::filesystem::remove(last_temp_path);
last_temp_path=boost::filesystem::path();
}
}
void ProjectMarkdown::compile_and_run() {
void Project::Markdown::compile_and_run() {
if(!last_temp_path.empty()) {
boost::filesystem::remove(last_temp_path);
last_temp_path=boost::filesystem::path();
@ -424,7 +552,7 @@ void ProjectMarkdown::compile_and_run() {
}
}
void ProjectPython::compile_and_run() {
void Project::Python::compile_and_run() {
auto command="python "+notebook.get_current_view()->file_path.string();
Terminal::get().print("Running "+command+"\n");
Terminal::get().async_process(command, notebook.get_current_view()->file_path.parent_path(), [command](int exit_status) {
@ -432,7 +560,7 @@ void ProjectPython::compile_and_run() {
});
}
void ProjectJavaScript::compile_and_run() {
void Project::JavaScript::compile_and_run() {
auto command="node "+notebook.get_current_view()->file_path.string();
Terminal::get().print("Running "+command+"\n");
Terminal::get().async_process(command, notebook.get_current_view()->file_path.parent_path(), [command](int exit_status) {
@ -440,7 +568,7 @@ void ProjectJavaScript::compile_and_run() {
});
}
void ProjectHTML::compile_and_run() {
void Project::HTML::compile_and_run() {
auto uri=notebook.get_current_view()->file_path.string();
#ifdef __APPLE__
Terminal::get().process("open \""+uri+"\"");

179
src/project.h

@ -1,6 +1,7 @@
#ifndef JUCI_PROJECT_H_
#define JUCI_PROJECT_H_
#include <gtkmm.h>
#include "notebook.h"
#include "cmake.h"
#include <boost/filesystem.hpp>
@ -10,93 +11,115 @@
#include "tooltips.h"
class Project {
public:
Project(Notebook &notebook) : notebook(notebook) {}
virtual ~Project() {}
Notebook &notebook;
static std::unordered_map<std::string, std::string> run_arguments;
static std::unordered_map<std::string, std::string> debug_run_arguments;
static std::atomic<bool> compiling;
static std::atomic<bool> debugging;
virtual std::pair<std::string, std::string> get_run_arguments() {return {"", ""};}
virtual void compile() {}
virtual void compile_and_run() {}
virtual std::pair<std::string, std::string> debug_get_run_arguments() {return {"", ""};}
Tooltips debug_variable_tooltips;
virtual void debug_start(std::function<void(const std::string &status)> status_callback,
std::function<void(const boost::filesystem::path &file_path, int line_nr, int line_index)> stop_callback) {}
virtual void debug_continue() {}
virtual void debug_stop() {}
virtual void debug_kill() {}
virtual void debug_step_over() {}
virtual void debug_step_into() {}
virtual void debug_step_out() {}
virtual void debug_backtrace() {}
virtual void debug_show_variables() {}
virtual void debug_run_command(const std::string &command) {}
virtual void debug_delete() {}
};
private:
std::pair<boost::filesystem::path, std::pair<int, int> > debug_stop;
std::mutex debug_stop_mutex;
boost::filesystem::path debug_last_stop_file_path;
Glib::Dispatcher debug_update_stop;
std::string debug_status;
std::mutex debug_status_mutex;
Glib::Dispatcher debug_update_status;
class ProjectClang : public Project {
Project();
Notebook &notebook; //convenience reference
public:
ProjectClang(Notebook &notebook) : Project(notebook) {}
static Project &get() {
static Project singleton;
return singleton;
}
Gtk::Label debug_status_label;
std::unordered_map<std::string, std::string> run_arguments;
std::unordered_map<std::string, std::string> debug_run_arguments;
std::atomic<bool> compiling;
std::atomic<bool> debugging;
std::unique_ptr<CMake> get_cmake();
class Language {
protected:
Notebook &notebook; //convenience reference
public:
Language() : notebook(Notebook::get()) {}
virtual ~Language() {}
virtual std::pair<std::string, std::string> get_run_arguments() {return {"", ""};}
virtual void compile() {}
virtual void compile_and_run() {}
virtual std::pair<std::string, std::string> debug_get_run_arguments() {return {"", ""};}
Tooltips debug_variable_tooltips;
virtual void debug_start() {}
virtual void debug_continue() {}
virtual void debug_stop() {}
virtual void debug_kill() {}
virtual void debug_step_over() {}
virtual void debug_step_into() {}
virtual void debug_step_out() {}
virtual void debug_backtrace() {}
virtual void debug_show_variables() {}
virtual void debug_run_command(const std::string &command) {}
virtual void debug_goto_stop() {}
virtual void debug_delete() {}
};
std::pair<std::string, std::string> get_run_arguments() override;
void compile() override;
void compile_and_run() override;
class Clang : public Language {
public:
Clang() : Language() {}
std::unique_ptr<CMake> get_cmake();
std::pair<std::string, std::string> get_run_arguments() override;
void compile() override;
void compile_and_run() override;
std::mutex debug_start_mutex;
#ifdef JUCI_ENABLE_DEBUG
std::pair<std::string, std::string> debug_get_run_arguments() override;
void debug_start() override;
void debug_continue() override;
void debug_stop() override;
void debug_kill() override;
void debug_step_over() override;
void debug_step_into() override;
void debug_step_out() override;
void debug_backtrace() override;
void debug_show_variables() override;
void debug_run_command(const std::string &command) override;
void debug_goto_stop() override;
void debug_delete() override;
#endif
};
std::mutex debug_start_mutex;
#ifdef JUCI_ENABLE_DEBUG
std::pair<std::string, std::string> debug_get_run_arguments() override;
void debug_start(std::function<void(const std::string &status)> status_callback,
std::function<void(const boost::filesystem::path &file_path, int line_nr, int line_index)> stop_callback) override;
void debug_continue() override;
void debug_stop() override;
void debug_kill() override;
void debug_step_over() override;
void debug_step_into() override;
void debug_step_out() override;
void debug_backtrace() override;
void debug_show_variables() override;
void debug_run_command(const std::string &command) override;
void debug_delete() override;
#endif
};
class ProjectMarkdown : public Project {
public:
ProjectMarkdown(Notebook &notebook) : Project(notebook) {}
~ProjectMarkdown();
class Markdown : public Language {
public:
Markdown() : Language() {}
~Markdown();
boost::filesystem::path last_temp_path;
void compile_and_run() override;
};
boost::filesystem::path last_temp_path;
void compile_and_run() override;
};
class ProjectPython : public Project {
public:
ProjectPython(Notebook &notebook) : Project(notebook) {}
class Python : public Language {
public:
Python() : Language() {}
void compile_and_run() override;
};
void compile_and_run() override;
};
class ProjectJavaScript : public Project {
public:
ProjectJavaScript(Notebook &notebook) : Project(notebook) {}
class JavaScript : public Language {
public:
JavaScript() : Language() {}
void compile_and_run() override;
};
void compile_and_run() override;
};
class ProjectHTML : public Project {
public:
ProjectHTML(Notebook &notebook) : Project(notebook) {}
class HTML : public Language {
public:
HTML() : Language() {}
void compile_and_run() override;
};
void compile_and_run() override;
std::unique_ptr<Language> get_language();
};
#endif // JUCI_PROJECT_H_

199
src/window.cc

@ -24,7 +24,7 @@ namespace sigc {
#endif
}
Window::Window() {
Window::Window() : notebook(Notebook::get()) {
JDEBUG("start");
set_title("juCi++");
set_events(Gdk::POINTER_MOTION_MASK|Gdk::FOCUS_CHANGE_MASK|Gdk::SCROLL_MASK|Gdk::LEAVE_NOTIFY_MASK);
@ -50,7 +50,7 @@ Window::Window() {
info_and_status_hbox.pack_start(notebook.info, Gtk::PACK_SHRINK);
#if GTK_VERSION_GE(3, 12)
info_and_status_hbox.set_center_widget(debug_status_label);
info_and_status_hbox.set_center_widget(Project::get().debug_status_label);
#else
debug_status_label.set_halign(Gtk::Align::ALIGN_CENTER);
info_and_status_hbox.pack_start(debug_status_label);
@ -121,74 +121,6 @@ Window::Window() {
about.hide();
});
debug_update_stop.connect([this](){
debug_stop_mutex.lock();
for(int c=0;c<notebook.size();c++) {
auto view=notebook.get_view(c);
if(view->file_path==debug_last_stop_file_path) {
view->get_source_buffer()->remove_source_marks(view->get_buffer()->begin(), view->get_buffer()->end(), "debug_stop");
break;
}
}
//Add debug stop source mark
for(int c=0;c<notebook.size();c++) {
auto view=notebook.get_view(c);
if(view->file_path==debug_stop.first) {
if(debug_stop.second.first-1<view->get_buffer()->get_line_count()) {
view->get_source_buffer()->create_source_mark("debug_stop", view->get_buffer()->get_iter_at_line(debug_stop.second.first-1));
debug_last_stop_file_path=debug_stop.first;
}
break;
}
}
if(notebook.get_current_page()!=-1)
notebook.get_current_view()->get_buffer()->place_cursor(notebook.get_current_view()->get_buffer()->get_insert()->get_iter());
debug_stop_mutex.unlock();
});
#ifdef JUCI_ENABLE_DEBUG
auto &menu=Menu::get();
menu.actions["debug_stop"]->set_enabled(false);
menu.actions["debug_kill"]->set_enabled(false);
menu.actions["debug_step_over"]->set_enabled(false);
menu.actions["debug_step_into"]->set_enabled(false);
menu.actions["debug_step_out"]->set_enabled(false);
menu.actions["debug_backtrace"]->set_enabled(false);
menu.actions["debug_show_variables"]->set_enabled(false);
menu.actions["debug_run_command"]->set_enabled(false);
menu.actions["debug_goto_stop"]->set_enabled(false);
#endif
debug_update_status.connect([this](){
debug_status_mutex.lock();
if(debug_status.empty()) {
debug_status_label.set_text("");
auto &menu=Menu::get();
menu.actions["debug_stop"]->set_enabled(false);
menu.actions["debug_kill"]->set_enabled(false);
menu.actions["debug_step_over"]->set_enabled(false);
menu.actions["debug_step_into"]->set_enabled(false);
menu.actions["debug_step_out"]->set_enabled(false);
menu.actions["debug_backtrace"]->set_enabled(false);
menu.actions["debug_show_variables"]->set_enabled(false);
menu.actions["debug_run_command"]->set_enabled(false);
menu.actions["debug_goto_stop"]->set_enabled(false);
}
else {
debug_status_label.set_text("debug: "+debug_status);
auto &menu=Menu::get();
menu.actions["debug_stop"]->set_enabled();
menu.actions["debug_kill"]->set_enabled();
menu.actions["debug_step_over"]->set_enabled();
menu.actions["debug_step_into"]->set_enabled();
menu.actions["debug_step_out"]->set_enabled();
menu.actions["debug_backtrace"]->set_enabled();
menu.actions["debug_show_variables"]->set_enabled();
menu.actions["debug_run_command"]->set_enabled();
menu.actions["debug_goto_stop"]->set_enabled();
}
debug_status_mutex.unlock();
});
about.set_version(Config::get().window.version);
about.set_authors({"(in order of appearance)",
"Ted Johan Kristoffersen",
@ -575,8 +507,8 @@ void Window::set_menu_actions() {
});
menu.add_action("project_set_run_arguments", [this]() {
project=get_project();
auto run_arguments=std::make_shared<std::pair<std::string, std::string> >(project->get_run_arguments());
auto project_language=Project::get().get_language();
auto run_arguments=std::make_shared<std::pair<std::string, std::string> >(project_language->get_run_arguments());
if(run_arguments->second.empty())
return;
@ -588,7 +520,7 @@ void Window::set_menu_actions() {
};
label_it->update(0, "");
entry_box.entries.emplace_back(run_arguments->second, [this, run_arguments](const std::string& content){
Project::run_arguments[run_arguments->first]=content;
Project::get().run_arguments[run_arguments->first]=content;
entry_box.hide();
}, 50);
auto entry_it=entry_box.entries.begin();
@ -599,24 +531,24 @@ void Window::set_menu_actions() {
entry_box.show();
});
menu.add_action("compile_and_run", [this]() {
if(Project::compiling)
if(Project::get().compiling)
return;
if(Config::get().window.save_on_compile_or_run)
notebook.save_project_files();
project=get_project();
project->compile_and_run();
project_language=Project::get().get_language();
project_language->compile_and_run();
});
menu.add_action("compile", [this]() {
if(Project::compiling)
if(Project::get().compiling)
return;
if(Config::get().window.save_on_compile_or_run)
notebook.save_project_files();
project=get_project();
project->compile();
project_language=Project::get().get_language();
project_language->compile();
});
menu.add_action("run_command", [this]() {
@ -656,8 +588,8 @@ void Window::set_menu_actions() {
#ifdef JUCI_ENABLE_DEBUG
menu.add_action("debug_set_run_arguments", [this]() {
project=get_project();
auto run_arguments=std::make_shared<std::pair<std::string, std::string> >(project->debug_get_run_arguments());
auto project_language=Project::get().get_language();
auto run_arguments=std::make_shared<std::pair<std::string, std::string> >(project_language->debug_get_run_arguments());
if(run_arguments->second.empty())
return;
@ -669,7 +601,7 @@ void Window::set_menu_actions() {
};
label_it->update(0, "");
entry_box.entries.emplace_back(run_arguments->second, [this, run_arguments](const std::string& content){
Project::debug_run_arguments[run_arguments->first]=content;
Project::get().debug_run_arguments[run_arguments->first]=content;
entry_box.hide();
}, 50);
auto entry_it=entry_box.entries.begin();
@ -680,64 +612,52 @@ void Window::set_menu_actions() {
entry_box.show();
});
menu.add_action("debug_start_continue", [this](){
if(Project::debugging) {
project->debug_continue();
if(Project::get().debugging) {
project_language->debug_continue();
return;
}
if(Config::get().window.save_on_compile_or_run)
notebook.save_project_files();
project=get_project();
project_language=Project::get().get_language();
project->debug_start([this](const std::string &status) {
debug_status_mutex.lock();
debug_status=status;
debug_status_mutex.unlock();
debug_update_status();
}, [this](const boost::filesystem::path &file_path, int line_nr, int line_index) {
debug_stop_mutex.lock();
debug_stop.first=file_path;
debug_stop.second.first=line_nr;
debug_stop.second.second=line_index;
debug_stop_mutex.unlock();
debug_update_stop();
});
project_language->debug_start();
});
menu.add_action("debug_stop", [this]() {
if(project)
project->debug_stop();
if(project_language)
project_language->debug_stop();
});
menu.add_action("debug_kill", [this]() {
if(project)
project->debug_kill();
if(project_language)
project_language->debug_kill();
});
menu.add_action("debug_step_over", [this]() {
if(project)
project->debug_step_over();
if(project_language)
project_language->debug_step_over();
});
menu.add_action("debug_step_into", [this]() {
if(project)
project->debug_step_into();
if(project_language)
project_language->debug_step_into();
});
menu.add_action("debug_step_out", [this]() {
if(project)
project->debug_step_out();
if(project_language)
project_language->debug_step_out();
});
menu.add_action("debug_backtrace", [this]() {
if(project)
project->debug_backtrace();
if(project_language)
project_language->debug_backtrace();
});
menu.add_action("debug_show_variables", [this]() {
if(project)
project->debug_show_variables();
if(project_language)
project_language->debug_show_variables();
});
menu.add_action("debug_run_command", [this]() {
entry_box.clear();
entry_box.entries.emplace_back(last_run_debug_command, [this](const std::string& content){
if(content!="") {
if(project)
project->debug_run_command(content);
if(project_language)
project_language->debug_run_command(content);
last_run_debug_command=content;
}
entry_box.hide();
@ -773,35 +693,8 @@ void Window::set_menu_actions() {
}
});
menu.add_action("debug_goto_stop", [this](){
if(project && project->debugging) {
debug_stop_mutex.lock();
auto debug_stop_copy=debug_stop;
debug_stop_mutex.unlock();
if(!debug_stop_copy.first.empty()) {
notebook.open(debug_stop_copy.first);
if(notebook.get_current_page()!=-1) {
auto view=notebook.get_current_view();
int line_nr=debug_stop_copy.second.first-1;
int line_index=debug_stop_copy.second.second-1;
if(line_nr<view->get_buffer()->get_line_count()) {
auto iter=view->get_buffer()->get_iter_at_line(line_nr);
auto end_line_iter=iter;
while(!iter.ends_line() && iter.forward_char()) {}
auto line=view->get_buffer()->get_text(iter, end_line_iter);
if(static_cast<size_t>(line_index)>=line.bytes())
line_index=0;
view->get_buffer()->place_cursor(view->get_buffer()->get_iter_at_line_index(line_nr, line_index));
while(g_main_context_pending(NULL))
g_main_context_iteration(NULL, false);
if(notebook.get_current_page()!=-1 && notebook.get_current_view()==view)
view->scroll_to(view->get_buffer()->get_insert(), 0.0, 1.0, 0.5);
}
debug_update_stop();
}
}
}
if(project_language)
project_language->debug_goto_stop();
});
#endif
@ -899,8 +792,8 @@ bool Window::on_delete_event(GdkEventAny *event) {
}
Terminal::get().kill_async_processes();
#ifdef JUCI_ENABLE_DEBUG
if(project)
project->debug_delete();
if(project_language)
project_language->debug_delete();
#endif
return false;
}
@ -1126,19 +1019,3 @@ void Window::rename_token_entry() {
}
}
}
std::unique_ptr<Project> Window::get_project() {
if(notebook.get_current_page()!=-1) {
auto language_id=notebook.get_current_view()->language->get_id();
if(language_id=="markdown")
return std::unique_ptr<Project>(new ProjectMarkdown(notebook));
if(language_id=="python")
return std::unique_ptr<Project>(new ProjectPython(notebook));
if(language_id=="js")
return std::unique_ptr<Project>(new ProjectJavaScript(notebook));
if(language_id=="html")
return std::unique_ptr<Project>(new ProjectHTML(notebook));
}
return std::unique_ptr<Project>(new ProjectClang(notebook));
}

19
src/window.h

@ -1,7 +1,7 @@
#ifndef JUCI_WINDOW_H_
#define JUCI_WINDOW_H_
#include "gtkmm.h"
#include <gtkmm.h>
#include "entrybox.h"
#include "notebook.h"
#include "cmake.h"
@ -11,13 +11,12 @@
class Window : public Gtk::ApplicationWindow {
private:
Window();
Notebook &notebook; //convenience reference
public:
static Window &get() {
static Window singleton;
return singleton;
}
Notebook notebook;
protected:
bool on_key_press_event(GdkEventKey *event) override;
@ -34,17 +33,7 @@ private:
Gtk::AboutDialog about;
EntryBox entry_box;
std::unique_ptr<Project> project;
Gtk::Label debug_status_label;
std::pair<boost::filesystem::path, std::pair<int, int> > debug_stop;
boost::filesystem::path debug_last_stop_file_path;
std::mutex debug_stop_mutex;
Glib::Dispatcher debug_update_stop;
std::string debug_status;
std::mutex debug_status_mutex;
Glib::Dispatcher debug_update_status;
std::unique_ptr<Project::Language> project_language;
void configure();
void set_menu_actions();
@ -60,8 +49,6 @@ private:
bool case_sensitive_search=true;
bool regex_search=false;
bool search_entry_shown=false;
std::unique_ptr<Project> get_project();
};
#endif // JUCI_WINDOW_H

Loading…
Cancel
Save