diff options
| author | Alexandru-Daniel Roman <alexroman5g@gmail.com> | 2017-02-28 11:48:29 +0000 |
|---|---|---|
| committer | Alexandru-Daniel Roman <alexroman5g@gmail.com> | 2017-02-28 11:48:29 +0000 |
| commit | 0fad68e35604556b9a3af81b90d8cc6b89e817b8 (patch) | |
| tree | 9de21c8ce185f3f5c2e7fda2538417d077f20e93 /src | |
| parent | More consistent naming scheme. (diff) | |
| download | inkscape-0fad68e35604556b9a3af81b90d8cc6b89e817b8.tar.gz inkscape-0fad68e35604556b9a3af81b90d8cc6b89e817b8.zip | |
This patch adds the copy-paste formated text functionality to the text tool.
It doesn't retain the font-size and font-style properties.
(bzr r15553)
Diffstat (limited to 'src')
| -rw-r--r-- | src/ui/clipboard.cpp | 45 | ||||
| -rw-r--r-- | src/ui/tools/text-tool.cpp | 56 | ||||
| -rw-r--r-- | src/ui/tools/text-tool.h | 1 |
3 files changed, 100 insertions, 2 deletions
diff --git a/src/ui/clipboard.cpp b/src/ui/clipboard.cpp index c1e824c1e..038711861 100644 --- a/src/ui/clipboard.cpp +++ b/src/ui/clipboard.cpp @@ -143,6 +143,11 @@ private: Inkscape::XML::Node *_clipnode; ///< The node that holds extra information Inkscape::XML::Document *_doc; ///< Reference to the clipboard's Inkscape::XML::Document std::set<SPItem*> cloned_elements; + std::vector<SPCSSAttr*> te_selected_style; + std::vector<unsigned> te_selected_style_positions; + int nr_blocks = 0; + unsigned copied_style_length = 0; + // we need a way to copy plain text AND remember its style; // the standard _clipnode is only available in an SVG tree, hence this special storage @@ -241,6 +246,9 @@ void ClipboardManagerImpl::copy(ObjectSet *set) sp_repr_css_attr_unref(_text_style); _text_style = NULL; } + te_selected_style.clear(); + te_selected_style_positions.clear(); + te_selected_style = Inkscape::UI::Tools::sp_text_get_selected_style(desktop->event_context, &copied_style_length, &nr_blocks, &te_selected_style_positions); _text_style = Inkscape::UI::Tools::sp_text_get_style_at_cursor(desktop->event_context); return; } @@ -983,7 +991,42 @@ bool ClipboardManagerImpl::_pasteText(SPDesktop *desktop) // if the text editing tool is active, paste the text into the active text object if (tools_isactive(desktop, TOOLS_TEXT)) { - return Inkscape::UI::Tools::sp_text_paste_inline(desktop->event_context); + if(Inkscape::UI::Tools::sp_text_paste_inline(desktop->event_context) == false) + return false; + //apply the saved style to pasted text + Glib::RefPtr<Gtk::Clipboard> refClipboard = Gtk::Clipboard::get(); + Glib::ustring const clip_text = refClipboard->wait_for_text(); + Glib::ustring text(clip_text); + if(text.length() == copied_style_length) + { + Inkscape::UI::Tools::TextTool *tc = SP_TEXT_CONTEXT(desktop->event_context); + Inkscape::Text::Layout const *layout = te_get_layout(tc->text); + Inkscape::Text::Layout::iterator it_next; + Inkscape::Text::Layout::iterator it = tc->text_sel_end; + + SPCSSAttr *css = take_style_from_item(tc->text); + for (int i = 0; i < nr_blocks; ++i) + { + gchar const *w = sp_repr_css_property(css, "font-size", "40px"); + if (w) + sp_repr_css_set_property(te_selected_style[i], "font-size", w); + } + + for (int i = 0; i < text.length(); ++i) + it.prevCharacter(); + it_next = layout->charIndexToIterator(layout->iteratorToCharIndex(it)); + + for (int i = 0; i < nr_blocks; ++i) + { + for (int j = te_selected_style_positions[i]; j < te_selected_style_positions[i+1]; ++j) + it_next.nextCharacter(); + sp_te_apply_style(tc->text, it, it_next, te_selected_style[i]); + te_update_layout_now_recursive(tc->text); + for (int j = te_selected_style_positions[i]; j < te_selected_style_positions[i+1]; ++j) + it.nextCharacter(); + } + } + return true; } // try to parse the text as a color and, if successful, apply it as the current style diff --git a/src/ui/tools/text-tool.cpp b/src/ui/tools/text-tool.cpp index 559187764..649bbb045 100644 --- a/src/ui/tools/text-tool.cpp +++ b/src/ui/tools/text-tool.cpp @@ -48,6 +48,8 @@ #include "ui/control-manager.h" #include "verbs.h" #include "xml/node-event-vector.h" +#include "xml/attribute-record.h" +#include "xml/sp-css-attr.h" using Inkscape::ControlManager; using Inkscape::DocumentUndo; @@ -1357,6 +1359,59 @@ SPCSSAttr *sp_text_get_style_at_cursor(ToolBase const *ec) return NULL; } +static bool css_attrs_are_equal(SPCSSAttr const *first, SPCSSAttr const *second) +{ + Inkscape::Util::List<Inkscape::XML::AttributeRecord const> attrs = first->attributeList(); + for ( ; attrs ; attrs++) { + gchar const *other_attr = second->attribute(g_quark_to_string(attrs->key)); + if (other_attr == NULL || strcmp(attrs->value, other_attr)) + return false; + } + attrs = second->attributeList(); + for ( ; attrs ; attrs++) { + gchar const *other_attr = first->attribute(g_quark_to_string(attrs->key)); + if (other_attr == NULL || strcmp(attrs->value, other_attr)) + return false; + } + return true; +} + +std::vector<SPCSSAttr*> sp_text_get_selected_style(ToolBase const *ec, unsigned *k, int *b, std::vector<unsigned> *positions) +{ + std::vector<SPCSSAttr*> vec; + SPCSSAttr *css, *css_new; + TextTool *tc = SP_TEXT_CONTEXT(ec); + Inkscape::Text::Layout::iterator i = std::min(tc->text_sel_start, tc->text_sel_end); + SPObject const *obj = sp_te_object_at_position(tc->text, i); + if (obj) { + css = take_style_from_item(const_cast<SPObject*>(obj)); + } + vec.push_back(css); + positions->push_back(0); + i.nextCharacter(); + *k = 1; + *b = 1; + while (i != std::max(tc->text_sel_start, tc->text_sel_end)) + { + obj = sp_te_object_at_position(tc->text, i); + if (obj) { + css_new = take_style_from_item(const_cast<SPObject*>(obj)); + } + if(!css_attrs_are_equal(css, css_new)) + { + vec.push_back(css_new); + css = sp_repr_css_attr_new(); + sp_repr_css_merge(css, css_new); + positions->push_back(*k); + (*b)++; + } + i.nextCharacter(); + (*k)++; + } + positions->push_back(*k); + return vec; +} + /** Deletes the currently selected characters. Returns false if there is no text selection currently. @@ -1442,7 +1497,6 @@ bool TextTool::_styleSet(SPCSSAttr const *css) _("Set text style")); sp_text_context_update_cursor(this); sp_text_context_update_text_selection(this); - return true; } diff --git a/src/ui/tools/text-tool.h b/src/ui/tools/text-tool.h index 289ee180d..f2e6fea1a 100644 --- a/src/ui/tools/text-tool.h +++ b/src/ui/tools/text-tool.h @@ -94,6 +94,7 @@ private: bool sp_text_paste_inline(ToolBase *ec); Glib::ustring sp_text_get_selected_text(ToolBase const *ec); SPCSSAttr *sp_text_get_style_at_cursor(ToolBase const *ec); +std::vector<SPCSSAttr*> sp_text_get_selected_style(ToolBase const *ec, unsigned *k, int *b, std::vector<unsigned> *positions); bool sp_text_delete_selection(ToolBase *ec); void sp_text_context_place_cursor (TextTool *tc, SPObject *text, Inkscape::Text::Layout::iterator where); void sp_text_context_place_cursor_at (TextTool *tc, SPObject *text, Geom::Point const p); |
