Browse Source

Fixed crash when closing a tab real quick after moving cursor.

merge-requests/365/head
eidheim 10 years ago
parent
commit
242a6ca963
  1. 15
      src/directories.cc
  2. 18
      src/notebook.cc
  3. 3
      src/selectiondialog.cc
  4. 24
      src/source.cc
  5. 2
      src/source.h
  6. 11
      src/terminal.cc
  7. 1
      src/tooltips.cc
  8. 13
      src/window.cc

15
src/directories.cc

@ -19,7 +19,7 @@ namespace sigc {
}
Directories::Directories() : stop_update_thread(false) {
DEBUG("adding treeview to scrolledwindow");
DEBUG("start");
add(tree_view);
set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
tree_store = Gtk::TreeStore::create(column_record);
@ -30,7 +30,6 @@ Directories::Directories() : stop_update_thread(false) {
tree_view.set_search_column(column_record.name);
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) {
auto path_str=iter->get_value(column_record.path);
@ -68,7 +67,6 @@ Directories::Directories() : stop_update_thread(false) {
});
update_dispatcher.connect([this](){
DEBUG("start");
update_mutex.lock();
for(auto &path: update_paths) {
if(last_write_times.count(path)>0)
@ -76,13 +74,11 @@ Directories::Directories() : stop_update_thread(false) {
}
update_paths.clear();
update_mutex.unlock();
DEBUG("end");
});
update_thread=std::thread([this](){
while(!stop_update_thread) {
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
DEBUG("start");
update_mutex.lock();
if(update_paths.size()==0) {
for(auto it=last_write_times.begin();it!=last_write_times.end();) {
@ -104,7 +100,6 @@ Directories::Directories() : stop_update_thread(false) {
update_dispatcher();
}
update_mutex.unlock();
DEBUG("end");
}
});
}
@ -115,11 +110,10 @@ Directories::~Directories() {
}
void Directories::open(const boost::filesystem::path& dir_path) {
DEBUG("start");
if(dir_path=="")
return;
INFO("Open folder");
tree_store->clear();
update_mutex.lock();
last_write_times.clear();
@ -138,7 +132,7 @@ void Directories::open(const boost::filesystem::path& dir_path) {
current_path=dir_path;
DEBUG("Folder opened");
DEBUG("end");
}
void Directories::update() {
@ -196,7 +190,6 @@ void Directories::select(const boost::filesystem::path &path) {
}
bool Directories::ignored(std::string path) {
DEBUG("Checking if file-/directory is filtered");
std::transform(path.begin(), path.end(), path.begin(), ::tolower);
for(std::string &i : Singleton::Config::directories()->exceptions) {
@ -212,7 +205,6 @@ bool Directories::ignored(std::string path) {
}
void Directories::add_path(const boost::filesystem::path& dir_path, const Gtk::TreeModel::Row &parent) {
DEBUG("start");
last_write_times[dir_path.string()]={parent, boost::filesystem::last_write_time(dir_path)};
std::unique_ptr<Gtk::TreeNodeChildren> children; //Gtk::TreeNodeChildren is missing default constructor...
if(parent)
@ -266,5 +258,4 @@ void Directories::add_path(const boost::filesystem::path& dir_path, const Gtk::T
auto child=tree_store->append(*children);
child->set_value(column_record.name, std::string("(empty)"));
}
DEBUG("end");
}

18
src/notebook.cc

@ -32,13 +32,11 @@ Source::View* Notebook::get_view(int page) {
}
Source::View* Notebook::get_current_view() {
INFO("Getting sourceview");
return get_view(get_current_page());
}
void Notebook::open(const boost::filesystem::path &file_path) {
INFO("Notebook open file");
INFO("Notebook create page");
DEBUG("start");
for(int c=0;c<size();c++) {
if(file_path==get_view(c)->file_path) {
set_current_page(c);
@ -106,14 +104,16 @@ void Notebook::open(const boost::filesystem::path &file_path) {
get_current_view()->on_update_status=[this](Source::View* view, const std::string &status) {
if(get_current_page()!=-1 && get_current_view()==view)
Singleton::status()->set_text(status);
else
Singleton::status()->set_text("");
};
DEBUG("end");
}
bool Notebook::save(int page) {
if(page>=size())
DEBUG("start");
if(page>=size()) {
DEBUG("end false");
return false;
}
auto view=get_view(page);
if (view->file_path != "" && view->get_buffer()->get_modified()) {
if(juci::filesystem::write(view->file_path, view->get_buffer())) {
@ -145,16 +145,16 @@ bool Notebook::save(int page) {
}
}
}
DEBUG("end true");
return true;
}
Singleton::terminal()->print("Error: could not save file " +view->file_path.string()+"\n");
}
DEBUG("end false");
return false;
}
bool Notebook::save_current() {
INFO("Notebook save current file");
if(get_current_page()==-1)
return false;
return save(get_current_page());
@ -162,7 +162,6 @@ bool Notebook::save_current() {
bool Notebook::close_current_page() {
DEBUG("start");
INFO("Notebook close page");
if (get_current_page()!=-1) {
if(get_current_view()->get_buffer()->get_modified()){
if(!save_modified_dialog()) {
@ -186,7 +185,6 @@ bool Notebook::close_current_page() {
}
bool Notebook::save_modified_dialog() {
INFO("Notebook::save_modified_dialog");
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: " + get_current_view()->file_path.string()+" ?");
int result = dialog.run();

3
src/selectiondialog.cc

@ -117,7 +117,6 @@ void SelectionDialogBase::update_tooltips() {
}
void SelectionDialogBase::move() {
INFO("SelectionDialog set position");
Gdk::Rectangle rectangle;
text_view.get_iter_location(start_mark->get_iter(), rectangle);
int buffer_x=rectangle.get_x();
@ -130,8 +129,6 @@ void SelectionDialogBase::move() {
}
void SelectionDialogBase::resize() {
INFO("SelectionDialog set size");
if(list_view_text.get_realized()) {
int row_width=0, row_height;
Gdk::Rectangle rect;

24
src/source.cc

@ -326,6 +326,9 @@ Source::View::~View() {
g_clear_object(&search_context);
g_clear_object(&search_settings);
delayed_tooltips_connection.disconnect();
delayed_spellcheck_suggestions_connection.disconnect();
if(spellcheck_checker!=NULL)
delete_aspell_speller(spellcheck_checker);
}
@ -755,6 +758,7 @@ clang::Index Source::ClangViewParse::clang_index(0, 0);
Source::ClangViewParse::ClangViewParse(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path):
Source::View(file_path), project_path(project_path) {
DEBUG("start");
auto scheme = get_source_buffer()->get_style_scheme();
auto tag_table=get_buffer()->get_tag_table();
for (auto &item : Singleton::Config::source()->clang_types) {
@ -762,7 +766,6 @@ Source::View(file_path), project_path(project_path) {
auto style = scheme->get_style(item.second);
auto tag = get_source_buffer()->create_tag(item.second);
if (style) {
DEBUG("Style " + item.second + " found in style " + scheme->get_name());
if (style->property_foreground_set())
tag->property_foreground() = style->property_foreground();
if (style->property_background_set())
@ -774,10 +777,9 @@ Source::View(file_path), project_path(project_path) {
// // 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
DEBUG("Style " + item.second + " not found in " + scheme->get_name());
INFO("Style " + item.second + " not found in " + scheme->get_name());
}
}
INFO("Tagtable filled");
parsing_in_progress=Singleton::terminal()->print_in_progress("Parsing "+file_path.string());
//GTK-calls must happen in main thread, so the parse_thread
@ -793,14 +795,12 @@ Source::View(file_path), project_path(project_path) {
parse_done.connect([this](){
if(parse_thread_mapped) {
if(parsing_mutex.try_lock()) {
INFO("Updating syntax");
update_syntax();
update_diagnostics();
update_types();
source_readable=true;
set_status("");
parsing_mutex.unlock();
INFO("Syntax updated");
}
parsing_in_progress->done("done");
}
@ -819,12 +819,16 @@ Source::View(file_path), project_path(project_path) {
bracket_regex=std::regex(std::string("^(")+tab_char+"*).*\\{ *$");
no_bracket_statement_regex=std::regex(std::string("^(")+tab_char+"*)(if|for|else if|catch|while) *\\(.*[^;}] *$");
no_bracket_no_para_statement_regex=std::regex(std::string("^(")+tab_char+"*)(else|try|do) *$");
DEBUG("end");
}
Source::ClangViewParse::~ClangViewParse() {
delayed_reparse_connection.disconnect();
}
void Source::ClangViewParse::init_parse() {
type_tooltips.hide();
diagnostic_tooltips.hide();
get_buffer()->remove_all_tags(get_buffer()->begin(), get_buffer()->end());
source_readable=false;
parse_thread_go=true;
parse_thread_mapped=false;
@ -1272,7 +1276,6 @@ void Source::ClangViewAutocomplete::autocomplete() {
if(!autocomplete_starting) {
autocomplete_starting=true;
autocomplete_cancel_starting=false;
INFO("Source::ClangViewAutocomplete::autocomplete getting autocompletions");
std::shared_ptr<std::vector<Source::AutoCompleteData> > ac_data=std::make_shared<std::vector<Source::AutoCompleteData> >();
autocomplete_done_connection.disconnect();
autocomplete_done_connection=autocomplete_done.connect([this, ac_data](){
@ -1368,7 +1371,6 @@ void Source::ClangViewAutocomplete::autocomplete() {
std::vector<Source::AutoCompleteData> Source::ClangViewAutocomplete::
get_autocomplete_suggestions(int line_number, int column, std::map<std::string, std::string>& buffer_map) {
INFO("Getting auto complete suggestions");
std::vector<Source::AutoCompleteData> suggestions;
auto results=clang_tu->get_code_completions(buffer_map, line_number, column);
if(!autocomplete_cancel_starting) {
@ -1394,8 +1396,6 @@ get_autocomplete_suggestions(int line_number, int column, std::map<std::string,
}
}
}
DEBUG("Number of suggestions");
DEBUG_VAR(suggestions.size());
return suggestions;
}
@ -1545,6 +1545,10 @@ Source::ClangViewAutocomplete(file_path, project_path) {
};
}
Source::ClangViewRefactor::~ClangViewRefactor() {
delayed_tag_similar_tokens_connection.disconnect();
}
Source::ClangView::ClangView(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path, Glib::RefPtr<Gsv::Language> language): ClangViewRefactor(file_path, project_path) {
if(language) {
get_source_buffer()->set_highlight_syntax(true);

2
src/source.h

@ -124,6 +124,7 @@ namespace Source {
class ClangViewParse : public View {
public:
ClangViewParse(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path);
~ClangViewParse();
boost::filesystem::path project_path;
void start_reparse();
bool start_reparse_needed=false;
@ -187,6 +188,7 @@ namespace Source {
class ClangViewRefactor : public ClangViewAutocomplete {
public:
ClangViewRefactor(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path);
~ClangViewRefactor();
private:
Glib::RefPtr<Gtk::TextTag> similar_tokens_tag;
std::string last_similar_tokens_tagged;

11
src/terminal.cc

@ -154,6 +154,7 @@ Terminal::Terminal() {
}
int Terminal::execute(const std::string &command, const boost::filesystem::path &path) {
DEBUG("start");
int stdin_fd, stdout_fd, stderr_fd;
auto pid=popen3(command, path.string(), &stdin_fd, &stdout_fd, &stderr_fd);
@ -176,7 +177,6 @@ int Terminal::execute(const std::string &command, const boost::filesystem::path
std::thread stdout_thread([this, stdout_fd](){
char buffer[1024];
ssize_t n;
INFO("read");
while ((n=read(stdout_fd, buffer, 1024)) > 0) {
std::string message;
for(ssize_t c=0;c<n;c++)
@ -192,12 +192,14 @@ int Terminal::execute(const std::string &command, const boost::filesystem::path
close(stdout_fd);
close(stderr_fd);
DEBUG("end");
return exit_code;
}
}
void Terminal::async_execute(const std::string &command, const boost::filesystem::path &path, std::function<void(int exit_code)> callback) {
std::thread async_execute_thread([this, command, path, callback](){
DEBUG("start");
int stdin_fd, stdout_fd, stderr_fd;
async_executes_mutex.lock();
stdin_buffer.clear();
@ -225,7 +227,6 @@ void Terminal::async_execute(const std::string &command, const boost::filesystem
std::thread stdout_thread([this, stdout_fd](){
char buffer[1024];
ssize_t n;
INFO("read");
while ((n=read(stdout_fd, buffer, 1024)) > 0) {
std::string message;
for(ssize_t c=0;c<n;c++)
@ -252,6 +253,8 @@ void Terminal::async_execute(const std::string &command, const boost::filesystem
if(callback)
callback(exit_code);
DEBUG("end");
}
});
async_execute_thread.detach();
@ -280,7 +283,6 @@ void Terminal::kill_async_executes(bool force) {
}
int Terminal::print(const std::string &message, bool bold){
DEBUG("start");
if(bold)
get_buffer()->insert_with_tag(get_buffer()->end(), message, bold_tag);
else
@ -293,16 +295,13 @@ int Terminal::print(const std::string &message, bool bold){
get_buffer()->delete_mark(mark);
}
DEBUG("end");
return get_buffer()->end().get_line();
}
void Terminal::print(int line_nr, const std::string &message){
DEBUG("start");
auto iter=get_buffer()->get_iter_at_line(line_nr);
while(!iter.ends_line() && iter.forward_char()) {}
get_buffer()->insert(iter, message);
DEBUG("end");
}
std::shared_ptr<Terminal::InProgress> Terminal::print_in_progress(std::string start_msg) {

1
src/tooltips.cc

@ -93,7 +93,6 @@ void Tooltip::adjust(bool disregard_drawn) {
}
void Tooltip::wrap_lines(Glib::RefPtr<Gtk::TextBuffer> text_buffer) {
INFO("Tooltip::wrap_lines");
auto iter=text_buffer->begin();
while(iter) {

13
src/window.cc

@ -29,7 +29,7 @@ void Window::generate_keybindings() {
}
Window::Window() : box(Gtk::ORIENTATION_VERTICAL), notebook(directories), compiling(false) {
INFO("Create Window");
DEBUG("start");
set_title("juCi++");
set_default_size(600, 400);
set_events(Gdk::POINTER_MOTION_MASK|Gdk::FOCUS_CHANGE_MASK|Gdk::SCROLL_MASK);
@ -80,7 +80,6 @@ Window::Window() : box(Gtk::ORIENTATION_VERTICAL), notebook(directories), compil
});
notebook.signal_switch_page().connect([this](Gtk::Widget* page, guint page_num) {
DEBUG("start");
if(notebook.get_current_page()!=-1) {
if(search_entry_shown && entry_box.labels.size()>0) {
notebook.get_current_view()->update_search_occurrences=[this](int number){
@ -109,7 +108,6 @@ Window::Window() : box(Gtk::ORIENTATION_VERTICAL), notebook(directories), compil
Singleton::status()->set_text(notebook.get_current_view()->status);
}
DEBUG("end");
});
notebook.signal_page_removed().connect([this](Gtk::Widget* page, guint page_num) {
entry_box.hide();
@ -130,11 +128,10 @@ 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);
INFO("Window created");
DEBUG("end");
} // Window constructor
void Window::create_menu() {
INFO("Adding actions to menu");
menu.action_group->add(Gtk::Action::create("FileQuit", "Quit juCi++"), Gtk::AccelKey(menu.key_map["quit"]), [this]() {
hide();
});
@ -187,7 +184,6 @@ void Window::create_menu() {
search_and_replace_entry();
});
menu.action_group->add(Gtk::Action::create("EditUndo", "Undo"), Gtk::AccelKey(menu.key_map["edit_undo"]), [this]() {
INFO("On undo");
if(notebook.get_current_page()!=-1) {
auto undo_manager = notebook.get_current_view()->get_source_buffer()->get_undo_manager();
if (undo_manager->can_undo()) {
@ -195,10 +191,8 @@ void Window::create_menu() {
notebook.get_current_view()->scroll_to(notebook.get_current_view()->get_buffer()->get_insert());
}
}
INFO("Done undo");
});
menu.action_group->add(Gtk::Action::create("EditRedo", "Redo"), Gtk::AccelKey(menu.key_map["edit_redo"]), [this]() {
INFO("On Redo");
if(notebook.get_current_page()!=-1) {
auto undo_manager = notebook.get_current_view()->get_source_buffer()->get_undo_manager();
if(undo_manager->can_redo()) {
@ -206,7 +200,6 @@ void Window::create_menu() {
notebook.get_current_view()->scroll_to(notebook.get_current_view()->get_buffer()->get_insert());
}
}
INFO("Done Redo");
});
menu.action_group->add(Gtk::Action::create("SourceGotoLine", "Go to Line"), Gtk::AccelKey(menu.key_map["source_goto_line"]), [this]() {
@ -336,7 +329,6 @@ void Window::create_menu() {
});
add_accel_group(menu.ui_manager->get_accel_group());
menu.build();
INFO("Menu build")
}
bool Window::on_key_press_event(GdkEventKey *event) {
@ -530,7 +522,6 @@ void Window::open_file_dialog() {
void Window::save_file_dialog() {
if(notebook.get_current_page()==-1)
return;
INFO("Save file dialog");
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);

Loading…
Cancel
Save