Browse Source

Merge pull request #54 from eidheim/master

Many bug fixes and improved clang indentation
merge-requests/365/head
Jørgen Lien Sellæg 10 years ago
parent
commit
67e6c6e38a
  1. 4
      src/CMakeLists.txt
  2. 13
      src/directories.cc
  3. 6
      src/juci.cc
  4. 2
      src/logging.h
  5. 4
      src/menu.cc
  6. 57
      src/notebook.cc
  7. 2
      src/notebook.h
  8. 12
      src/selectiondialog.cc
  9. 751
      src/source.cc
  10. 24
      src/source.h
  11. 65
      src/sourcefile.cc
  12. 4
      src/sourcefile.h
  13. 42
      src/terminal.cc
  14. 24
      src/tooltips.cc
  15. 35
      src/window.cc

4
src/CMakeLists.txt

@ -3,7 +3,9 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -std=c++11 -pthread -Wall -Wno-reord
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_LIST_DIR}/cmake/Modules/") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_LIST_DIR}/cmake/Modules/")
if(APPLE) if(APPLE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L/usr/local/opt/gettext/lib -I/usr/local/opt/gettext/include -undefined dynamic_lookup") #T set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -undefined dynamic_lookup")
link_directories(/usr/local/lib /usr/local/opt/gettext/lib)
include_directories(/usr/local/opt/gettext/include)
set(CMAKE_MACOSX_RPATH 1) set(CMAKE_MACOSX_RPATH 1)
set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:/usr/local/lib/pkgconfig:/opt/X11/lib/pkgconfig") set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:/usr/local/lib/pkgconfig:/opt/X11/lib/pkgconfig")
endif() endif()

13
src/directories.cc

