Browse Source

Label with the number of search matches addes as well as case sensitive and regex toggle buttons. Some minor fixes too.

merge-requests/365/head
eidheim 11 years ago
parent
commit
7ca29d8396
  1. 30
      juci/entrybox.cc
  2. 15
      juci/entrybox.h
  3. 169
      juci/notebook.cc
  4. 5
      juci/notebook.h
  5. 12
      juci/source.cc
  6. 3
      juci/source.h

30
juci/entrybox.cc

@ -20,24 +20,44 @@ EntryBox::Button::Button(const std::string& label, std::function<void()> on_acti
});
}
EntryBox::EntryBox() : Gtk::Box(Gtk::ORIENTATION_HORIZONTAL) {}
EntryBox::ToggleButton::ToggleButton(const std::string& label, std::function<void()> on_activate) : Gtk::ToggleButton(label), on_activate(on_activate) {
signal_clicked().connect([this](){
if(this->on_activate)
this->on_activate();
});
}
EntryBox::Label::Label(std::function<void(int state, const std::string& message)> update) : Gtk::Label(), update(update) {
if(this->update)
this->update(-1, "");
}
EntryBox::EntryBox() : Gtk::Box(Gtk::ORIENTATION_VERTICAL), upper_box(Gtk::ORIENTATION_HORIZONTAL), lower_box(Gtk::ORIENTATION_HORIZONTAL) {
pack_start(upper_box, Gtk::PACK_SHRINK);
pack_start(lower_box, Gtk::PACK_SHRINK);
}
void EntryBox::clear() {
hide();
entries.clear();
buttons.clear();
toggle_buttons.clear();
labels.clear();
}
void EntryBox::show() {
std::vector<Gtk::Widget*> focus_chain;
for(auto& entry: entries) {
pack_start(entry, Gtk::PACK_SHRINK);
upper_box.pack_start(entry, Gtk::PACK_SHRINK);
focus_chain.emplace_back(&entry);
}
for(auto& button: buttons)
pack_start(button, Gtk::PACK_SHRINK);
set_focus_chain(focus_chain);
upper_box.pack_start(button, Gtk::PACK_SHRINK);
for(auto& toggle_button: toggle_buttons)
upper_box.pack_start(toggle_button, Gtk::PACK_SHRINK);
for(auto& label: labels)
lower_box.pack_start(label, Gtk::PACK_SHRINK);
upper_box.set_focus_chain(focus_chain);
show_all();
if(entries.size()>0) {
entries.begin()->grab_focus();

15
juci/entrybox.h

@ -17,12 +17,27 @@ public:
Button(const std::string& label, std::function<void()> on_activate=nullptr);
std::function<void()> on_activate;
};
class ToggleButton : public Gtk::ToggleButton {
public:
ToggleButton(const std::string& label, std::function<void()> on_activate=nullptr);
std::function<void()> on_activate;
};
class Label : public Gtk::Label {
public:
Label(std::function<void(int state, const std::string& message)> update=nullptr);
std::function<void(int state, const std::string& message)> update;
};
public:
EntryBox();
Gtk::Box upper_box;
Gtk::Box lower_box;
void clear();
void show();
std::list<Entry> entries;
std::list<Button> buttons;
std::list<ToggleButton> toggle_buttons;
std::list<Label> labels;
};
#endif // JUCI_ENTRYBOX_H_

169
juci/notebook.cc

