Browse Source

Merge remote-tracking branch 'origin/master' into little_fixes

merge-requests/365/head
Vadim 10 years ago
parent
commit
1c4454b6ea
  1. 6
      src/dialogs.cc
  2. 5
      src/dialogs_win.cc
  3. 23
      src/directories.cc
  4. 63
      src/selectiondialog.cc
  5. 25
      src/selectiondialog.h
  6. 17
      src/source.cc
  7. 62
      src/source_clang.cc
  8. 13
      src/window.cc

6
src/dialogs.cc

@ -42,9 +42,11 @@ std::string Dialog::gtk_dialog(const std::string &title,
dialog.set_transient_for(*application->window); dialog.set_transient_for(*application->window);
auto current_path=application->window->notebook.get_current_folder(); auto current_path=application->window->notebook.get_current_folder();
boost::system::error_code ec;
if(current_path.empty()) if(current_path.empty())
current_path=boost::filesystem::current_path(); current_path=boost::filesystem::current_path(ec);
gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), current_path.string().c_str()); if(!ec)
gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), current_path.string().c_str());
if (!file_name.empty()) if (!file_name.empty())
gtk_file_chooser_set_filename((GtkFileChooser*)dialog.gobj(), file_name.c_str()); gtk_file_chooser_set_filename((GtkFileChooser*)dialog.gobj(), file_name.c_str());

5
src/dialogs_win.cc

@ -99,8 +99,11 @@ private:
auto application=Glib::RefPtr<Application>::cast_static(gio_application); auto application=Glib::RefPtr<Application>::cast_static(gio_application);
auto current_path=application->window->notebook.get_current_folder(); auto current_path=application->window->notebook.get_current_folder();
boost::system::error_code ec;
if(current_path.empty()) if(current_path.empty())
current_path=boost::filesystem::current_path(); current_path=boost::filesystem::current_path(ec);
if(ec)
return false;
std::wstring path=current_path.native(); std::wstring path=current_path.native();
size_t pos=0; size_t pos=0;

23
src/directories.cc