@ -23,7 +23,7 @@ namespace sigc {
} }
Directories::Directories() : stop_update_thread(false) { Directories::Directories() : stop_update_thread(false) {
DEBUG("adding treeview to scrolledwindow"); DEBUG("start");
add(tree_view); add(tree_view);
set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
tree_store = Gtk::TreeStore::create(column_record); tree_store = Gtk::TreeStore::create(column_record);
@ -34,7 +34,6 @@ Directories::Directories() : stop_update_thread(false) {
tree_view.set_search_column(column_record.name); tree_view.set_search_column(column_record.name);
tree_view.signal_row_activated().connect([this](const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* column){ 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); auto iter = tree_store->get_iter(path);
if (iter) { if (iter) {
auto path_str=iter->get_value(column_record.path); auto path_str=iter->get_value(column_record.path);
@ -115,11 +114,10 @@ Directories::~Directories() {
} }
void Directories::open(const boost::filesystem::path& dir_path) { void Directories::open(const boost::filesystem::path& dir_path) {
DEBUG("start");
if(dir_path=="") if(dir_path=="")
return; return;
INFO("Open folder");
tree_store->clear(); tree_store->clear();
update_mutex.lock(); update_mutex.lock();
last_write_times.clear(); last_write_times.clear();
@ -138,18 +136,21 @@ void Directories::open(const boost::filesystem::path& dir_path) {
current_path=dir_path; current_path=dir_path;
DEBUG("Folder opened"); DEBUG("end");
} }
void Directories::update() { void Directories::update() {
DEBUG("start");
update_mutex.lock(); update_mutex.lock();
for(auto &last_write_time: last_write_times) { for(auto &last_write_time: last_write_times) {
add_path(last_write_time.first, last_write_time.second.first); add_path(last_write_time.first, last_write_time.second.first);
} }
update_mutex.unlock(); update_mutex.unlock();
DEBUG("end");
} }
void Directories::select(const boost::filesystem::path &path) { void Directories::select(const boost::filesystem::path &path) {
DEBUG("start");
if(current_path=="") if(current_path=="")
return; return;
@ -189,10 +190,10 @@ void Directories::select(const boost::filesystem::path &path) {
} }
return false; return false;
}); });
DEBUG("end");
} }
bool Directories::ignored(std::string path) { bool Directories::ignored(std::string path) {
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);
for(std::string &i : Singleton::Config::directories()->exceptions) { for(std::string &i : Singleton::Config::directories()->exceptions) {

6
src/juci.cc

@ -6,9 +6,9 @@
using namespace std; //TODO: remove using namespace std; //TODO: remove
void init_logging() { void init_logging() {
add_common_attributes(); boost::log::add_common_attributes();
add_file_log(keywords::file_name = Singleton::log_dir() + "juci.log", boost::log::add_file_log(boost::log::keywords::file_name = Singleton::log_dir() + "juci.log",
keywords::auto_flush = true); boost::log::keywords::auto_flush = true);
INFO("Logging initalized"); INFO("Logging initalized");
} }

2
src/logging.h

@ -10,8 +10,6 @@
#include <boost/log/sources/severity_logger.hpp> #include <boost/log/sources/severity_logger.hpp>
#include <boost/log/sources/record_ostream.hpp> #include <boost/log/sources/record_ostream.hpp>
using namespace boost::log;
#define TRACE_VAR(x) BOOST_LOG_TRIVIAL(trace) << "** Trace: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): " << #x << "=<" << x << ">"; #define TRACE_VAR(x) BOOST_LOG_TRIVIAL(trace) << "** Trace: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): " << #x << "=<" << x << ">";
#define DEBUG_VAR(x) BOOST_LOG_TRIVIAL(debug) << "** Debug: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): " << #x << "=<" << x << ">"; #define DEBUG_VAR(x) BOOST_LOG_TRIVIAL(debug) << "** Debug: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): " << #x << "=<" << x << ">";
#define INFO_VAR(x) BOOST_LOG_TRIVIAL(info) << "** Info: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): " << #x << "=<" << x << ">"; #define INFO_VAR(x) BOOST_LOG_TRIVIAL(info) << "** Info: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): " << #x << "=<" << x << ">";

4
src/menu.cc

@ -1,8 +1,7 @@
#include "menu.h" #include "menu.h"
#include "logging.h" #include <iostream>
Menu::Menu() : box(Gtk::ORIENTATION_VERTICAL) { Menu::Menu() : box(Gtk::ORIENTATION_VERTICAL) {
INFO("Creating menu");
action_group = Gtk::ActionGroup::create(); action_group = Gtk::ActionGroup::create();
ui_manager = Gtk::UIManager::create(); ui_manager = Gtk::UIManager::create();
@ -15,7 +14,6 @@ Menu::Menu() : box(Gtk::ORIENTATION_VERTICAL) {
action_group->add(Gtk::Action::create("SourceMenu", "_Source")); action_group->add(Gtk::Action::create("SourceMenu", "_Source"));
action_group->add(Gtk::Action::create("PluginMenu", "_Plugins")); action_group->add(Gtk::Action::create("PluginMenu", "_Plugins"));
action_group->add(Gtk::Action::create("HelpMenu", "Help")); action_group->add(Gtk::Action::create("HelpMenu", "Help"));
INFO("Menu created");
} }
Gtk::Widget& Menu::get_widget() { Gtk::Widget& Menu::get_widget() {

57
src/notebook.cc

@ -32,21 +32,15 @@ int Notebook::size() {
} }
Source::View* Notebook::get_view(int page) { Source::View* Notebook::get_view(int page) {
if(page>=size())
return nullptr;
return source_views.at(page); return source_views.at(page);
} }
Source::View* Notebook::get_current_view() { Source::View* Notebook::get_current_view() {
INFO("Getting sourceview");
if(get_current_page()==-1)
return nullptr;
return get_view(get_current_page()); return get_view(get_current_page());
} }
void Notebook::open(const boost::filesystem::path &file_path) { void Notebook::open(const boost::filesystem::path &file_path) {
INFO("Notebook open file"); DEBUG("start");
INFO("Notebook create page");
for(int c=0;c<size();c++) { for(int c=0;c<size();c++) {
if(file_path==get_view(c)->file_path) { if(file_path==get_view(c)->file_path) {
set_current_page(c); set_current_page(c);
@ -112,22 +106,28 @@ void Notebook::open(const boost::filesystem::path &file_path) {
}); });
get_current_view()->on_update_status=[this](Source::View* view, const std::string &status) { get_current_view()->on_update_status=[this](Source::View* view, const std::string &status) {
if(get_current_view()==view) if(get_current_page()!=-1 && get_current_view()==view)
Singleton::status()->set_text(status); Singleton::status()->set_text(status);
}; };
DEBUG("end");
} }
bool Notebook::save(int page) { bool Notebook::save(int page, bool reparse_needed) {
if(page>=size()) DEBUG("start");
if(page>=size()) {
DEBUG("end false");
return false; return false;
}
auto view=get_view(page); auto view=get_view(page);
if (view->file_path != "" && view->get_buffer()->get_modified()) { if (view->file_path != "" && view->get_buffer()->get_modified()) {
if(juci::filesystem::write(view->file_path, view->get_buffer())) { if(juci::filesystem::write(view->file_path, view->get_buffer())) {
if(auto clang_view=dynamic_cast<Source::ClangView*>(view)) { if(reparse_needed) {
for(auto a_view: source_views) { if(auto clang_view=dynamic_cast<Source::ClangView*>(view)) {
if(auto a_clang_view=dynamic_cast<Source::ClangView*>(a_view)) { for(auto a_view: source_views) {
if(clang_view!=a_clang_view) if(auto a_clang_view=dynamic_cast<Source::ClangView*>(a_view)) {
a_clang_view->start_reparse_needed=true; if(clang_view!=a_clang_view)
a_clang_view->reparse_needed=true;
}
} }
} }
} }
@ -145,53 +145,54 @@ bool Notebook::save(int page) {
if(source_clang_view->restart_parse()) if(source_clang_view->restart_parse())
Singleton::terminal()->async_print("Reparsing "+source_clang_view->file_path.string()+"\n"); Singleton::terminal()->async_print("Reparsing "+source_clang_view->file_path.string()+"\n");
else else
Singleton::terminal()->async_print("Already reparsing "+source_clang_view->file_path.string()+". Please reopen the file manually.\n"); Singleton::terminal()->async_print("Error: failed to reparse "+source_clang_view->file_path.string()+". Please reopen the file manually.\n");
} }
} }
} }
} }
} }
DEBUG("end true");
return true; return true;
} }
Singleton::terminal()->print("Error: could not save file " +view->file_path.string()+"\n"); Singleton::terminal()->print("Error: could not save file " +view->file_path.string()+"\n");
} }
DEBUG("end false");
return false; return false;
} }
bool Notebook::save_current() { bool Notebook::save_current() {
INFO("Notebook save current file");
if(get_current_page()==-1) if(get_current_page()==-1)
return false; return false;
return save(get_current_page()); return save(get_current_page(), true);
} }
bool Notebook::close_current_page() { bool Notebook::close_current_page() {
INFO("Notebook close page"); DEBUG("start");
if (size() != 0) { if (get_current_page()!=-1) {
if(get_current_view()->get_buffer()->get_modified()){ if(get_current_view()->get_buffer()->get_modified()){
if(!save_modified_dialog()) if(!save_modified_dialog()) {
DEBUG("end false");
return false; return false;
}
} }
int page = get_current_page(); int page = get_current_page();
remove_page(page); remove_page(page);
if(get_current_page()==-1)
Singleton::status()->set_text("");
auto source_view=source_views.at(page); auto source_view=source_views.at(page);
source_views.erase(source_views.begin()+ page);
scrolled_windows.erase(scrolled_windows.begin()+page);
hboxes.erase(hboxes.begin()+page);
if(auto source_clang_view=dynamic_cast<Source::ClangView*>(source_view)) if(auto source_clang_view=dynamic_cast<Source::ClangView*>(source_view))
source_clang_view->async_delete(); source_clang_view->async_delete();
else else
delete source_view; delete source_view;
source_views.erase(source_views.begin()+ page);
scrolled_windows.erase(scrolled_windows.begin()+page);
hboxes.erase(hboxes.begin()+page);
} }
DEBUG("end true");
return true; return true;
} }
bool Notebook::save_modified_dialog() { 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); Gtk::MessageDialog dialog((Gtk::Window&)(*get_toplevel()), "Save file!", false, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO);
dialog.set_default_response(Gtk::RESPONSE_YES);
dialog.set_secondary_text("Do you want to save: " + get_current_view()->file_path.string()+" ?"); dialog.set_secondary_text("Do you want to save: " + get_current_view()->file_path.string()+" ?");
int result = dialog.run(); int result = dialog.run();
if(result==Gtk::RESPONSE_YES) { if(result==Gtk::RESPONSE_YES) {

2
src/notebook.h

@ -18,7 +18,7 @@ public:
Source::View* get_current_view(); Source::View* get_current_view();
bool close_current_page(); bool close_current_page();
void open(const boost::filesystem::path &file_path); void open(const boost::filesystem::path &file_path);
bool save(int page); bool save(int page, bool reparse_needed=false);
bool save_current(); bool save_current();
private: private:

12
src/selectiondialog.cc

@ -121,7 +121,6 @@ void SelectionDialogBase::update_tooltips() {
} }
void SelectionDialogBase::move() { void SelectionDialogBase::move() {
INFO("SelectionDialog set position");
Gdk::Rectangle rectangle; Gdk::Rectangle rectangle;
text_view.get_iter_location(start_mark->get_iter(), rectangle); text_view.get_iter_location(start_mark->get_iter(), rectangle);
int buffer_x=rectangle.get_x(); int buffer_x=rectangle.get_x();
@ -134,8 +133,6 @@ void SelectionDialogBase::move() {
} }
void SelectionDialogBase::resize() { void SelectionDialogBase::resize() {
INFO("SelectionDialog set size");
if(list_view_text.get_realized()) { if(list_view_text.get_realized()) {
int row_width=0, row_height; int row_width=0, row_height;
Gdk::Rectangle rect; Gdk::Rectangle rect;
@ -214,7 +211,8 @@ void SelectionDialog::show() {
else { else {
auto last_it=list_view_text.get_model()->children().end(); auto last_it=list_view_text.get_model()->children().end();
last_it--; last_it--;
list_view_text.set_cursor(list_view_text.get_model()->get_path(last_it)); if(last_it)
list_view_text.set_cursor(list_view_text.get_model()->get_path(last_it));
} }
return true; return true;
} }
@ -273,7 +271,8 @@ bool SelectionDialog::on_key_press(GdkEventKey* key) {
else { else {
auto last_it=list_view_text.get_model()->children().end(); auto last_it=list_view_text.get_model()->children().end();
last_it--; last_it--;
list_view_text.set_cursor(list_view_text.get_model()->get_path(last_it)); if(last_it)
list_view_text.set_cursor(list_view_text.get_model()->get_path(last_it));
} }
return true; return true;
} }
@ -422,7 +421,8 @@ bool CompletionDialog::on_key_press(GdkEventKey* key) {
else { else {
auto last_it=list_view_text.get_model()->children().end(); auto last_it=list_view_text.get_model()->children().end();
last_it--; last_it--;
list_view_text.set_cursor(list_view_text.get_model()->get_path(last_it)); if(last_it)
list_view_text.set_cursor(list_view_text.get_model()->get_path(last_it));
} }
select(false); select(false);
update_tooltips(); update_tooltips();

751
src/source.cc

File diff suppressed because it is too large Load Diff

24
src/source.h

@ -87,8 +87,17 @@ namespace Source {
void set_status(const std::string &status); void set_status(const std::string &status);
std::string get_line(size_t line_number); std::string get_line(const Gtk::TextIter &iter);
std::string get_line_before_insert(); std::string get_line(Glib::RefPtr<Gtk::TextBuffer::Mark> mark);
std::string get_line(int line_nr);
std::string get_line();
std::string get_line_before(const Gtk::TextIter &iter);
std::string get_line_before(Glib::RefPtr<Gtk::TextBuffer::Mark> mark);
std::string get_line_before();
bool find_start_of_closed_expression(Gtk::TextIter iter, Gtk::TextIter &found_iter);
bool find_open_expression_symbol(Gtk::TextIter iter, const Gtk::TextIter &until_iter, Gtk::TextIter &found_iter);
bool find_right_bracket_forward(Gtk::TextIter iter, Gtk::TextIter &found_iter);
bool on_key_press_event(GdkEventKey* key); bool on_key_press_event(GdkEventKey* key);
bool on_button_press_event(GdkEventButton *event); bool on_button_press_event(GdkEventButton *event);
@ -100,6 +109,8 @@ namespace Source {
std::regex tabs_regex; std::regex tabs_regex;
bool spellcheck_all=false; bool spellcheck_all=false;
std::unique_ptr<SelectionDialog> spellcheck_suggestions_dialog;
bool spellcheck_suggestions_dialog_shown=false;
private: private:
GtkSourceSearchContext *search_context; GtkSourceSearchContext *search_context;
GtkSourceSearchSettings *search_settings; GtkSourceSearchSettings *search_settings;
@ -108,12 +119,12 @@ namespace Source {
static AspellConfig* spellcheck_config; static AspellConfig* spellcheck_config;
AspellCanHaveError *spellcheck_possible_err; AspellCanHaveError *spellcheck_possible_err;
AspellSpeller *spellcheck_checker; AspellSpeller *spellcheck_checker;
bool is_word_iter(const Gtk::TextIter& iter);
std::pair<Gtk::TextIter, Gtk::TextIter> spellcheck_get_word(Gtk::TextIter iter); std::pair<Gtk::TextIter, Gtk::TextIter> spellcheck_get_word(Gtk::TextIter iter);
void spellcheck_word(const Gtk::TextIter& start, const Gtk::TextIter& end); void spellcheck_word(const Gtk::TextIter& start, const Gtk::TextIter& end);
std::vector<std::string> spellcheck_get_suggestions(const Gtk::TextIter& start, const Gtk::TextIter& end); std::vector<std::string> spellcheck_get_suggestions(const Gtk::TextIter& start, const Gtk::TextIter& end);
std::unique_ptr<SelectionDialog> spellcheck_suggestions_dialog;
bool spellcheck_suggestions_dialog_shown=false;
sigc::connection delayed_spellcheck_suggestions_connection; sigc::connection delayed_spellcheck_suggestions_connection;
bool last_keyval_is_backspace=false;
}; };
class GenericView : public View { class GenericView : public View {
@ -124,9 +135,10 @@ namespace Source {
class ClangViewParse : public View { class ClangViewParse : public View {
public: public:
ClangViewParse(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path); ClangViewParse(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path);
~ClangViewParse();
boost::filesystem::path project_path; boost::filesystem::path project_path;
void start_reparse(); void start_reparse();
bool start_reparse_needed=false; bool reparse_needed=false;
protected: protected:
void init_parse(); void init_parse();
bool on_key_press_event(GdkEventKey* key); bool on_key_press_event(GdkEventKey* key);
@ -157,6 +169,7 @@ namespace Source {
Glib::Dispatcher parse_done; Glib::Dispatcher parse_done;
Glib::Dispatcher parse_start; Glib::Dispatcher parse_start;
Glib::Dispatcher parse_fail;
std::map<std::string, std::string> parse_thread_buffer_map; std::map<std::string, std::string> parse_thread_buffer_map;
std::mutex parse_thread_buffer_map_mutex; std::mutex parse_thread_buffer_map_mutex;
std::atomic<bool> parse_thread_go; std::atomic<bool> parse_thread_go;
@ -187,6 +200,7 @@ namespace Source {
class ClangViewRefactor : public ClangViewAutocomplete { class ClangViewRefactor : public ClangViewAutocomplete {
public: public:
ClangViewRefactor(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path); ClangViewRefactor(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path);
~ClangViewRefactor();
private: private:
Glib::RefPtr<Gtk::TextTag> similar_tokens_tag; Glib::RefPtr<Gtk::TextTag> similar_tokens_tag;
std::string last_similar_tokens_tagged; std::string last_similar_tokens_tagged;

65
src/sourcefile.cc

@ -15,29 +15,58 @@ std::string juci::filesystem::read(const std::string &path) {
return ss.str(); return ss.str();
} }
bool juci::filesystem::read(const std::string &path, Glib::RefPtr<Gtk::TextBuffer> text_buffer) { int juci::filesystem::read(const std::string &path, Glib::RefPtr<Gtk::TextBuffer> text_buffer) {
std::ifstream input(path, std::ofstream::binary); std::ifstream input(path, std::ofstream::binary);
if(input) { if(input) {
std::vector<char> buffer(buffer_size); //need to read the whole file to make this work...
std::stringstream ss;
ss << input.rdbuf();
Glib::ustring ustr=std::move(ss.str());
bool valid=true;
//This was way too slow...
/*Glib::ustring::iterator iter;
while(!ustr.validate(iter)) {
auto next_char_iter=iter;
next_char_iter++;
ustr.replace(iter, next_char_iter, "?");
if(valid)
valid=false;
}*/
if(ustr.validate())
text_buffer->insert_at_cursor(ustr);
else
valid=false;
//TODO: maybe correct this, emphasis on maybe:
/*std::vector<char> buffer(buffer_size);
size_t read_length; size_t read_length;
std::string buffer_str;
while((read_length=input.read(&buffer[0], buffer_size).gcount())>0) { while((read_length=input.read(&buffer[0], buffer_size).gcount())>0) {
buffer_str+=std::string(&buffer[0], read_length); //auto ustr=Glib::ustring(std::string(&buffer[0], read_length)); //this works...
if(buffer_str.back()>=0) {
auto ustr=Glib::ustring(buffer_str); //this does not work:
buffer_str=""; Glib::ustring ustr;
if(ustr.validate()) ustr.resize(read_length);
text_buffer->insert_at_cursor(ustr); ustr.replace(0, read_length, &buffer[0]);
else {
input.close(); Glib::ustring::iterator iter;
return false; while(!ustr.validate(iter)) {
} auto next_char_iter=iter;
next_char_iter++;
ustr.replace(iter, next_char_iter, "?");
} }
}
text_buffer->insert_at_cursor(ustr); //What if insert happens in the middle of an UTF-8 char???
}*/
input.close(); input.close();
return true; if(valid)
return 1;
else
return -1;
} }
return false; return 0;
} }
//Only use on small files //Only use on small files
@ -70,9 +99,7 @@ bool juci::filesystem::write(const std::string &path, Glib::RefPtr<Gtk::TextBuff
bool end_reached=false; bool end_reached=false;
while(!end_reached) { while(!end_reached) {
for(size_t c=0;c<buffer_size;c++) { for(size_t c=0;c<buffer_size;c++) {
if(end_iter) if(!end_iter.forward_char()) {
end_iter++;
else {
end_reached=true; end_reached=true;
break; break;
} }

4
src/sourcefile.h

@ -10,8 +10,8 @@ namespace juci {
public: public:
static std::string read(const std::string &path); static std::string read(const std::string &path);
static std::string read(const boost::filesystem::path &path) { return read(path.string()); } static std::string read(const boost::filesystem::path &path) { return read(path.string()); }
static bool read(const std::string &path, Glib::RefPtr<Gtk::TextBuffer> text_buffer); static int read(const std::string &path, Glib::RefPtr<Gtk::TextBuffer> text_buffer);
static bool read(const boost::filesystem::path &path, Glib::RefPtr<Gtk::TextBuffer> text_buffer) { return read(path.string(), text_buffer); } static int read(const boost::filesystem::path &path, Glib::RefPtr<Gtk::TextBuffer> text_buffer) { return read(path.string(), text_buffer); }
static std::vector<std::string> read_lines(const std::string &path); static std::vector<std::string> read_lines(const std::string &path);
static std::vector<std::string> read_lines(const boost::filesystem::path &path) { return read_lines(path.string()); }; static std::vector<std::string> read_lines(const boost::filesystem::path &path) { return read_lines(path.string()); };

42
src/terminal.cc

@ -154,6 +154,7 @@ Terminal::Terminal() {
} }
int Terminal::execute(const std::string &command, const boost::filesystem::path &path) { int Terminal::execute(const std::string &command, const boost::filesystem::path &path) {
DEBUG("start");
int stdin_fd, stdout_fd, stderr_fd; int stdin_fd, stdout_fd, stderr_fd;
auto pid=popen3(command, path.string(), &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](){ std::thread stdout_thread([this, stdout_fd](){
char buffer[1024]; char buffer[1024];
ssize_t n; ssize_t n;
INFO("read");
while ((n=read(stdout_fd, buffer, 1024)) > 0) { while ((n=read(stdout_fd, buffer, 1024)) > 0) {
std::string message; std::string message;
for(ssize_t c=0;c<n;c++) 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(stdout_fd);
close(stderr_fd); close(stderr_fd);
DEBUG("end");
return exit_code; return exit_code;
} }
} }
void Terminal::async_execute(const std::string &command, const boost::filesystem::path &path, std::function<void(int exit_code)> callback) { 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](){ std::thread async_execute_thread([this, command, path, callback](){
DEBUG("start");
int stdin_fd, stdout_fd, stderr_fd; int stdin_fd, stdout_fd, stderr_fd;
async_executes_mutex.lock(); async_executes_mutex.lock();
stdin_buffer.clear(); 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](){ std::thread stdout_thread([this, stdout_fd](){
char buffer[1024]; char buffer[1024];
ssize_t n; ssize_t n;
INFO("read");
while ((n=read(stdout_fd, buffer, 1024)) > 0) { while ((n=read(stdout_fd, buffer, 1024)) > 0) {
std::string message; std::string message;
for(ssize_t c=0;c<n;c++) 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) if(callback)
callback(exit_code); callback(exit_code);
DEBUG("end");
} }
}); });
async_execute_thread.detach(); async_execute_thread.detach();
@ -280,15 +283,22 @@ void Terminal::kill_async_executes(bool force) {
} }
int Terminal::print(const std::string &message, bool bold){ int Terminal::print(const std::string &message, bool bold){
INFO("Terminal: PrintMessage"); Glib::ustring umessage=message;
Glib::ustring::iterator iter;
while(!umessage.validate(iter)) {
auto next_char_iter=iter;
next_char_iter++;
umessage.replace(iter, next_char_iter, "?");
}
if(bold) if(bold)
get_buffer()->insert_with_tag(get_buffer()->end(), message, bold_tag); get_buffer()->insert_with_tag(get_buffer()->end(), umessage, bold_tag);
else else
get_buffer()->insert(get_buffer()->end(), message); get_buffer()->insert(get_buffer()->end(), umessage);
auto iter=get_buffer()->end(); auto end_iter=get_buffer()->end();
if(iter.backward_char()) { if(end_iter.backward_char()) {
auto mark=get_buffer()->create_mark(iter); auto mark=get_buffer()->create_mark(end_iter);
scroll_to(mark, 0.0, 1.0, 1.0); scroll_to(mark, 0.0, 1.0, 1.0);
get_buffer()->delete_mark(mark); get_buffer()->delete_mark(mark);
} }
@ -297,11 +307,17 @@ int Terminal::print(const std::string &message, bool bold){
} }
void Terminal::print(int line_nr, const std::string &message){ void Terminal::print(int line_nr, const std::string &message){
INFO("Terminal: PrintMessage at line " << line_nr); Glib::ustring umessage=message;
auto iter=get_buffer()->get_iter_at_line(line_nr); Glib::ustring::iterator iter;
while(!iter.ends_line()) while(!umessage.validate(iter)) {
iter++; auto next_char_iter=iter;
get_buffer()->insert(iter, message); next_char_iter++;
umessage.replace(iter, next_char_iter, "?");
}
auto end_line_iter=get_buffer()->get_iter_at_line(line_nr);
while(!end_line_iter.ends_line() && end_line_iter.forward_char()) {}
get_buffer()->insert(end_line_iter, umessage);
} }
std::shared_ptr<Terminal::InProgress> Terminal::print_in_progress(std::string start_msg) { std::shared_ptr<Terminal::InProgress> Terminal::print_in_progress(std::string start_msg) {

24
src/tooltips.cc

@ -1,6 +1,9 @@
#include "tooltips.h" #include "tooltips.h"
#include "singletons.h" #include "singletons.h"
#include <iostream>
using namespace std;
namespace sigc { namespace sigc {
#ifndef SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE #ifndef SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE
template <typename Functor> template <typename Functor>
@ -32,12 +35,10 @@ void Tooltip::update() {
auto end_iter=end_mark->get_iter(); auto end_iter=end_mark->get_iter();
text_view.get_iter_location(iter, activation_rectangle); text_view.get_iter_location(iter, activation_rectangle);
if(iter.get_offset()<end_iter.get_offset()) { if(iter.get_offset()<end_iter.get_offset()) {
iter++; while(iter.forward_char() && iter!=end_iter) {
while(iter!=end_iter) {
Gdk::Rectangle rectangle; Gdk::Rectangle rectangle;
text_view.get_iter_location(iter, rectangle); text_view.get_iter_location(iter, rectangle);
activation_rectangle.join(rectangle); activation_rectangle.join(rectangle);
iter++;
} }
} }
int location_window_x, location_window_y; int location_window_x, location_window_y;
@ -96,7 +97,6 @@ void Tooltip::adjust(bool disregard_drawn) {
} }
void Tooltip::wrap_lines(Glib::RefPtr<Gtk::TextBuffer> text_buffer) { void Tooltip::wrap_lines(Glib::RefPtr<Gtk::TextBuffer> text_buffer) {
INFO("Tooltip::wrap_lines");
auto iter=text_buffer->begin(); auto iter=text_buffer->begin();
while(iter) { while(iter) {
@ -111,28 +111,28 @@ void Tooltip::wrap_lines(Glib::RefPtr<Gtk::TextBuffer> text_buffer) {
last_space=iter; last_space=iter;
if(*iter=='\n') { if(*iter=='\n') {
end=true; end=true;
iter++; iter.forward_char();
break; break;
} }
iter++; iter.forward_char();
} }
if(!end) { if(!end) {
while(!last_space && iter) { //If no space (word longer than 80) while(!last_space && iter) { //If no space (word longer than 80)
iter++; iter.forward_char();
if(iter && *iter==' ') if(iter && *iter==' ')
last_space=iter; last_space=iter;
} }
if(iter && last_space) { if(iter && last_space) {
auto mark=text_buffer->create_mark(last_space); auto mark=text_buffer->create_mark(last_space);
auto iter_mark=text_buffer->create_mark(iter); auto last_space_p=last_space;
auto last_space_p=last_space++; last_space.forward_char();
text_buffer->erase(last_space, last_space_p); text_buffer->erase(last_space_p, last_space);
text_buffer->insert(mark->get_iter(), "\n"); text_buffer->insert(mark->get_iter(), "\n");
iter=iter_mark->get_iter(); iter=mark->get_iter();
iter.forward_char();
text_buffer->delete_mark(mark); text_buffer->delete_mark(mark);
text_buffer->delete_mark(iter_mark);
} }
} }
} }

35
src/window.cc

@ -33,7 +33,7 @@ void Window::generate_keybindings() {
} }
Window::Window() : box(Gtk::ORIENTATION_VERTICAL), notebook(directories), compiling(false) { Window::Window() : box(Gtk::ORIENTATION_VERTICAL), notebook(directories), compiling(false) {
INFO("Create Window"); DEBUG("start");
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);
@ -104,9 +104,9 @@ Window::Window() : box(Gtk::ORIENTATION_VERTICAL), notebook(directories), compil
directories.select(notebook.get_current_view()->file_path); directories.select(notebook.get_current_view()->file_path);
if(auto source_view=dynamic_cast<Source::ClangView*>(notebook.get_current_view())) { if(auto source_view=dynamic_cast<Source::ClangView*>(notebook.get_current_view())) {
if(source_view->start_reparse_needed) { if(source_view->reparse_needed) {
source_view->start_reparse(); source_view->start_reparse();
source_view->start_reparse_needed=false; source_view->reparse_needed=false;
} }
} }
@ -132,11 +132,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_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_license_type(Gtk::License::LICENSE_MIT_X11);
about.set_transient_for(*this); about.set_transient_for(*this);
INFO("Window created"); DEBUG("end");
} // Window constructor } // Window constructor
void Window::create_menu() { 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]() { menu.action_group->add(Gtk::Action::create("FileQuit", "Quit juCi++"), Gtk::AccelKey(menu.key_map["quit"]), [this]() {
hide(); hide();
}); });
@ -189,7 +188,6 @@ void Window::create_menu() {
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("EditUndo", "Undo"), Gtk::AccelKey(menu.key_map["edit_undo"]), [this]() {
INFO("On undo");
if(notebook.get_current_page()!=-1) { if(notebook.get_current_page()!=-1) {
auto undo_manager = notebook.get_current_view()->get_source_buffer()->get_undo_manager(); auto undo_manager = notebook.get_current_view()->get_source_buffer()->get_undo_manager();
if (undo_manager->can_undo()) { if (undo_manager->can_undo()) {
@ -197,10 +195,8 @@ void Window::create_menu() {
notebook.get_current_view()->scroll_to(notebook.get_current_view()->get_buffer()->get_insert()); 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]() { 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) { if(notebook.get_current_page()!=-1) {
auto undo_manager = notebook.get_current_view()->get_source_buffer()->get_undo_manager(); auto undo_manager = notebook.get_current_view()->get_source_buffer()->get_undo_manager();
if(undo_manager->can_redo()) { if(undo_manager->can_redo()) {
@ -208,7 +204,6 @@ void Window::create_menu() {
notebook.get_current_view()->scroll_to(notebook.get_current_view()->get_buffer()->get_insert()); 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]() { menu.action_group->add(Gtk::Action::create("SourceGotoLine", "Go to Line"), Gtk::AccelKey(menu.key_map["source_goto_line"]), [this]() {
@ -218,7 +213,8 @@ void Window::create_menu() {
if(notebook.get_current_page()!=-1) { if(notebook.get_current_page()!=-1) {
while(gtk_events_pending()) while(gtk_events_pending())
gtk_main_iteration(); gtk_main_iteration();
notebook.get_current_view()->scroll_to(notebook.get_current_view()->get_buffer()->get_insert(), 0.0, 1.0, 0.5); if(notebook.get_current_page()!=-1)
notebook.get_current_view()->scroll_to(notebook.get_current_view()->get_buffer()->get_insert(), 0.0, 1.0, 0.5);
} }
}); });
menu.action_group->add(Gtk::Action::create("SourceGotoDeclaration", "Go to Declaration"), Gtk::AccelKey(menu.key_map["source_goto_declaration"]), [this]() { menu.action_group->add(Gtk::Action::create("SourceGotoDeclaration", "Go to Declaration"), Gtk::AccelKey(menu.key_map["source_goto_declaration"]), [this]() {
@ -230,7 +226,8 @@ void Window::create_menu() {
notebook.get_current_view()->get_buffer()->place_cursor(notebook.get_current_view()->get_buffer()->get_iter_at_line_index(location.second.line-1, location.second.index-1)); notebook.get_current_view()->get_buffer()->place_cursor(notebook.get_current_view()->get_buffer()->get_iter_at_line_index(location.second.line-1, location.second.index-1));
while(gtk_events_pending()) while(gtk_events_pending())
gtk_main_iteration(); gtk_main_iteration();
notebook.get_current_view()->scroll_to(notebook.get_current_view()->get_buffer()->get_insert(), 0.0, 1.0, 0.5); if(notebook.get_current_page()!=-1)
notebook.get_current_view()->scroll_to(notebook.get_current_view()->get_buffer()->get_insert(), 0.0, 1.0, 0.5);
} }
} }
} }
@ -325,6 +322,10 @@ void Window::create_menu() {
}); });
menu.action_group->add(Gtk::Action::create("WindowCloseTab", "Close Tab"), Gtk::AccelKey(menu.key_map["close_tab"]), [this]() { menu.action_group->add(Gtk::Action::create("WindowCloseTab", "Close Tab"), Gtk::AccelKey(menu.key_map["close_tab"]), [this]() {
notebook.close_current_page(); notebook.close_current_page();
if(notebook.get_current_page()!=-1)
Singleton::status()->set_text(notebook.get_current_view()->status);
else
Singleton::status()->set_text("");
}); });
menu.action_group->add(Gtk::Action::create("HelpAbout", "About"), [this] () { menu.action_group->add(Gtk::Action::create("HelpAbout", "About"), [this] () {
about.show(); about.show();
@ -332,7 +333,6 @@ void Window::create_menu() {
}); });
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")
} }
bool Window::on_key_press_event(GdkEventKey *event) { bool Window::on_key_press_event(GdkEventKey *event) {
@ -526,7 +526,6 @@ void Window::open_file_dialog() {
void Window::save_file_dialog() { void Window::save_file_dialog() {
if(notebook.get_current_page()==-1) if(notebook.get_current_page()==-1)
return; return;
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.get_current_view()->file_path.string().c_str()); 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.set_position(Gtk::WindowPosition::WIN_POS_CENTER_ALWAYS);
@ -652,7 +651,8 @@ void Window::goto_line_entry() {
buffer->place_cursor(buffer->get_iter_at_line(line)); buffer->place_cursor(buffer->get_iter_at_line(line));
while(gtk_events_pending()) while(gtk_events_pending())
gtk_main_iteration(); gtk_main_iteration();
notebook.get_current_view()->scroll_to(buffer->get_insert(), 0.0, 1.0, 0.5); if(notebook.get_current_page()!=-1)
notebook.get_current_view()->scroll_to(buffer->get_insert(), 0.0, 1.0, 0.5);
} }
} }
catch(const std::exception &e) {} catch(const std::exception &e) {}
@ -688,10 +688,11 @@ void Window::rename_token_entry() {
entry_box.entries.emplace_back(*token_name, [this, token_name, token](const std::string& content){ entry_box.entries.emplace_back(*token_name, [this, token_name, token](const std::string& content){
if(notebook.get_current_page()!=-1 && content!=*token_name) { if(notebook.get_current_page()!=-1 && content!=*token_name) {
for(int c=0;c<notebook.size();c++) { for(int c=0;c<notebook.size();c++) {
if(notebook.get_view(c)->rename_similar_tokens) { auto view=notebook.get_view(c);
auto number=notebook.get_view(c)->rename_similar_tokens(*token, content); if(view->rename_similar_tokens) {
auto number=view->rename_similar_tokens(*token, content);
if(number>0) { if(number>0) {
Singleton::terminal()->print("Replaced "+boost::lexical_cast<std::string>(number)+" occurrences in file "+notebook.get_view(c)->file_path.string()+"\n"); Singleton::terminal()->print("Replaced "+boost::lexical_cast<std::string>(number)+" occurrences in file "+view->file_path.string()+"\n");
notebook.save(c); notebook.save(c);
} }
} }

Loading…
Cancel
Save