From 75f7b307c385c13cee15230618083631d3398c1a Mon Sep 17 00:00:00 2001 From: gbanaszk Date: Wed, 18 Jul 2007 18:33:13 +0000 Subject: [PATCH] Cleaned up logic of sp_te_delete to adhere to UI/logic layering. --- src/text-context.cpp | 73 +++++++++++++++++++++++++++++++++++--------- src/text-editing.cpp | 54 +++++++++++++++----------------- src/text-editing.h | 6 ++-- 3 files changed, 87 insertions(+), 46 deletions(-) diff --git a/src/text-context.cpp b/src/text-context.cpp index f3f974c6f..0410ab3b4 100644 --- a/src/text-context.cpp +++ b/src/text-context.cpp @@ -912,30 +912,51 @@ sp_text_context_root_handler(SPEventContext *const ec, GdkEvent *const event) case GDK_Return: case GDK_KP_Enter: + { if (!tc->text) { // printable key; create text if none (i.e. if nascent_object) sp_text_context_setup_text(tc); tc->nascent_object = 0; // we don't need it anymore, having created a real } - tc->text_sel_start = tc->text_sel_end - = sp_te_delete(tc->text, tc->text_sel_start, tc->text_sel_end, SP_TE_DELETE_OTHER); + + iterator_pair enter_pair; + bool success = sp_te_delete(tc->text, tc->text_sel_start, tc->text_sel_end, enter_pair); + tc->text_sel_start = tc->text_sel_end = enter_pair.first; tc->text_sel_start = tc->text_sel_end = sp_te_insert_line(tc->text, tc->text_sel_start); + sp_text_context_update_cursor(tc); sp_text_context_update_text_selection(tc); sp_document_done(sp_desktop_document(ec->desktop), SP_VERB_CONTEXT_TEXT, _("New line")); return TRUE; + } case GDK_BackSpace: if (tc->text) { // if nascent_object, do nothing, but return TRUE; same for all other delete and move keys - sp_te_deletion_type deleteType = SP_TE_DELETE_OTHER; - - if (tc->text_sel_start == tc->text_sel_end) { + + bool noSelection = false; + + if (tc->text_sel_start == tc->text_sel_end) { tc->text_sel_start.prevCursorPosition(); - deleteType = SP_TE_DELETE_SINGLE_BACKSPACE; + noSelection = true; } + + iterator_pair bspace_pair; + bool success = sp_te_delete(tc->text, tc->text_sel_start, tc->text_sel_end, bspace_pair); - tc->text_sel_start = tc->text_sel_end - = sp_te_delete(tc->text, tc->text_sel_start, tc->text_sel_end, deleteType); + if (noSelection) { + if (success) { + tc->text_sel_start = tc->text_sel_end = bspace_pair.first; + } else { // nothing deleted + tc->text_sel_start = tc->text_sel_end = bspace_pair.second; + } + } else { + if (success) { + tc->text_sel_start = tc->text_sel_end = bspace_pair.first; + } else { // nothing deleted + tc->text_sel_start = bspace_pair.first; + tc->text_sel_end = bspace_pair.second; + } + } sp_text_context_update_cursor(tc); sp_text_context_update_text_selection(tc); @@ -946,15 +967,27 @@ sp_text_context_root_handler(SPEventContext *const ec, GdkEvent *const event) case GDK_Delete: case GDK_KP_Delete: if (tc->text) { - sp_te_deletion_type deleteType = SP_TE_DELETE_OTHER; - + bool noSelection = false; + if (tc->text_sel_start == tc->text_sel_end) { tc->text_sel_end.nextCursorPosition(); - deleteType = SP_TE_SINGLE_DELETE; + noSelection = true; + } + + iterator_pair del_pair; + bool success = sp_te_delete(tc->text, tc->text_sel_start, tc->text_sel_end, del_pair); + + if (noSelection) { + tc->text_sel_start = tc->text_sel_end = del_pair.first; + } else { + if (success) { + tc->text_sel_start = tc->text_sel_end = del_pair.first; + } else { // nothing deleted + tc->text_sel_start = del_pair.first; + tc->text_sel_end = del_pair.second; + } } - tc->text_sel_start = tc->text_sel_end - = sp_te_delete(tc->text, tc->text_sel_start, tc->text_sel_end, deleteType); sp_text_context_update_cursor(tc); sp_text_context_update_text_selection(tc); @@ -1307,9 +1340,21 @@ bool sp_text_delete_selection(SPEventContext *ec) if (tc->text_sel_start == tc->text_sel_end) return false; - tc->text_sel_start = tc->text_sel_end = sp_te_delete(tc->text, tc->text_sel_start, tc->text_sel_end, SP_TE_DELETE_OTHER); + + iterator_pair pair; + bool success = sp_te_delete(tc->text, tc->text_sel_start, tc->text_sel_end, pair); + + + if (success) { + tc->text_sel_start = tc->text_sel_end = pair.first; + } else { // nothing deleted + tc->text_sel_start = pair.first; + tc->text_sel_end = pair.second; + } + sp_text_context_update_cursor(tc); sp_text_context_update_text_selection(tc); + return true; } diff --git a/src/text-editing.cpp b/src/text-editing.cpp index 2ad894cc6..02fec31d1 100644 --- a/src/text-editing.cpp +++ b/src/text-editing.cpp @@ -138,8 +138,9 @@ char * dump_hexy(const gchar * utf8) Inkscape::Text::Layout::iterator sp_te_replace(SPItem *item, Inkscape::Text::Layout::iterator const &start, Inkscape::Text::Layout::iterator const &end, gchar const *utf8) { - Inkscape::Text::Layout::iterator new_start = sp_te_delete(item, start, end, SP_TE_DELETE_OTHER); - return sp_te_insert(item, new_start, utf8); + iterator_pair pair; + sp_te_delete(item, start, end, pair); + return sp_te_insert(item, pair.first, utf8); } @@ -678,20 +679,21 @@ static void erase_from_spstring(SPString *string_item, Glib::ustring::iterator i quite a complicated operation, partly due to the cleanup that is done if all the text in a subobject has been deleted, and partly due to the difficulty of figuring out what is a line break and how to delete one. Returns the -lesser of \a start and \a end, because that is where the cursor should be -put after the deletion is done. */ -Inkscape::Text::Layout::iterator +real start and ending iterators based on the situation. */ +bool sp_te_delete (SPItem *item, Inkscape::Text::Layout::iterator const &start, - Inkscape::Text::Layout::iterator const &end, sp_te_deletion_type deletionType) + Inkscape::Text::Layout::iterator const &end, iterator_pair &iter_pair) { - if (start == end) return start; - Inkscape::Text::Layout::iterator first, last; - if (start < end) { - first = start; - last = end; - } else { - first = end; - last = start; + bool success = false; + + iter_pair.first = start; + iter_pair.second = end; + + if (start == end) return success; + + if (start > end) { + iter_pair.first = end; + iter_pair.second = start; } SPDesktop *desktop = SP_ACTIVE_DESKTOP; @@ -700,12 +702,12 @@ sp_te_delete (SPItem *item, Inkscape::Text::Layout::iterator const &start, SPObject *start_item = 0, *end_item = 0; void *rawptr = 0; Glib::ustring::iterator start_text_iter, end_text_iter; - layout->getSourceOfCharacter(first, &rawptr, &start_text_iter); + layout->getSourceOfCharacter(iter_pair.first, &rawptr, &start_text_iter); start_item = SP_OBJECT(rawptr); - layout->getSourceOfCharacter(last, &rawptr, &end_text_iter); + layout->getSourceOfCharacter(iter_pair.second, &rawptr, &end_text_iter); end_item = SP_OBJECT(rawptr); if (start_item == 0) - return first; // start is at end of text + return success; // start is at end of text if (is_line_break_object(start_item)) move_to_end_of_paragraph(&start_item, &start_text_iter); if (end_item == 0) { @@ -723,14 +725,9 @@ sp_te_delete (SPItem *item, Inkscape::Text::Layout::iterator const &start, // If the parent is a tref, editing on this particular string is disallowed. if (SP_IS_TREF(SP_OBJECT_PARENT(start_item))) { desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, tref_edit_message); - - // Compensate so the cursor doesn't move when hitting backspace - if (deletionType == SP_TE_DELETE_SINGLE_BACKSPACE) { - first = last; - } - } else { erase_from_spstring(SP_STRING(start_item), start_text_iter, end_text_iter); + success = true; } } } else { @@ -742,15 +739,12 @@ sp_te_delete (SPItem *item, Inkscape::Text::Layout::iterator const &start, // If the parent is a tref, editing on this particular string is disallowed. if (SP_IS_TREF(SP_OBJECT_PARENT(sub_item))) { desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, tref_edit_message); - // Compensate so the cursor doesn't move when hitting backspace - if (deletionType == SP_TE_DELETE_SINGLE_BACKSPACE) { - //first = last; - } break; } Glib::ustring *string = &SP_STRING(sub_item)->string; erase_from_spstring(SP_STRING(sub_item), string->begin(), end_text_iter); + success = true; } break; } @@ -760,6 +754,7 @@ sp_te_delete (SPItem *item, Inkscape::Text::Layout::iterator const &start, erase_from_spstring(string, start_text_iter, string->string.end()); else erase_from_spstring(string, string->string.begin(), string->string.end()); + success = true; } // walk to the next item in the tree if (sub_item->hasChildren()) @@ -788,8 +783,9 @@ sp_te_delete (SPItem *item, Inkscape::Text::Layout::iterator const &start, while (tidy_xml_tree_recursively(common_ancestor)); te_update_layout_now(item); item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - layout->validateIterator(&first); - return first; + layout->validateIterator(&iter_pair.first); + layout->validateIterator(&iter_pair.second); + return success; } diff --git a/src/text-editing.h b/src/text-editing.h index 8955d1e30..fb2f17365 100644 --- a/src/text-editing.h +++ b/src/text-editing.h @@ -18,6 +18,8 @@ struct SPItem; class SPCSSAttr; namespace NR { class Point; } +typedef std::pair iterator_pair; + Inkscape::Text::Layout const * te_get_layout (SPItem const *item); bool sp_te_output_is_empty (SPItem const *item); @@ -35,9 +37,7 @@ SPStyle const * sp_te_style_at_position(SPItem const *text, Inkscape::Text::Layo Inkscape::Text::Layout::iterator sp_te_insert(SPItem *item, Inkscape::Text::Layout::iterator const &position, gchar const *utf8); Inkscape::Text::Layout::iterator sp_te_replace(SPItem *item, Inkscape::Text::Layout::iterator const &start, Inkscape::Text::Layout::iterator const &end, gchar const *utf8); Inkscape::Text::Layout::iterator sp_te_insert_line (SPItem *text, Inkscape::Text::Layout::iterator const &position); - -enum sp_te_deletion_type { SP_TE_DELETE_SINGLE_BACKSPACE, SP_TE_SINGLE_DELETE, SP_TE_DELETE_OTHER }; -Inkscape::Text::Layout::iterator sp_te_delete (SPItem *item, Inkscape::Text::Layout::iterator const &start, Inkscape::Text::Layout::iterator const &end, sp_te_deletion_type deletionType); +bool sp_te_delete (SPItem *item, Inkscape::Text::Layout::iterator const &start, Inkscape::Text::Layout::iterator const &end, iterator_pair &iter_pair); gchar *sp_te_get_string_multiline(SPItem const *text); Glib::ustring sp_te_get_string_multiline(SPItem const *text, Inkscape::Text::Layout::iterator const &start, Inkscape::Text::Layout::iterator const &end); -- 2.30.2