@ -90,19 +90,16 @@ Directories::Directories() : stop_update_thread(false) {
update_mutex.lock(); update_mutex.lock();
if(update_paths.size()==0) { if(update_paths.size()==0) {
for(auto it=last_write_times.begin();it!=last_write_times.end();) { for(auto it=last_write_times.begin();it!=last_write_times.end();) {
try { boost::system::error_code ec;
if(boost::filesystem::exists(it->first)) { //Added for older boost versions (no exception thrown) auto last_write_time=boost::filesystem::last_write_time(it->first, ec);
if(it->second.second<boost::filesystem::last_write_time(it->first)) { if(!ec) {
update_paths.emplace_back(it->first); if(it->second.second<last_write_time) {
} update_paths.emplace_back(it->first);
it++;
} }
else it++;
it=last_write_times.erase(it);
} }
catch(const std::exception &e) { else
it=last_write_times.erase(it); it=last_write_times.erase(it);
}
} }
if(update_paths.size()>0) if(update_paths.size()>0)
update_dispatcher(); update_dispatcher();
@ -198,7 +195,11 @@ void Directories::select(const boost::filesystem::path &path) {
} }
void Directories::add_path(const boost::filesystem::path& dir_path, const Gtk::TreeModel::Row &parent) { void Directories::add_path(const boost::filesystem::path& dir_path, const Gtk::TreeModel::Row &parent) {
last_write_times[dir_path.string()]={parent, boost::filesystem::last_write_time(dir_path)}; boost::system::error_code ec;
auto last_write_time=boost::filesystem::last_write_time(dir_path, ec);
if(ec)
return;
last_write_times[dir_path.string()]={parent, last_write_time};
std::unique_ptr<Gtk::TreeNodeChildren> children; //Gtk::TreeNodeChildren is missing default constructor... std::unique_ptr<Gtk::TreeNodeChildren> children; //Gtk::TreeNodeChildren is missing default constructor...
if(parent) if(parent)
children=std::unique_ptr<Gtk::TreeNodeChildren>(new Gtk::TreeNodeChildren(parent.children())); children=std::unique_ptr<Gtk::TreeNodeChildren>(new Gtk::TreeNodeChildren(parent.children()));

63
src/selectiondialog.cc

@ -15,8 +15,36 @@ namespace sigc {
#endif #endif
} }
SelectionDialogBase::SelectionDialogBase(Gtk::TextView& text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark, bool show_search_entry): text_view(text_view), ListViewText::ListViewText(bool use_markup) : Gtk::TreeView(), use_markup(use_markup) {
start_mark(start_mark), show_search_entry(show_search_entry), list_view_text(1, false, Gtk::SelectionMode::SELECTION_BROWSE) { list_store = Gtk::ListStore::create(column_record);
set_model(list_store);
append_column("", cell_renderer);
if(use_markup)
get_column(0)->add_attribute(cell_renderer.property_markup(), column_record.text);
else
get_column(0)->add_attribute(cell_renderer.property_text(), column_record.text);
get_selection()->set_mode(Gtk::SelectionMode::SELECTION_BROWSE);
set_enable_search(true);
set_headers_visible(false);
set_hscroll_policy(Gtk::ScrollablePolicy::SCROLL_NATURAL);
set_activate_on_single_click(true);
set_hover_selection(false);
set_rules_hint(true);
}
void ListViewText::ListViewText::append(const std::string& value) {
auto new_row=list_store->append();
new_row->set_value(column_record.text, value);
}
void ListViewText::ListViewText::hide() {
Gtk::TreeView::hide();
list_store->clear();
}
SelectionDialogBase::SelectionDialogBase(Gtk::TextView& text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark, bool show_search_entry, bool use_markup): text_view(text_view),
list_view_text(use_markup), start_mark(start_mark), show_search_entry(show_search_entry) {
if(!show_search_entry) if(!show_search_entry)
window=std::unique_ptr<Gtk::Window>(new Gtk::Window(Gtk::WindowType::WINDOW_POPUP)); window=std::unique_ptr<Gtk::Window>(new Gtk::Window(Gtk::WindowType::WINDOW_POPUP));
else else
@ -27,13 +55,6 @@ start_mark(start_mark), show_search_entry(show_search_entry), list_view_text(1,
window->property_decorated()=false; window->property_decorated()=false;
window->set_skip_taskbar_hint(true); window->set_skip_taskbar_hint(true);
scrolled_window.set_policy(Gtk::PolicyType::POLICY_AUTOMATIC, Gtk::PolicyType::POLICY_AUTOMATIC); scrolled_window.set_policy(Gtk::PolicyType::POLICY_AUTOMATIC, Gtk::PolicyType::POLICY_AUTOMATIC);
list_view_text.set_enable_search(true);
list_view_text.set_headers_visible(false);
list_view_text.set_hscroll_policy(Gtk::ScrollablePolicy::SCROLL_NATURAL);
list_view_text.set_activate_on_single_click(true);
list_view_text.set_hover_selection(false);
list_view_text.set_rules_hint(true);
//list_view_text.set_fixed_height_mode(true); //TODO: This is buggy on OS X, remember to post an issue on GTK+ 3
list_view_text.signal_realize().connect([this](){ list_view_text.signal_realize().connect([this](){
resize(); resize();
@ -89,8 +110,8 @@ void SelectionDialogBase::hide() {
} }
void SelectionDialogBase::update_tooltips() { void SelectionDialogBase::update_tooltips() {
if(list_view_text.get_selected().size()>0) { auto it=list_view_text.get_selection()->get_selected();
auto it=list_view_text.get_selection()->get_selected(); if(it) {
std::string row; std::string row;
it->get_value(0, row); it->get_value(0, row);
if(row!=last_row || last_row.size()==0) { if(row!=last_row || last_row.size()==0) {
@ -155,7 +176,7 @@ void SelectionDialogBase::resize() {
} }
} }
SelectionDialog::SelectionDialog(Gtk::TextView& text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark, bool show_search_entry) : SelectionDialogBase(text_view, start_mark, show_search_entry) {} SelectionDialog::SelectionDialog(Gtk::TextView& text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark, bool show_search_entry, bool use_markup) : SelectionDialogBase(text_view, start_mark, show_search_entry, use_markup) {}
void SelectionDialog::show() { void SelectionDialog::show() {
SelectionDialogBase::show(); SelectionDialogBase::show();
@ -168,6 +189,14 @@ void SelectionDialog::show() {
auto search_key_lc=*search_key; auto search_key_lc=*search_key;
std::transform(row_lc.begin(), row_lc.end(), row_lc.begin(), ::tolower); std::transform(row_lc.begin(), row_lc.end(), row_lc.begin(), ::tolower);
std::transform(search_key_lc.begin(), search_key_lc.end(), search_key_lc.begin(), ::tolower); std::transform(search_key_lc.begin(), search_key_lc.end(), search_key_lc.begin(), ::tolower);
if(list_view_text.use_markup) {
size_t pos=0;
while((pos=row_lc.find('<', pos))!=std::string::npos) {
auto pos2=row_lc.find('>', pos+1);
row_lc.erase(pos, pos2-pos+1);
}
search_key_lc=Glib::Markup::escape_text(search_key_lc);
}
if(row_lc.find(search_key_lc)!=std::string::npos) if(row_lc.find(search_key_lc)!=std::string::npos)
return true; return true;
return false; return false;
@ -221,8 +250,8 @@ void SelectionDialog::show() {
}); });
auto activate=[this](){ auto activate=[this](){
if(on_select && list_view_text.get_selected().size()>0) { auto it=list_view_text.get_selection()->get_selected();
auto it=list_view_text.get_selection()->get_selected(); if(on_select && it) {
std::string row; std::string row;
it->get_value(0, row); it->get_value(0, row);
on_select(row, true); on_select(row, true);
@ -288,7 +317,7 @@ bool SelectionDialog::on_key_press(GdkEventKey* key) {
return false; return false;
} }
CompletionDialog::CompletionDialog(Gtk::TextView& text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark) : SelectionDialogBase(text_view, start_mark, false) {} CompletionDialog::CompletionDialog(Gtk::TextView& text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark) : SelectionDialogBase(text_view, start_mark, false, false) {}
void CompletionDialog::show() { void CompletionDialog::show() {
SelectionDialogBase::show(); SelectionDialogBase::show();
@ -344,8 +373,8 @@ void CompletionDialog::show() {
void CompletionDialog::select(bool hide_window) { void CompletionDialog::select(bool hide_window) {
row_in_entry=true; row_in_entry=true;
if(list_view_text.get_selected().size()>0) { auto it=list_view_text.get_selection()->get_selected();
auto it=list_view_text.get_selection()->get_selected(); if(it) {
std::string row; std::string row;
it->get_value(0, row); it->get_value(0, row);
if(on_select) if(on_select)

25
src/selectiondialog.h

@ -6,9 +6,28 @@
#include "tooltips.h" #include "tooltips.h"
#include <unordered_map> #include <unordered_map>
class ListViewText : public Gtk::TreeView {
class ColumnRecord : public Gtk::TreeModel::ColumnRecord {
public:
ColumnRecord() {
add(text);
}
Gtk::TreeModelColumn<std::string> text;
};
public:
bool use_markup;
ListViewText(bool use_markup);
void append(const std::string& value);
void hide();
private:
Glib::RefPtr<Gtk::ListStore> list_store;
ColumnRecord column_record;
Gtk::CellRendererText cell_renderer;
};
class SelectionDialogBase { class SelectionDialogBase {
public: public:
SelectionDialogBase(Gtk::TextView& text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark, bool show_search_entry); SelectionDialogBase(Gtk::TextView& text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark, bool show_search_entry, bool use_markup);
~SelectionDialogBase(); ~SelectionDialogBase();
virtual void add_row(const std::string& row, const std::string& tooltip=""); virtual void add_row(const std::string& row, const std::string& tooltip="");
virtual void show(); virtual void show();
@ -25,7 +44,7 @@ protected:
std::unique_ptr<Gtk::Window> window; std::unique_ptr<Gtk::Window> window;
Gtk::ScrolledWindow scrolled_window; Gtk::ScrolledWindow scrolled_window;
Gtk::ListViewText list_view_text; ListViewText list_view_text;
Gtk::Entry search_entry; Gtk::Entry search_entry;
bool show_search_entry; bool show_search_entry;
std::unique_ptr<Tooltips> tooltips; std::unique_ptr<Tooltips> tooltips;
@ -37,7 +56,7 @@ private:
class SelectionDialog : public SelectionDialogBase { class SelectionDialog : public SelectionDialogBase {
public: public:
SelectionDialog(Gtk::TextView& text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark, bool show_search_entry=true); SelectionDialog(Gtk::TextView& text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark, bool show_search_entry=true, bool use_markup=false);
bool on_key_press(GdkEventKey* key); bool on_key_press(GdkEventKey* key);
void show(); void show();
}; };

17
src/source.cc

@ -371,8 +371,10 @@ void Source::View::configure() {
note_tag->property_foreground()=style->property_foreground(); note_tag->property_foreground()=style->property_foreground();
} }
if(Singleton::config->source.spellcheck_language.size()>0) if(Singleton::config->source.spellcheck_language.size()>0) {
aspell_config_replace(spellcheck_config, "lang", Singleton::config->source.spellcheck_language.c_str()); aspell_config_replace(spellcheck_config, "lang", Singleton::config->source.spellcheck_language.c_str());
aspell_config_replace(spellcheck_config, "encoding", "utf-8");
}
spellcheck_possible_err=new_aspell_speller(spellcheck_config); spellcheck_possible_err=new_aspell_speller(spellcheck_config);
if(spellcheck_checker!=NULL) if(spellcheck_checker!=NULL)
delete_aspell_speller(spellcheck_checker); delete_aspell_speller(spellcheck_checker);
@ -533,10 +535,13 @@ void Source::View::replace_all(const std::string &replacement) {
void Source::View::paste() { void Source::View::paste() {
std::string text=Gtk::Clipboard::get()->wait_for_text(); std::string text=Gtk::Clipboard::get()->wait_for_text();
//remove carriage returns (which leads to crash) //Replace carriage returns (which leads to crash) with newlines
for(auto it=text.begin();it!=text.end();it++) { for(size_t c=0;c<text.size();c++) {
if(*it=='\r') { if(text[c]=='\r') {
it=text.erase(it); if((c+1)<text.size() && text[c+1]=='\n')
text.replace(c, 2, "\n");
else
text.replace(c, 1, "\n");
} }
} }
@ -655,6 +660,8 @@ void Source::View::set_info(const std::string &info) {
} }
void Source::View::spellcheck(const Gtk::TextIter& start, const Gtk::TextIter& end) { void Source::View::spellcheck(const Gtk::TextIter& start, const Gtk::TextIter& end) {
if(spellcheck_checker==NULL)
return;
auto iter=start; auto iter=start;
while(iter && iter<end) { while(iter && iter<end) {
if(is_word_iter(iter)) { if(is_word_iter(iter)) {

62
src/source_clang.cc

@ -1059,13 +1059,36 @@ Source::ClangViewAutocomplete(file_path, project_path, language) {
(token.language->get_id()=="chdr" || token.language->get_id()=="cpphdr" || token.language->get_id()=="c" || token.language->get_id()=="cpp" || token.language->get_id()=="objc")) { (token.language->get_id()=="chdr" || token.language->get_id()=="cpphdr" || token.language->get_id()=="c" || token.language->get_id()=="cpp" || token.language->get_id()=="objc")) {
auto offsets=clang_tokens->get_similar_token_offsets(static_cast<clang::CursorKind>(token.type), token.spelling, token.usr); auto offsets=clang_tokens->get_similar_token_offsets(static_cast<clang::CursorKind>(token.type), token.spelling, token.usr);
for(auto &offset: offsets) { for(auto &offset: offsets) {
size_t whitespaces_removed=0;
auto start_iter=get_buffer()->get_iter_at_line(offset.first.line-1); auto start_iter=get_buffer()->get_iter_at_line(offset.first.line-1);
while(!start_iter.ends_line() && (*start_iter==' ' || *start_iter=='\t')) while(!start_iter.ends_line() && (*start_iter==' ' || *start_iter=='\t')) {
start_iter.forward_char(); start_iter.forward_char();
whitespaces_removed++;
}
auto end_iter=start_iter; auto end_iter=start_iter;
while(!end_iter.ends_line()) while(!end_iter.ends_line())
end_iter.forward_char(); end_iter.forward_char();
usages.emplace_back(Offset(offset.first.line-1, offset.first.index-1, this->file_path), get_buffer()->get_text(start_iter, end_iter)); std::string line=Glib::Markup::escape_text(get_buffer()->get_text(start_iter, end_iter));
//markup token as bold
size_t token_start_pos=offset.first.index-1-whitespaces_removed;
size_t token_end_pos=offset.second.index-1-whitespaces_removed;
size_t pos=0;
while((pos=line.find('&', pos))!=std::string::npos) {
size_t pos2=line.find(';', pos+2);
if(token_start_pos>pos) {
token_start_pos+=pos2-pos;
token_end_pos+=pos2-pos;
}
else if(token_end_pos>pos)
token_end_pos+=pos2-pos;
else
break;
pos=pos2+1;
}
line.insert(token_end_pos, "</b>");
line.insert(token_start_pos, "<b>");
usages.emplace_back(Offset(offset.first.line-1, offset.first.index-1, this->file_path), line);
} }
} }
@ -1083,14 +1106,43 @@ Source::ClangViewAutocomplete(file_path, project_path, language) {
if(!visible_rect.intersects(iter_rect)) { if(!visible_rect.intersects(iter_rect)) {
get_iter_at_location(iter, 0, visible_rect.get_y()+visible_rect.get_height()/3); get_iter_at_location(iter, 0, visible_rect.get_y()+visible_rect.get_height()/3);
} }
selection_dialog=std::unique_ptr<SelectionDialog>(new SelectionDialog(*this, get_buffer()->create_mark(iter))); selection_dialog=std::unique_ptr<SelectionDialog>(new SelectionDialog(*this, get_buffer()->create_mark(iter), true, true));
auto rows=std::make_shared<std::unordered_map<std::string, clang::Offset> >(); auto rows=std::make_shared<std::unordered_map<std::string, clang::Offset> >();
auto methods=clang_tokens->get_cxx_methods(); auto methods=clang_tokens->get_cxx_methods();
if(methods.size()==0) if(methods.size()==0)
return; return;
for(auto &method: methods) { for(auto &method: methods) {
(*rows)[method.first]=method.second; std::string row=std::to_string(method.second.line)+": "+Glib::Markup::escape_text(method.first);
selection_dialog->add_row(method.first); //Add bold method token
size_t token_end_pos=row.find('(');
if(token_end_pos==0 || token_end_pos==std::string::npos)
continue;
if(token_end_pos>8 && row.substr(token_end_pos-4, 4)=="&gt;") {
token_end_pos-=8;
size_t angle_bracket_count=1;
do {
if(row.substr(token_end_pos-4, 4)=="&gt;") {
angle_bracket_count++;
token_end_pos-=4;
}
else if(row.substr(token_end_pos-4, 4)=="&lt;") {
angle_bracket_count--;
token_end_pos-=4;
}
else
token_end_pos--;
} while(angle_bracket_count>0 && token_end_pos>4);
}
auto pos=token_end_pos;
do {
pos--;
} while(((row[pos]>='a' && row[pos]<='z') ||
(row[pos]>='A' && row[pos]<='Z') ||
(row[pos]>='0' && row[pos]<='9') || row[pos]=='_' || row[pos]=='~') && pos>0);
row.insert(token_end_pos, "</b>");
row.insert(pos+1, "<b>");
(*rows)[row]=method.second;
selection_dialog->add_row(row);
} }
selection_dialog->on_select=[this, rows](const std::string& selected, bool hide_window) { selection_dialog->on_select=[this, rows](const std::string& selected, bool hide_window) {
auto offset=rows->at(selected); auto offset=rows->at(selected);

13
src/window.cc

@ -172,7 +172,9 @@ void Window::set_menu_actions() {
auto time_now=std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); auto time_now=std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
boost::filesystem::path path = Dialog::new_folder(); boost::filesystem::path path = Dialog::new_folder();
if(path!="" && boost::filesystem::exists(path)) { if(path!="" && boost::filesystem::exists(path)) {
if(boost::filesystem::last_write_time(path)>=time_now) { boost::system::error_code ec;
auto last_write_time=boost::filesystem::last_write_time(path, ec);
if(!ec && last_write_time>=time_now) {
if(Singleton::directories->current_path!="") if(Singleton::directories->current_path!="")
Singleton::directories->update(); Singleton::directories->update();
Singleton::terminal->print("New folder "+path.string()+" created.\n"); Singleton::terminal->print("New folder "+path.string()+" created.\n");
@ -425,7 +427,7 @@ void Window::set_menu_actions() {
if(!visible_rect.intersects(iter_rect)) { if(!visible_rect.intersects(iter_rect)) {
current_view->get_iter_at_location(iter, 0, visible_rect.get_y()+visible_rect.get_height()/3); current_view->get_iter_at_location(iter, 0, visible_rect.get_y()+visible_rect.get_height()/3);
} }
current_view->selection_dialog=std::unique_ptr<SelectionDialog>(new SelectionDialog(*current_view, current_view->get_buffer()->create_mark(iter))); current_view->selection_dialog=std::unique_ptr<SelectionDialog>(new SelectionDialog(*current_view, current_view->get_buffer()->create_mark(iter), true, true));
auto rows=std::make_shared<std::unordered_map<std::string, Source::Offset> >(); auto rows=std::make_shared<std::unordered_map<std::string, Source::Offset> >();
//First add usages in current file //First add usages in current file
@ -464,10 +466,7 @@ void Window::set_menu_actions() {
notebook.open(declaration_file); notebook.open(declaration_file);
auto view=notebook.get_current_view(); auto view=notebook.get_current_view();
view->get_buffer()->place_cursor(view->get_buffer()->get_iter_at_line_index(offset.line, offset.index)); view->get_buffer()->place_cursor(view->get_buffer()->get_iter_at_line_index(offset.line, offset.index));
while(g_main_context_pending(NULL)) view->scroll_to(view->get_buffer()->get_insert(), 0.0, 1.0, 0.5);
g_main_context_iteration(NULL, false);
if(notebook.get_current_page()!=-1)
view->scroll_to(view->get_buffer()->get_insert(), 0.0, 1.0, 0.5);
view->delayed_tooltips_connection.disconnect(); view->delayed_tooltips_connection.disconnect();
}; };
current_view->selection_dialog->show(); current_view->selection_dialog->show();
@ -877,7 +876,7 @@ void Window::rename_token_entry() {
if(notebook.get_current_page()!=-1) { if(notebook.get_current_page()!=-1) {
if(notebook.get_current_view()->get_token) { if(notebook.get_current_view()->get_token) {
auto token=std::make_shared<Source::Token>(notebook.get_current_view()->get_token()); auto token=std::make_shared<Source::Token>(notebook.get_current_view()->get_token());
if(token) { if(*token) {
entry_box.labels.emplace_back(); entry_box.labels.emplace_back();
auto label_it=entry_box.labels.begin(); auto label_it=entry_box.labels.begin();
label_it->update=[label_it](int state, const std::string& message){ label_it->update=[label_it](int state, const std::string& message){

Loading…
Cancel
Save