@ -27,8 +27,10 @@ Notebook::Controller::Controller() :
}
});
view.notebook.signal_switch_page().connect([this](Gtk::Widget* page, guint page_num) {
if(search_entry_shown && CurrentPage()!=-1)
CurrentSourceView()->search_highlight(last_search);
if(search_entry_shown && entry_box.labels.size()>0 && CurrentPage()!=-1) {
CurrentSourceView()->search_highlight(last_search, case_sensitive_search, regex_search);
entry_box.labels.back().update(0, std::to_string(CurrentSourceView()->get_search_occurences()));
}
});
INFO("Notebook Controller Success");
} // Constructor
@ -48,65 +50,7 @@ void Notebook::Controller::CreateKeybindings() {
OnCloseCurrentPage();
});
menu->action_group->add(Gtk::Action::create("EditFind", "Find"), Gtk::AccelKey(menu->key_map["edit_find"]), [this]() {
entry_box.clear();
entry_box.entries.emplace_back(last_search, [this](const std::string& content){
if(CurrentPage()!=-1)
CurrentSourceView()->search_forward();
});
auto search_entry_it=entry_box.entries.begin();
search_entry_it->set_placeholder_text("Find");
if(CurrentPage()!=-1)
CurrentSourceView()->search_highlight(search_entry_it->get_text());
search_entry_it->signal_key_press_event().connect([this](GdkEventKey* event){
if(event->keyval==GDK_KEY_Return && event->state==GDK_SHIFT_MASK) {
if(CurrentPage()!=-1)
CurrentSourceView()->search_backward();
}
return false;
});
search_entry_it->signal_changed().connect([this, search_entry_it](){
last_search=search_entry_it->get_text();
if(CurrentPage()!=-1)
CurrentSourceView()->search_highlight(search_entry_it->get_text());
});
entry_box.entries.emplace_back(last_replace, [this](const std::string &content){
if(CurrentPage()!=-1)
CurrentSourceView()->replace_forward(content);
});
auto replace_entry_it=entry_box.entries.begin();
replace_entry_it++;
replace_entry_it->set_placeholder_text("Replace");
replace_entry_it->signal_key_press_event().connect([this, replace_entry_it](GdkEventKey* event){
if(event->keyval==GDK_KEY_Return && event->state==GDK_SHIFT_MASK) {
if(CurrentPage()!=-1)
CurrentSourceView()->replace_backward(replace_entry_it->get_text());
}
return false;
});
replace_entry_it->signal_changed().connect([this, replace_entry_it](){
last_replace=replace_entry_it->get_text();
});
entry_box.buttons.emplace_back("Find", [this](){
if(CurrentPage()!=-1)
CurrentSourceView()->search_forward();
});
entry_box.buttons.emplace_back("Replace", [this, replace_entry_it](){
if(CurrentPage()!=-1)
CurrentSourceView()->replace_forward(replace_entry_it->get_text());
});
entry_box.buttons.emplace_back("Replace all", [this, replace_entry_it](){
if(CurrentPage()!=-1)
CurrentSourceView()->replace_all(replace_entry_it->get_text());
});
entry_box.signal_hide().connect([this]() {
for(int c=0;c<Pages();c++)
source_views.at(c)->view->search_highlight("");
search_entry_shown=false;
});
search_entry_shown=true;
entry_box.show();
show_search_and_replace();
});
menu->action_group->add(Gtk::Action::create("EditCopy", "Copy"), Gtk::AccelKey(menu->key_map["edit_copy"]), [this]() {
if (Pages() != 0) {
@ -167,6 +111,103 @@ void Notebook::Controller::CreateKeybindings() {
INFO("Notebook signal handlers sucsess");
}
void Notebook::Controller::show_search_and_replace() {
entry_box.clear();
entry_box.labels.emplace_back();
auto label_it=entry_box.labels.begin();
label_it->update=[this, label_it](int state, const std::string& message){
if(state==0) {
int number=stoi(message);
if(number<1)
label_it->set_text("");
else if(number==1)
label_it->set_text("1 result found");
else
label_it->set_text(std::to_string(number)+" results found");
}
};
entry_box.entries.emplace_back(last_search, [this](const std::string& content){
if(CurrentPage()!=-1)
CurrentSourceView()->search_forward();
});
auto search_entry_it=entry_box.entries.begin();
search_entry_it->set_placeholder_text("Find");
if(CurrentPage()!=-1) {
CurrentSourceView()->search_highlight(search_entry_it->get_text(), case_sensitive_search, regex_search);
label_it->update(0, std::to_string(CurrentSourceView()->get_search_occurences()));
}
search_entry_it->signal_key_press_event().connect([this](GdkEventKey* event){
if(event->keyval==GDK_KEY_Return && event->state==GDK_SHIFT_MASK) {
if(CurrentPage()!=-1)
CurrentSourceView()->search_backward();
}
return false;
});
search_entry_it->signal_changed().connect([this, search_entry_it, label_it](){
last_search=search_entry_it->get_text();
if(CurrentPage()!=-1) {
CurrentSourceView()->search_highlight(search_entry_it->get_text(), case_sensitive_search, regex_search);
label_it->update(0, std::to_string(CurrentSourceView()->get_search_occurences()));
}
});
entry_box.entries.emplace_back(last_replace, [this, label_it](const std::string &content){
if(CurrentPage()!=-1)
CurrentSourceView()->replace_forward(content);
});
auto replace_entry_it=entry_box.entries.begin();
replace_entry_it++;
replace_entry_it->set_placeholder_text("Replace");
replace_entry_it->signal_key_press_event().connect([this, replace_entry_it](GdkEventKey* event){
if(event->keyval==GDK_KEY_Return && event->state==GDK_SHIFT_MASK) {
if(CurrentPage()!=-1)
CurrentSourceView()->replace_backward(replace_entry_it->get_text());
}
return false;
});
replace_entry_it->signal_changed().connect([this, replace_entry_it](){
last_replace=replace_entry_it->get_text();
});
entry_box.buttons.emplace_back("Find", [this](){
if(CurrentPage()!=-1)
CurrentSourceView()->search_forward();
});
entry_box.buttons.emplace_back("Replace", [this, replace_entry_it](){
if(CurrentPage()!=-1)
CurrentSourceView()->replace_forward(replace_entry_it->get_text());
});
entry_box.buttons.emplace_back("Replace all", [this, replace_entry_it, label_it](){
if(CurrentPage()!=-1) {
CurrentSourceView()->replace_all(replace_entry_it->get_text());
label_it->update(0, std::to_string(CurrentSourceView()->get_search_occurences()));
}
});
entry_box.toggle_buttons.emplace_back("Match case");
entry_box.toggle_buttons.back().set_active(case_sensitive_search);
entry_box.toggle_buttons.back().on_activate=[this, search_entry_it, label_it](){
case_sensitive_search=!case_sensitive_search;
if(CurrentPage()!=-1) {
CurrentSourceView()->search_highlight(search_entry_it->get_text(), case_sensitive_search, regex_search);
label_it->update(0, std::to_string(CurrentSourceView()->get_search_occurences()));
}
};
entry_box.toggle_buttons.emplace_back("Use regex", [this, search_entry_it, label_it](){
regex_search=!regex_search;
if(CurrentPage()!=-1) {
CurrentSourceView()->search_highlight(search_entry_it->get_text(), case_sensitive_search, regex_search);
label_it->update(0, std::to_string(CurrentSourceView()->get_search_occurences()));
}
});
entry_box.signal_hide().connect([this]() {
for(int c=0;c<Pages();c++)
source_views.at(c)->view->search_highlight("", case_sensitive_search, regex_search);
search_entry_shown=false;
});
search_entry_shown=true;
entry_box.show();
}
void Notebook::Controller::open_file(std::string path) {
INFO("Notebook open file");
INFO("Notebook create page");
@ -197,6 +238,12 @@ void Notebook::Controller::open_file(std::string path) {
title+="*";
view.notebook.set_tab_label_text(*(view.notebook.get_nth_page(CurrentPage())), title);
});
auto this_view=CurrentSourceView();
CurrentSourceView()->get_buffer()->signal_end_user_action().connect([this, this_view](){
if(this_view==CurrentSourceView() && search_entry_shown && entry_box.labels.size()>0) {
entry_box.labels.back().update(0, std::to_string(this_view->get_search_occurences()));
}
});
}
void Notebook::Controller::OnCloseCurrentPage() {

5
juci/notebook.h

@ -35,10 +35,15 @@ namespace Notebook {
std::string OnSaveFileAs();
std::string project_path;
Directories::Controller directories; //Todo: make private after creating open_directory()
EntryBox entry_box;
void show_search_and_replace();
std::string last_search;
std::string last_replace;
bool case_sensitive_search=true;
bool regex_search=false;
bool search_entry_shown=false;
std::vector<std::unique_ptr<Source> > source_views;
private:
void CreateKeybindings();

12
juci/source.cc

@ -74,13 +74,17 @@ Source::View::~View() {
g_clear_object(&search_settings);
}
void Source::View::search_highlight(const std::string &text) {
if(text.size()>0) {
void Source::View::search_highlight(const std::string &text, bool case_sensitive, bool regex) {
gtk_source_search_settings_set_case_sensitive(search_settings, case_sensitive);
gtk_source_search_settings_set_regex_enabled(search_settings, regex);
gtk_source_search_settings_set_search_text(search_settings, text.c_str());
gtk_source_search_context_set_highlight(search_context, true);
}
else
gtk_source_search_context_set_highlight(search_context, false);
int Source::View::get_search_occurences() {
while(gtk_events_pending())
gtk_main_iteration();
return gtk_source_search_context_get_occurrences_count(search_context);
}
void Source::View::search_forward() {

3
juci/source.h

@ -50,7 +50,8 @@ public:
View(const std::string& file_path, const std::string& project_path);
~View();
void search_highlight(const std::string &text);
void search_highlight(const std::string &text, bool case_sensitive, bool regex);
int get_search_occurences();
void search_forward();
void search_backward();
void replace_forward(const std::string &replacement);

Loading…
Cancel
Save