16#include <glibmm/i18n.h>
17#include <glibmm/regex.h>
18#include <gtkmm/entry.h>
19#include <gtkmm/enums.h>
20#include <gtkmm/sizegroup.h>
59 entry_find(_(
"F_ind:"), _(
"Find objects by their content or properties (exact or partial match)")),
60 entry_replace(_(
"R_eplace:"), _(
"Replace match with this value")),
63 check_scope_all(_(
"_All")),
64 check_scope_layer(_(
"Current _layer")),
65 check_scope_selection(_(
"Sele_ction")),
66 check_searchin_text(_(
"_Text")),
67 check_searchin_property(_(
"_Properties")),
68 frame_searchin(_(
"Search in")),
69 frame_scope(_(
"Scope")),
71 check_case_sensitive(_(
"Case sensiti_ve")),
72 check_exact_match(_(
"E_xact match")),
73 check_include_hidden(_(
"Include _hidden")),
74 check_include_locked(_(
"Include loc_ked")),
75 expander_options(_(
"Options")),
76 frame_options(_(
"General")),
79 check_attributename(_(
"Attribute _name")),
80 check_attributevalue(_(
"Attri_bute value")),
81 check_style(_(
"_Style")),
82 check_font(_(
"F_ont")),
83 check_desc(_(
"_Desc")),
84 check_title(_(
"Title")),
85 frame_properties(_(
"Properties")),
87 check_alltypes(_(
"All types")),
88 check_rects(_(
"Rectangles")),
89 check_ellipses(_(
"Ellipses")),
90 check_stars(_(
"Stars")),
91 check_spirals(_(
"Spirals")),
92 check_paths(_(
"Paths")),
93 check_texts(_(
"Texts")),
94 check_groups(_(
"Groups")),
97 C_(
"Find dialog",
"Clones")),
99 check_images(_(
"Images")),
100 check_offsets(_(
"Offsets")),
101 frame_types(_(
"Object types")),
107 button_find(_(
"_Find")),
108 button_replace(_(
"_Replace All")),
109 _action_replace(false),
131 label1->set_xalign(0);
132 label1->set_hexpand(
false);
137 label2->set_xalign(0);
138 label2->set_hexpand(
false);
140 static constexpr int MARGIN = 4;
141 set_margin_start(MARGIN);
142 set_margin_end(MARGIN);
148 button_find.set_tooltip_text(_(
"Select all objects matching the selection criteria"));
176 check_ids.set_tooltip_text(_(
"Search ID name"));
188 check_font.set_tooltip_text(_(
"Search fonts"));
191 check_desc.set_tooltip_text(_(
"Search description"));
200 check_rects.set_tooltip_text(_(
"Search rectangles"));
203 check_ellipses.set_tooltip_text(_(
"Search ellipses, arcs, circles"));
206 check_stars.set_tooltip_text(_(
"Search stars and polygons"));
212 check_paths.set_tooltip_text(_(
"Search paths, lines, polylines"));
215 check_texts.set_tooltip_text(_(
"Search text objects"));
402Glib::ustring
Find::find_replace(
const gchar *str,
const gchar *find,
const gchar *replace,
bool exact,
bool casematch,
bool replaceall)
404 Glib::ustring ustr = str;
405 Glib::ustring ufind = find;
406 gsize replace_length = Glib::ustring(replace).length();
408 ufind = ufind.lowercase();
410 gsize n =
find_strcmp_pos(ustr.c_str(), ufind.c_str(), exact, casematch);
411 while (n != std::string::npos) {
412 ustr.replace(n, ufind.length(), replace);
417 n =
find_strcmp_pos(ustr.c_str(), ufind.c_str(), exact, casematch, n + replace_length);
424 Glib::ustring ustr = str ? str :
"";
425 Glib::ustring ufind = find;
428 ustr = ustr.lowercase();
429 ufind = ufind.lowercase();
432 gsize pos = std::string::npos;
438 pos = ustr.find(ufind,
start);
447 return (std::string::npos !=
find_strcmp_pos(str, find, exact, casematch));
453 bool found =
find_strcmp(desc, text, exact, casematch);
454 if (found && replace) {
465 bool found =
find_strcmp(title, text, exact, casematch);
466 if (found && replace) {
482 if (!item_text.empty()) {
483 bool found =
find_strcmp(item_text.c_str(), find, exact, casematch);
485 if (found && replace) {
486 Glib::ustring ufind = find;
488 ufind = ufind.lowercase();
497 gsize n =
find_strcmp_pos(item_text.c_str(), ufind.c_str(), exact, casematch);
500 while (n != std::string::npos) {
505 n =
find_strcmp_pos(item_text.c_str(), ufind.c_str(), exact, casematch, n + replace.length());
526 bool found =
find_strcmp(item_id,
id, exact, casematch);
528 if (found && replace) {
530 Glib::ustring new_item_style =
find_replace(item_id,
id, replace_text , exact, casematch,
true);
531 if (new_item_style != item_id) {
534 g_free(replace_text);
547 if (item_style ==
nullptr) {
551 bool found =
find_strcmp(item_style, text, exact, casematch);
553 if (found && replace) {
555 Glib::ustring new_item_style =
find_replace(item_style, text, replace_text , exact, casematch,
true);
556 if (new_item_style != item_style) {
559 g_free(replace_text);
576 found = (attr_value !=
nullptr);
583 if (found && replace) {
599 const gchar*
key = g_quark_to_string(iter.key);
601 bool found =
find_strcmp(attr_value, text, exact, casematch);
606 if (found && replace) {
608 Glib::ustring new_item_style =
find_replace(attr_value, text, replace_text , exact, casematch,
true);
609 if (new_item_style != attr_value) {
630 if (item_style ==
nullptr) {
634 std::vector<Glib::ustring> vFontTokenNames;
635 vFontTokenNames.emplace_back(
"font-family:");
636 vFontTokenNames.emplace_back(
"-inkscape-font-specification:");
638 std::vector<Glib::ustring> vStyleTokens = Glib::Regex::split_simple(
";", item_style);
639 for (
auto & vStyleToken : vStyleTokens) {
640 Glib::ustring token = vStyleToken;
641 for (
const auto & vFontTokenName : vFontTokenNames) {
642 if ( token.find(vFontTokenName) != std::string::npos) {
643 Glib::ustring font1 = Glib::ustring(vFontTokenName).append(text);
644 bool found =
find_strcmp(token.c_str(), font1.c_str(), exact, casematch);
649 gchar *orig_str = g_strdup(token.c_str());
651 Glib::ustring new_item_style =
find_replace(orig_str, text, replace_text ,
false , casematch,
true);
652 if (new_item_style != orig_str) {
653 vStyleToken = new_item_style;
656 g_free(replace_text);
664 Glib::ustring new_item_style;
665 for (
const auto & vStyleToken : vStyleTokens) {
666 new_item_style.append(vStyleToken).append(
";");
668 new_item_style.erase(new_item_style.size()-1);
682 gchar* text = g_strdup(tmp.c_str());
684 std::vector<SPItem*> in = l;
685 std::vector<SPItem*> out;
688 for (std::vector<SPItem*>::const_reverse_iterator i=in.rbegin(); in.rend() != i; ++i) {
690 auto item = cast<SPItem>(obj);
691 g_assert(
item !=
nullptr);
693 if (out.end()==find(out.begin(),out.end(), *i)) {
713 for (std::vector<SPItem*>::const_reverse_iterator i=in.rbegin(); in.rend() != i; ++i) {
715 auto item = cast<SPItem>(obj);
717 if (out.end()==find(out.begin(),out.end(), *i)) {
729 for (std::vector<SPItem*>::const_reverse_iterator i=in.rbegin(); in.rend() != i; ++i) {
731 auto item = cast<SPItem>(obj);
732 g_assert(
item !=
nullptr);
734 if (out.end()==find(out.begin(),out.end(), *i)){
746 for (std::vector<SPItem*>::const_reverse_iterator i=in.rbegin(); in.rend() != i; ++i) {
748 auto item = cast<SPItem>(obj);
749 g_assert(
item !=
nullptr);
751 if (out.end()==find(out.begin(),out.end(), *i)) {
763 for (std::vector<SPItem*>::const_reverse_iterator i=in.rbegin(); in.rend() != i; ++i) {
765 auto item = cast<SPItem>(obj);
766 g_assert(
item !=
nullptr);
768 if (out.end()==find(out.begin(),out.end(), *i)) {
780 for (std::vector<SPItem*>::const_reverse_iterator i=in.rbegin(); in.rend() != i; ++i) {
782 auto item = cast<SPItem>(obj);
783 g_assert(
item !=
nullptr);
785 if (out.end()==find(out.begin(),out.end(),*i)) {
795 for (std::vector<SPItem*>::const_reverse_iterator i=in.rbegin(); in.rend() != i; ++i) {
797 auto item = cast<SPItem>(obj);
798 g_assert(
item !=
nullptr);
800 if (out.end()==find(out.begin(),out.end(),*i)) {
810 for (std::vector<SPItem*>::const_reverse_iterator i=in.rbegin(); in.rend() != i; ++i) {
812 auto item = cast<SPItem>(obj);
813 g_assert(
item !=
nullptr);
815 if (out.end()==find(out.begin(),out.end(),*i)) {
837 if (is<SPRect>(
item)) {
840 }
else if (is<SPGenericEllipse>(
item)) {
843 }
else if (is<SPStar>(
item) || is<SPPolygon>(
item)) {
846 }
else if (is<SPSpiral>(
item)) {
849 }
else if (is<SPPath>(
item) || is<SPLine>(
item) || is<SPPolyLine>(
item)) {
852 }
else if (is<SPText>(
item) || is<SPTSpan>(
item) ||
854 is<SPFlowtext>(
item) || is<SPFlowdiv>(
item) ||
855 is<SPFlowtspan>(
item) || is<SPFlowpara>(
item)) {
858 }
else if (is<SPGroup>(
item) &&
862 }
else if (is<SPUse>(
item)) {
865 }
else if (is<SPImage>(
item)) {
868 }
else if (is<SPOffset>(
item)) {
877 std::vector<SPItem*> n;
878 for (std::vector<SPItem*>::const_reverse_iterator i=l.rbegin(); l.rend() != i; ++i) {
880 auto item = cast<SPItem>(obj);
881 g_assert(
item !=
nullptr);
903 if (!strcmp(r->
getRepr()->
name(),
"svg:metadata")) {
923 auto itemlist = s->
items();
924 for (
auto i=boost::rbegin(itemlist); boost::rend(itemlist) != i; ++i) {
926 auto item = cast<SPItem>(obj);
927 g_assert(
item !=
nullptr);
960 status.set_text(_(
"Nothing to replace"));
979 std::vector<SPItem*> l;
993 guint all = l.size();
995 std::vector<SPItem*> n =
filter_list (l, exact, casematch);
998 int count = n.size();
1001 ngettext(
"<b>%d</b> object found (out of <b>%d</b>), %s match.",
1002 "<b>%d</b> objects found (out of <b>%d</b>), %s match.",
1004 count, all, exact? _(
"exact") : _(
"partial"));
1007 status.set_text(Glib::ustring::compose(ngettext(
"%1 match replaced",
"%1 matches replaced",count), count));
1011 status.set_text(Glib::ustring::compose(ngettext(
"%1 object found",
"%1 objects found",count), count));
1020 auto item = cast<SPItem>(obj);
1021 g_assert(
item !=
nullptr);
1029 status.set_text(_(
"Nothing found"));
1042 bool objectok =
false;
1049 if (checkType->get_active()) {
1055 status.set_text(_(
"Select an object type"));
1059 bool propertyok =
false;
1066 if (checkProperty->get_active()) {
1073 status.set_text(_(
"Select a property"));
1079 button_find.set_sensitive(objectok && propertyok);
1088 checkType->set_sensitive(!all);
1109 checkProperty->set_sensitive(on);
TODO: insert short description here.
static void done(SPDocument *document, Glib::ustring const &event_description, Glib::ustring const &undo_icon, unsigned int object_modified_tag=0)
SPGroup * currentLayer() const
Returns current top layer.
bool isLayer(SPObject *object) const
True if object is a layer.
MessageId flash(MessageType type, char const *message)
Temporarily pushes a message onto the stack.
MessageId flashF(MessageType type, char const *format,...) G_GNUC_PRINTF(3
temporarily pushes a message onto the stack using printf-like formatting
SPItemRange items()
Returns a range of selected SPItems.
boost::enable_if< boost::is_base_of< SPObject, T >, void >::type setList(const std::vector< T * > &objs)
Selects exactly the specified objects.
void clear()
Unselects all selected objects.
SPItem * singleItem()
Returns a single selected item.
The set of selected SPObjects for a given document and layer model.
Holds a position within the glyph output of Layout.
Generates the layout for either wrapped or non-wrapped text and stores the result.
iterator charIndexToIterator(int char_index) const
Returns an iterator pointing at the given character index.
DialogBase is the base class for the dialog system.
Selection * getSelection() const
SPDesktop * getDesktop() const
Gtk::CheckButton check_include_locked
void onFind()
Callbacks for pressing the dialog buttons.
Gtk::CheckButton check_texts
Gtk::CheckButton check_groups
Gtk::CheckButton check_ellipses
Gtk::Box vbox_properties2
Gtk::CheckButton check_scope_selection
Gtk::CheckButton check_ids
Property type widgets.
Gtk::Button button_replace
gsize find_strcmp_pos(const gchar *str, const gchar *find, bool exact, bool casematch, gsize start=0)
Find a string within a string and return the position with options for exact, casematching and search...
Glib::RefPtr< Gtk::SizeGroup > _left_size_group
std::vector< Gtk::CheckButton * > checkTypes
A vector of all the check option widgets for easy processing.
bool item_id_match(SPItem *item, const gchar *id, bool exact, bool casematch, bool replace=false)
Returns true if the SPItem 'item' has the same id.
void desktopReplaced() override
Called when the desktop has certainly changed.
Gtk::CheckButton check_stars
Gtk::CheckButton check_images
Glib::RefPtr< Gtk::SizeGroup > _right_size_group
Gtk::CheckButton check_case_sensitive
General option widgets.
Gtk::CheckButton check_include_hidden
void searchinToggle(bool on)
Toggle all the properties checkboxes.
Gtk::CheckButton check_paths
Gtk::Box vbox_properties1
bool item_attr_match(SPItem *item, const gchar *name, bool exact, bool casematch, bool replace=false)
Returns true if found the SPItem 'item' has the same attribute name.
UI::Widget::Frame frame_searchin
std::vector< SPItem * > & all_items(SPObject *r, std::vector< SPItem * > &l, bool hidden, bool locked)
recursive function to return a list of all the items in the SPObject tree
bool find_strcmp(const gchar *str, const gchar *find, bool exact, bool casematch)
Find a string within a string and returns true if found with options for exact and casematching.
Gtk::Expander expander_options
bool item_attrvalue_match(SPItem *item, const gchar *name, bool exact, bool casematch, bool replace=false)
Returns true if the SPItem 'item' has the same attribute value.
bool item_type_match(SPItem *item)
Gtk::CheckButton check_style
Gtk::CheckButton check_desc
std::vector< SPItem * > filter_fields(std::vector< SPItem * > &l, bool exact, bool casematch)
Function to filter a list of items based on the item type by calling each item_XXX_match function.
Gtk::CheckButton check_clones
UI::Widget::Entry entry_find
Gtk::CheckButton check_searchin_property
Gtk::CheckButton check_scope_layer
void onSearchinProperty()
Gtk::CheckButton check_alltypes
Object type widgets.
Gtk::CheckButton check_font
bool item_style_match(SPItem *item, const gchar *text, bool exact, bool casematch, bool replace=false)
Returns true if the SPItem 'item' has the same text in the style attribute.
std::vector< SPItem * > filter_types(std::vector< SPItem * > &l)
UI::Widget::Entry entry_replace
bool item_font_match(SPItem *item, const gchar *name, bool exact, bool casematch, bool replace=false)
Returns true if the SPItem 'item' has the same font values.
Gtk::CheckButton check_offsets
UI::Widget::Frame frame_types
Gtk::CheckButton check_attributename
Glib::RefPtr< Gtk::SizeGroup > label_group
Gtk::CheckButton check_exact_match
Gtk::CheckButton check_searchin_text
std::vector< SPItem * > & filter_list(std::vector< SPItem * > &l, bool exact, bool casematch)
std::vector< Gtk::CheckButton * > checkProperties
A vector of all the properties widgets for easy processing.
Gtk::CheckButton check_scope_all
Scope and search in widgets.
UI::Widget::Frame frame_scope
Gtk::CheckButton check_spirals
bool item_desc_match(SPItem *item, const gchar *text, bool exact, bool casematch, bool replace=false)
Returns true if the SPItem 'item' has a <title> or <desc> child that matches.
bool item_text_match(SPItem *item, const gchar *text, bool exact, bool casematch, bool replace=false)
Returns true if the SPItem 'item' has the same text content.
Gtk::Label status
Action Buttons and status.
UI::Widget::Frame frame_options
void selectionChanged(Selection *selection) override
UI::Widget::Frame frame_properties
std::vector< SPItem * > & all_selection_items(Inkscape::Selection *s, std::vector< SPItem * > &l, SPObject *ancestor, bool hidden, bool locked)
to return a list of all the selected items
Gtk::CheckButton check_attributevalue
bool item_title_match(SPItem *item, const gchar *text, bool exact, bool casematch, bool replace=false)
void squeeze_window()
Shrink the dialog size when the expander widget is closed Currently not working, no known way to do t...
Gtk::CheckButton check_title
bool _action_replace
Finding or replacing.
Glib::ustring find_replace(const gchar *str, const gchar *find, const gchar *replace, bool exact, bool casematch, bool replaceall)
Replace a string with another string with options for exact and casematching and replace once/all.
Gtk::CheckButton check_rects
Gtk::Entry const * getEntry() const
virtual char const * name() const =0
Get the name of the element node.
virtual const AttributeVector & attributeList() const =0
Get a list of the node's attributes.
virtual char const * attribute(char const *key) const =0
Get the string representation of a node's attribute.
virtual bool matchAttributeName(char const *partial_name) const =0
Check whether this node has any attribute that matches a string.
SPDocument * getDocument() const
bool itemIsHidden(SPItem const *item) const
Inkscape::MessageStack * messageStack() const
Inkscape::Selection * getSelection() const
Inkscape::LayerManager & layerManager()
SPRoot * getRoot()
Returns our SPRoot.
Base class for visual SVG elements.
SPObject is an abstract base class of all of the document nodes at the SVG document level.
char * desc() const
Returns the description of this object, or NULL if there is none.
void setAttribute(Inkscape::Util::const_char_ptr key, Inkscape::Util::const_char_ptr value)
bool setDesc(char const *desc, bool verbatim=false)
Sets the description of this object.
bool setTitle(char const *title, bool verbatim=false)
Sets the title of this object.
Inkscape::XML::Node * getRepr()
Returns the XML representation of tree.
char * title() const
Returns the title of this object, or NULL if there is none.
bool isAncestorOf(SPObject const *object) const
True if object is non-NULL and this is some in/direct parent of object.
Editable view implementation.
Event handler for dialog windows.
TODO: insert short description here.
Macro for icon names used in Inkscape.
Raw stack of active status messages.
void pack_end(Gtk::Box &box, Gtk::Widget &child, bool const expand, bool const fill, unsigned const padding)
Adds child to box, packed with reference to the end of box.
void pack_start(Gtk::Box &box, Gtk::Widget &child, bool const expand, bool const fill, unsigned const padding)
Adds child to box, packed with reference to the start of box.
static cairo_user_data_key_t key
Helpers for using Gtk::Boxes, encapsulating large changes between GTK3 & GTK4.
void scroll_to_show_item(SPDesktop *desktop, SPItem *item)
If item is not entirely visible then adjust visible area to centre on the centre on of item.
TODO: insert short description here.
TODO: insert short description here.
SVG <image> implementation.
TODO: insert short description here.
SPRoot: SVG <svg> implementation.
SVG <tref> implementation, see sp-tref.cpp.
TODO: insert short description here.
Glib::ustring sp_te_get_string_multiline(SPItem const *text)
Gets a text-only representation of the given text or flowroot object, replacing line break elements w...
Inkscape::Text::Layout const * te_get_layout(SPItem const *item)
Inkscape::Text::Layout::iterator sp_te_replace(SPItem *item, Inkscape::Text::Layout::iterator const &start, Inkscape::Text::Layout::iterator const &end, gchar const *utf8)