23#include <glibmm/i18n.h>
24#include <glibmm/ustring.h>
25#include <glibmm/variant.h>
26#include <giomm/simpleactiongroup.h>
27#include <gtkmm/button.h>
29#include <gtkmm/enums.h>
30#include <gtkmm/entry.h>
31#include <gtkmm/image.h>
32#include <gtkmm/menubutton.h>
33#include <gtkmm/object.h>
34#include <gtkmm/paned.h>
35#include <gtkmm/scrolledwindow.h>
36#include <gtkmm/treeview.h>
64void paned_set_vertical(Gtk::Paned &paned,
bool vertical)
66 auto& first = *paned.get_start_child();
67 auto& second = *paned.get_end_child();
69 paned.set_resize_start_child(vertical);
70 first.set_margin_bottom(vertical ? space : 0);
71 first.set_margin_end(vertical ? 0 : space);
72 second.set_margin_top(vertical ? space : 0);
73 second.set_margin_start(vertical ? 0 : space);
74 paned.set_resize_end_child(!vertical);
75 paned.set_orientation(vertical ? Gtk::Orientation::VERTICAL :
Gtk::Orientation::
HORIZONTAL);
86 , xml_element_new_button(
get_widget<
Gtk::Button>(_builder,
"new-elem"))
87 , xml_text_new_button(
get_widget<
Gtk::Button>(_builder,
"new-text"))
88 , xml_node_delete_button(
get_widget<
Gtk::Button>(_builder,
"del"))
89 , xml_node_duplicate_button(
get_widget<
Gtk::Button>(_builder,
"dup"))
90 , unindent_node_button(
get_widget<
Gtk::Button>(_builder,
"unindent"))
91 , indent_node_button(
get_widget<
Gtk::Button>(_builder,
"indent"))
92 , lower_node_button(
get_widget<
Gtk::Button>(_builder,
"lower"))
93 , raise_node_button(
get_widget<
Gtk::Button>(_builder,
"raise"))
94 , _syntax_theme(
"/theme/syntax-color-theme")
95 , _mono_font(
"/dialogs/xml/mono-font", false)
98 _xml_treeview = Gtk::make_managed<Inkscape::UI::Widget::XmlTreeView>();
99 _xml_treeview->set_tooltip_text( _(
"Drag to reorder nodes") );
101 Gtk::ScrolledWindow& tree_scroller = get_widget<Gtk::ScrolledWindow>(
_builder,
"tree-wnd");
117 _paned.set_resize_end_child(
true);
120 _xml_treeview->get_selection()->signal_changed().connect([
this]() {
139 set_name(
"XMLAndAttributesDialog");
142 int panedpos = prefs->
getInt(
"/dialogs/xml/panedpos", 200);
143 _paned.property_position() = panedpos;
148 _bin.set_expand(
true);
150 int min_width = 0, dummy;
151 measure(Gtk::Orientation::HORIZONTAL, -1, min_width, dummy, dummy, dummy);
153 auto auto_arrange_panels = [=,
this] (
int width,
int height) {
158 bool const narrow =
width < min_width * 1.5;
159 paned_set_vertical(
_paned, narrow);
168 paned_set_vertical(
_paned,
false);
171 paned_set_vertical(
_paned,
true);
180 auto& popup = get_widget<Gtk::MenuButton>(
_builder,
"layout-btn");
181 popup.set_has_tooltip();
182 popup.signal_query_tooltip().connect([
this](
int x,
int y,
bool kbd,
const Glib::RefPtr<Gtk::Tooltip>& tooltip){
185 case Auto: tip = _(
"Automatic panel layout:\nchanges with dialog size");
187 case Horizontal: tip = _(
"Horizontal panel layout");
189 case Vertical: tip = _(
"Vertical panel layout");
192 tooltip->set_text(tip);
197 Glib::ustring icon =
"layout-auto";
199 icon =
"layout-horizontal";
201 icon =
"layout-vertical";
203 get_widget<Gtk::MenuButton>(
_builder,
"layout-btn").set_icon_name(icon +
"-symbolic");
204 prefs->
setInt(
"/dialogs/xml/layout", layout);
205 arrange_panels(layout, get_width(), get_height());
210 auto action_group = Gio::SimpleActionGroup::create();
211 auto action = action_group->add_action_radio_integer(
"layout",
_layout);
212 action->property_state().signal_changed().connect([=, &popup]
214 popup.set_active(
false);
215 int target; action->get_state(target); set_layout(
static_cast<DialogLayout>(target));
217 insert_action_group(
"xml-tree", std::move(action_group));
221 paned_set_vertical(
_paned,
true);
232 Glib::ustring mono(
"mono-font");
243 renderer->signal_editing_canceled().connect([
this]() {
247 renderer->signal_edited().connect([
this](
const Glib::ustring& path,
const Glib::ustring&
name) {
251 renderer->signal_editing_started().connect([
this](Gtk::CellEditable* cell,
const Glib::ustring& path) {
272 prefs->
setInt(
"/dialogs/xml/panedpos",
_paned.property_position());
346 auto group = cast<SPGroup>(
object);
376 if (is<SPGroup>(object->
parent)) {
403 assert(repr !=
nullptr);
417 gtk_label_set_markup(GTK_LABEL(widget), message ? message :
"");
436 bool unindentable =
false;
440 if (grandparent && grandparent->parent()) {
447 bool indentable =
false;
452 assert (
parent->firstChild());
457 prev = prev->
next() ){};
497 if ( !strcmp(
node->
name(),
"svg:defs") ||
498 !strcmp(
node->
name(),
"sodipodi:namedview") ) {
533 renderer->property_editable() =
true;
537 _dummy = xml_doc->createElement(dummy);
551 auto entry =
dynamic_cast<Gtk::Entry *
>(cell);
552 entry->get_buffer()->set_text(
"");
558 renderer->property_editable() =
false;
588 static auto const extract_tagname = Glib::Regex::create(
"^<?\\s*(\\w[\\w:\\-\\d]*)");
589 Glib::MatchInfo match_info;
590 extract_tagname->match(element, match_info);
591 if (!match_info.matches()) {
594 element = match_info.fetch(1);
598 if (element.find(
':') == Glib::ustring::npos) {
599 element =
"svg:" + element;
679 g_return_if_fail(
parent !=
nullptr);
686 before = before->
next();
728 g_return_if_fail(
parent !=
nullptr);
729 g_return_if_fail(
parent->firstChild() != repr);
732 while (prev && (prev->
next() != repr)) {
735 g_return_if_fail(prev !=
nullptr);
762 g_assert(repr !=
nullptr);
768 g_return_if_fail(grandparent);
770 parent->removeChild(repr);
789 while (is<SPItem>(
child)) {
792 g_assert(is<SPRoot>(
child));
801 g_assert(!is<SPRoot>(
child));
static void done(SPDocument *document, Glib::ustring const &event_description, Glib::ustring const &undo_icon, unsigned int object_modified_tag=0)
void setCurrentLayer(SPObject *object, bool clear=false)
Sets the current layer of the desktop.
XML::Node * singleRepr()
Returns a single selected object's xml node.
std::function< void()> action
The action to perform when the value changes, if any.
Preference storage class.
static Preferences * get()
Access the singleton Preferences object.
int getInt(Glib::ustring const &pref_path, int def=0)
Retrieve an integer.
void setInt(Glib::ustring const &pref_path, int value)
Set an integer value.
int getIntLimited(Glib::ustring const &pref_path, int def=0, int min=INT_MIN, int max=INT_MAX)
Retrieve a limited integer.
The set of selected SPObjects for a given document and layer model.
void set(XML::Node *repr)
Set the selection to an XML node's SPObject.
void set_mono_font(bool mono)
Gtk::ScrolledWindow & get_scrolled_window()
Gtk::Box & get_status_box()
void setRepr(Inkscape::XML::Node *repr)
AttrDialog::setRepr Set the internal xml object that I'm working on right now.
DialogBase is the base class for the dialog system.
Selection * getSelection() const
void setDesktop(SPDesktop *new_desktop)
Called when the desktop might have changed for this dialog.
SPDocument * getDocument() const
void fix_inner_scroll(Gtk::ScrolledWindow &scrollwin)
SPDesktop * getDesktop() const
void cmd_new_element_node()
Callbacks for toolbar buttons being pressed.
void desktopReplaced() final
Called when the desktop has certainly changed.
Gtk::Button & raise_node_button
static void _set_status_message(Inkscape::MessageType type, const gchar *message, GtkWidget *dialog)
Callbacks for changes in desktop selection and current document.
void documentReplaced() final
Inkscape::XML::Node * selected_repr
Signal handlers.
void cmd_duplicate_node()
void set_tree_select(Inkscape::XML::Node *repr, bool edit=false)
Select a node in the xml tree.
void on_tree_unselect_row_disable()
Gtk::Button & xml_node_duplicate_button
Inkscape::XML::Node * _dummy
Inkscape::XML::Node * get_dt_select()
Find the current desktop selection.
Pref< Glib::ustring > _syntax_theme
void selectionChanged(Selection *selection) final
Gtk::Button & lower_node_button
void set_dt_select(Inkscape::XML::Node *repr)
Select the current desktop selection.
Inkscape::XML::Node * _node_parent
Gtk::Button & unindent_node_button
bool in_dt_coordsys(SPObject const &item)
Returns true iff item is suitable to be included in the selection, in particular whether it has a bou...
void on_tree_select_row_enable(Inkscape::XML::Node *node)
Enable widgets based on current selections.
void propagate_tree_select(Inkscape::XML::Node *repr)
Set the attribute list to match the selected node in the tree.
bool deferred_on_tree_select_row()
gint blocked
Flag to ensure only one operation is performed at once.
bool xml_tree_node_mutable(Inkscape::XML::Node *node)
Is the selected tree node editable.
sigc::scoped_connection _tree_select_idle
Callback for deferring the on_tree_select_row response in order to skip invalid intermediate selectio...
Gtk::Button & xml_node_delete_button
Inkscape::UI::Widget::XmlTreeView * _xml_treeview
void startNodeEditing(Gtk::CellEditable *cell, Glib::ustring const &path)
void onCreateNameChanged()
void stopNodeEditing(bool ok, Glib::ustring const &path, Glib::ustring name)
Gtk::Button * create_button
void setSyntaxStyle(Inkscape::UI::Syntax::XMLStyles const &new_style)
Gtk::Button & indent_node_button
Gtk::Button & xml_element_new_button
Gtk::Button & xml_text_new_button
Glib::RefPtr< Gtk::Builder > _builder
Interface for refcounted XML nodes.
virtual Node * parent()=0
Get the parent of this node.
virtual Node * next()=0
Get the next sibling of this node.
virtual void addChild(Node *child, Node *after)=0
Insert another node as a child of this node.
virtual void changeOrder(Node *child, Node *after)=0
Move a given node in this node's child order.
virtual void appendChild(Node *child)=0
Append a node as the last child of this node.
virtual char const * name() const =0
Get the name of the element node.
virtual Node * duplicate(Document *doc) const =0
Create a duplicate of this node.
virtual Node * firstChild()=0
Get the first child of this node.
virtual void removeChild(Node *child)=0
Remove a child of this node.
virtual NodeType type() const =0
Get the type of the node.
Inkscape::LayerManager & layerManager()
void setXMLDialogSelectedObject(SPObject *activexmltree)
Inkscape::XML::Node * getReprRoot()
Inkscape::XML::Document * getReprDoc()
Our Inkscape::XML::Document.
SPObject * getObjectByRepr(Inkscape::XML::Node *repr) const
SPObject is an abstract base class of all of the document nodes at the SVG document level.
void requestDisplayUpdate(unsigned int flags)
Queues an deferred update of this object's display.
Editable view implementation.
Event handler for dialog windows.
static char const *const parent
TODO: insert short description here.
Macro for icon names used in Inkscape.
Inkscape::XML::Node * node
static bool isRealLayer(SPObject const *object)
Like SPDesktop::isLayer(), but ignores SPGroup::effectiveLayerMode().
XMLStyles build_xml_styles(const Glib::ustring &syntax_theme)
Build XML styles from a GTKSourceView syntax color theme.
W & get_widget(const Glib::RefPtr< Gtk::Builder > &builder, const char *id)
Glib::RefPtr< Gtk::Builder > create_builder(const char *filename)
void trim(Glib::ustring &input, Glib::ustring const &also_remove="")
Modifies a string in place, removing leading and trailing whitespace characters.
@ COMMENT_NODE
Comment node, e.g. <!– some comment –>.
@ ELEMENT_NODE
Regular element node, e.g. <group />.
@ TEXT_NODE
Text node, e.g. "Some text" in <group>Some text</group> is represented by a text node.
static void append(std::vector< T > &target, std::vector< T > &&source)
MessageType
A hint about the meaning of a message; is it an ordinary message, a message advising the user of some...
@ HORIZONTAL
The x-dimension (0).
Helpers for using Gtk::Boxes, encapsulating large changes between GTK3 & GTK4.
Singleton class to access the preferences file in a convenient way.
void sp_repr_unparent(Inkscape::XML::Node *repr)
Remove repr from children of its parent node.
SPRoot: SVG <svg> implementation.
The styles used for simple XML syntax highlighting.
Interface for XML documents.
virtual Node * createTextNode(char const *content)=0
virtual Node * createElement(char const *name)=0
Inkscape::Util::trim - trim whitespace and other characters.
This is XML tree editor, which allows direct modifying of all elements of Inkscape document,...