Browse Source

Fixes: #412 : Added Edit->Cut Lines and Edit->Copy Lines. Additionally, successive cut lines now accumulates the clipboard

merge-requests/399/head
eidheim 6 years ago
parent
commit
d641274247
  1. 2
      CMakeLists.txt
  2. 2
      src/files.h
  3. 8
      src/menu.cc
  4. 32
      src/source_base.cc
  5. 4
      src/source_base.h
  6. 91
      src/window.cc

2
CMakeLists.txt

@ -1,7 +1,7 @@
cmake_minimum_required (VERSION 2.8.8) cmake_minimum_required (VERSION 2.8.8)
project(juci) project(juci)
set(JUCI_VERSION "1.4.6.7") set(JUCI_VERSION "1.4.6.8")
set(CPACK_PACKAGE_NAME "jucipp") set(CPACK_PACKAGE_NAME "jucipp")
set(CPACK_PACKAGE_CONTACT "Ole Christian Eidheim <eidheim@gmail.com>") set(CPACK_PACKAGE_CONTACT "Ole Christian Eidheim <eidheim@gmail.com>")

2
src/files.h

@ -87,7 +87,9 @@ const std::string default_config_file = R"RAW({
"edit_undo": "<primary>z", "edit_undo": "<primary>z",
"edit_redo": "<primary><shift>z", "edit_redo": "<primary><shift>z",
"edit_cut": "<primary>x", "edit_cut": "<primary>x",
"edit_cut_lines": "<primary><shift>x",
"edit_copy": "<primary>c", "edit_copy": "<primary>c",
"edit_copy_lines": "<primary><shift>c",
"edit_paste": "<primary>v", "edit_paste": "<primary>v",
"edit_extend_selection": "<primary><shift>a", "edit_extend_selection": "<primary><shift>a",
"edit_shrink_selection": "<primary><shift><alt>a", "edit_shrink_selection": "<primary><shift><alt>a",

8
src/menu.cc

@ -188,10 +188,18 @@ const Glib::ustring menu_xml = R"RAW(<interface>
<attribute name='label' translatable='yes'>_Cut</attribute> <attribute name='label' translatable='yes'>_Cut</attribute>
<attribute name='action'>app.edit_cut</attribute> <attribute name='action'>app.edit_cut</attribute>
</item> </item>
<item>
<attribute name='label' translatable='yes'>_Cut _Lines</attribute>
<attribute name='action'>app.edit_cut_lines</attribute>
</item>
<item> <item>
<attribute name='label' translatable='yes'>_Copy</attribute> <attribute name='label' translatable='yes'>_Copy</attribute>
<attribute name='action'>app.edit_copy</attribute> <attribute name='action'>app.edit_copy</attribute>
</item> </item>
<item>
<attribute name='label' translatable='yes'>_Copy _Lines</attribute>
<attribute name='action'>app.edit_copy_lines</attribute>
</item>
<item> <item>
<attribute name='label' translatable='yes'>_Paste</attribute> <attribute name='label' translatable='yes'>_Paste</attribute>
<attribute name='action'>app.edit_paste</attribute> <attribute name='action'>app.edit_paste</attribute>

32
src/source_base.cc

@ -69,6 +69,15 @@ Source::BaseView::BaseView(const boost::filesystem::path &file_path, const Glib:
rgba.set_rgba(0.5, 0.5, 0.5, 0.4); rgba.set_rgba(0.5, 0.5, 0.5, 0.4);
snippet_argument_tag->property_background_rgba() = rgba; snippet_argument_tag->property_background_rgba() = rgba;
snippet_argument_tag->property_background_set() = true; snippet_argument_tag->property_background_set() = true;
get_buffer()->signal_mark_set().connect([this](const Gtk::TextBuffer::iterator &iter, const Glib::RefPtr<Gtk::TextBuffer::Mark> &mark) {
if(mark->get_name() == "insert")
keep_clipboard = false;
});
get_buffer()->signal_changed().connect([this] {
keep_clipboard = false;
});
} }
Source::BaseView::~BaseView() { Source::BaseView::~BaseView() {
@ -678,6 +687,29 @@ void Source::BaseView::cleanup_whitespace_characters(const Gtk::TextIter &iter)
get_buffer()->erase(start_blank_iter, end_blank_iter); get_buffer()->erase(start_blank_iter, end_blank_iter);
} }
void Source::BaseView::cut() {
if(!get_buffer()->get_has_selection())
cut_line();
else
get_buffer()->cut_clipboard(Gtk::Clipboard::get());
keep_clipboard = true;
}
void Source::BaseView::cut_line() {
Gtk::TextIter start, end;
get_buffer()->get_selection_bounds(start, end);
start = get_buffer()->get_iter_at_line(start.get_line());
if(!end.ends_line())
end.forward_to_line_end();
end.forward_char();
if(keep_clipboard)
Gtk::Clipboard::get()->set_text(Gtk::Clipboard::get()->wait_for_text() + get_buffer()->get_text(start, end));
else
Gtk::Clipboard::get()->set_text(get_buffer()->get_text(start, end));
get_buffer()->erase(start, end);
keep_clipboard = true;
}
void Source::BaseView::paste() { void Source::BaseView::paste() {
if(CompletionDialog::get()) if(CompletionDialog::get())
CompletionDialog::get()->hide(); CompletionDialog::get()->hide();

4
src/source_base.h

@ -66,6 +66,8 @@ namespace Source {
std::string status_branch; std::string status_branch;
std::function<void(int number)> update_search_occurrences; std::function<void(int number)> update_search_occurrences;
void cut();
void cut_line();
void paste(); void paste();
std::string get_selected_text(); std::string get_selected_text();
@ -86,6 +88,8 @@ namespace Source {
GtkSourceSearchSettings *search_settings; GtkSourceSearchSettings *search_settings;
static void search_occurrences_updated(GtkWidget *widget, GParamSpec *property, gpointer data); static void search_occurrences_updated(GtkWidget *widget, GParamSpec *property, gpointer data);
bool keep_clipboard = false;
protected: protected:
std::time_t last_write_time; std::time_t last_write_time;
void monitor_file(); void monitor_file();

91
src/window.cc

@ -481,29 +481,46 @@ void Window::set_menu_actions() {
} }
auto widget = get_focus(); auto widget = get_focus();
if(auto entry = dynamic_cast<Gtk::Entry *>(widget)) if(auto entry = dynamic_cast<Gtk::Entry *>(widget)) {
entry->cut_clipboard(); int start, end;
if(!entry->get_selection_bounds(start, end)) {
Gtk::Clipboard::get()->set_text(entry->get_text());
entry->set_text("");
}
else
entry->cut_clipboard();
}
else if(auto view = dynamic_cast<Gtk::TextView *>(widget)) { else if(auto view = dynamic_cast<Gtk::TextView *>(widget)) {
if(!view->get_editable()) if(!view->get_editable())
return; return;
auto source_view = dynamic_cast<Source::View *>(view); if(auto source_view = dynamic_cast<Source::View *>(view)) {
if(source_view)
source_view->disable_spellcheck = true; source_view->disable_spellcheck = true;
if(!view->get_buffer()->get_has_selection()) { source_view->cut();
auto start = view->get_buffer()->get_iter_at_line(view->get_buffer()->get_insert()->get_iter().get_line()); source_view->disable_spellcheck = false;
auto end = start;
if(!end.ends_line())
end.forward_to_line_end();
end.forward_char();
if(!end.starts_line()) // In case of \r\n
end.forward_char();
Gtk::Clipboard::get()->set_text(view->get_buffer()->get_text(start, end));
view->get_buffer()->erase(start, end);
} }
else }
view->get_buffer()->cut_clipboard(Gtk::Clipboard::get()); });
if(source_view) menu.add_action("edit_cut_lines", [this]() {
// Return if a shown tooltip has selected text
for(auto tooltip : Tooltips::shown_tooltips) {
auto buffer = tooltip->text_buffer;
if(buffer && buffer->get_has_selection())
return;
}
auto widget = get_focus();
if(auto entry = dynamic_cast<Gtk::Entry *>(widget)) {
Gtk::Clipboard::get()->set_text(entry->get_text());
entry->set_text("");
}
else if(auto view = dynamic_cast<Gtk::TextView *>(widget)) {
if(!view->get_editable())
return;
if(auto source_view = dynamic_cast<Source::View *>(view)) {
source_view->disable_spellcheck = true;
source_view->cut_line();
source_view->disable_spellcheck = false; source_view->disable_spellcheck = false;
}
} }
}); });
menu.add_action("edit_copy", [this]() { menu.add_action("edit_copy", [this]() {
@ -517,8 +534,13 @@ void Window::set_menu_actions() {
} }
auto widget = get_focus(); auto widget = get_focus();
if(auto entry = dynamic_cast<Gtk::Entry *>(widget)) if(auto entry = dynamic_cast<Gtk::Entry *>(widget)) {
entry->copy_clipboard(); int start, end;
if(!entry->get_selection_bounds(start, end))
Gtk::Clipboard::get()->set_text(entry->get_text());
else
entry->copy_clipboard();
}
else if(auto view = dynamic_cast<Gtk::TextView *>(widget)) { else if(auto view = dynamic_cast<Gtk::TextView *>(widget)) {
if(!view->get_buffer()->get_has_selection()) { if(!view->get_buffer()->get_has_selection()) {
auto start = view->get_buffer()->get_iter_at_line(view->get_buffer()->get_insert()->get_iter().get_line()); auto start = view->get_buffer()->get_iter_at_line(view->get_buffer()->get_insert()->get_iter().get_line());
@ -526,14 +548,41 @@ void Window::set_menu_actions() {
if(!end.ends_line()) if(!end.ends_line())
end.forward_to_line_end(); end.forward_to_line_end();
end.forward_char(); end.forward_char();
if(!end.starts_line()) // In case of \r\n
end.forward_char();
Gtk::Clipboard::get()->set_text(view->get_buffer()->get_text(start, end)); Gtk::Clipboard::get()->set_text(view->get_buffer()->get_text(start, end));
} }
else else
view->get_buffer()->copy_clipboard(Gtk::Clipboard::get()); view->get_buffer()->copy_clipboard(Gtk::Clipboard::get());
} }
}); });
menu.add_action("edit_copy_lines", [this]() {
// Copy from a tooltip if it has selected text
for(auto tooltip : Tooltips::shown_tooltips) {
auto buffer = tooltip->text_buffer;
if(buffer && buffer->get_has_selection()) {
Gtk::TextIter start, end;
buffer->get_selection_bounds(start, end);
start = buffer->get_iter_at_line(start.get_line());
if(!end.ends_line())
end.forward_to_line_end();
end.forward_char();
Gtk::Clipboard::get()->set_text(buffer->get_text(start, end));
return;
}
}
auto widget = get_focus();
if(auto entry = dynamic_cast<Gtk::Entry *>(widget))
Gtk::Clipboard::get()->set_text(entry->get_text());
else if(auto view = dynamic_cast<Gtk::TextView *>(widget)) {
Gtk::TextIter start, end;
view->get_buffer()->get_selection_bounds(start, end);
start = view->get_buffer()->get_iter_at_line(start.get_line());
if(!end.ends_line())
end.forward_to_line_end();
end.forward_char();
Gtk::Clipboard::get()->set_text(view->get_buffer()->get_text(start, end));
}
});
menu.add_action("edit_paste", [this]() { menu.add_action("edit_paste", [this]() {
auto widget = get_focus(); auto widget = get_focus();
if(auto entry = dynamic_cast<Gtk::Entry *>(widget)) if(auto entry = dynamic_cast<Gtk::Entry *>(widget))

Loading…
Cancel
Save