summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJabiertxo Arraiza Cenoz <jtx@jtx-desktop.markerlab.es>2017-11-09 18:03:26 +0000
committerJabier Arraiza <jabier.arraiza@marker.es>2017-11-10 18:54:28 +0000
commitc78c92430c6a07adf448fe9ff8105f2935aa1d5e (patch)
treeaec68f124b3086df8b58056072dd8f82886ec8e9 /src
parentMerge branch 'master' into fixSymbolsCpuProblems (diff)
downloadinkscape-c78c92430c6a07adf448fe9ff8105f2935aa1d5e.tar.gz
inkscape-c78c92430c6a07adf448fe9ff8105f2935aa1d5e.zip
Add lock margins to document settings
Diffstat (limited to 'src')
-rw-r--r--src/ui/dialog/symbols.cpp.orig1364
-rw-r--r--src/ui/dialog/symbols.cpp.rej384
-rw-r--r--src/ui/dialog/symbols.h.orig172
-rw-r--r--src/ui/dialog/symbols.h.rej19
-rw-r--r--src/ui/widget/page-sizer.cpp45
-rw-r--r--src/ui/widget/page-sizer.h26
6 files changed, 1994 insertions, 16 deletions
diff --git a/src/ui/dialog/symbols.cpp.orig b/src/ui/dialog/symbols.cpp.orig
new file mode 100644
index 000000000..52f22103f
--- /dev/null
+++ b/src/ui/dialog/symbols.cpp.orig
@@ -0,0 +1,1364 @@
+/**
+ * @file
+ * Symbols dialog.
+ */
+/* Authors:
+ * Copyright (C) 2012 Tavmjong Bah
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <iostream>
+#include <algorithm>
+#include <locale>
+#include <sstream>
+
+#include <glibmm/regex.h>
+#include <glibmm/stringutils.h>
+#include <glibmm/markup.h>
+
+#include "path-prefix.h"
+#include "io/sys.h"
+#include "io/resource.h"
+
+#include "ui/cache/svg_preview_cache.h"
+#include "ui/clipboard.h"
+#include "ui/icon-names.h"
+
+#include "symbols.h"
+
+#include "selection.h"
+#include "desktop.h"
+
+#include "document.h"
+#include "inkscape.h"
+#include "sp-root.h"
+#include "sp-use.h"
+#include "sp-defs.h"
+#include "sp-symbol.h"
+
+#ifdef WITH_LIBVISIO
+ #include <libvisio/libvisio.h>
+
+ // TODO: Drop this check when librevenge is widespread.
+ #if WITH_LIBVISIO01
+ #include <librevenge-stream/librevenge-stream.h>
+
+ using librevenge::RVNGFileStream;
+ using librevenge::RVNGString;
+ using librevenge::RVNGStringVector;
+ using librevenge::RVNGPropertyList;
+ using librevenge::RVNGSVGDrawingGenerator;
+ #else
+ #include <libwpd-stream/libwpd-stream.h>
+
+ typedef WPXFileStream RVNGFileStream;
+ typedef libvisio::VSDStringVector RVNGStringVector;
+ #endif
+#endif
+
+#include "verbs.h"
+#include "helper/action.h"
+#include <glibmm/i18n.h>
+
+namespace Inkscape {
+namespace UI {
+
+namespace Dialog {
+
+// See: http://developer.gnome.org/gtkmm/stable/classGtk_1_1TreeModelColumnRecord.html
+class SymbolColumns : public Gtk::TreeModel::ColumnRecord
+{
+public:
+
+ Gtk::TreeModelColumn<Glib::ustring> symbol_id;
+ Gtk::TreeModelColumn<Glib::ustring> symbol_title;
+ Gtk::TreeModelColumn<Glib::ustring> symbol_doc_title;
+ Gtk::TreeModelColumn< Glib::RefPtr<Gdk::Pixbuf> > symbol_image;
+
+
+ SymbolColumns() {
+ add(symbol_id);
+ add(symbol_title);
+ add(symbol_doc_title);
+ add(symbol_image);
+ }
+};
+
+SymbolColumns* SymbolsDialog::getColumns()
+{
+ SymbolColumns* columns = new SymbolColumns();
+ return columns;
+}
+
+/**
+ * Constructor
+ */
+SymbolsDialog::SymbolsDialog( gchar const* prefsPath ) :
+ UI::Widget::Panel("", prefsPath, SP_VERB_DIALOG_SYMBOLS),
+ store(Gtk::ListStore::create(*getColumns())),
+ icon_view(0),
+ current_desktop(0),
+ desk_track(),
+ current_document(0),
+ preview_document(0),
+ instanceConns()
+{
+
+ /******************** Table *************************/
+ auto table = new Gtk::Grid();
+ table->set_margin_left(3);
+ table->set_margin_right(3);
+ table->set_margin_top(4);
+ // panel is a cloked Gtk::VBox
+ _getContents()->pack_start(*Gtk::manage(table), Gtk::PACK_EXPAND_WIDGET);
+ guint row = 0;
+
+ /******************** Symbol Sets *************************/
+ Gtk::Label* label_set = new Gtk::Label(_("Symbol set: "));
+ table->attach(*Gtk::manage(label_set),0,row,1,1);
+ symbol_set = new Gtk::ComboBoxText(); // Fill in later
+ symbol_set->append(_("Current Document"));
+ symbol_set->append(_("All symbols sets"));
+ symbol_set->set_active_text(_("Current Document"));
+ symbol_set->set_hexpand();
+
+ table->attach(*Gtk::manage(symbol_set),1,row,1,1);
+ sigc::connection connSet = symbol_set->signal_changed().connect(
+ sigc::mem_fun(*this, &SymbolsDialog::rebuild));
+ instanceConns.push_back(connSet);
+
+ ++row;
+
+ /******************** Separator *************************/
+
+
+ Gtk::Separator* separator = Gtk::manage(new Gtk::Separator()); // Search
+ separator->set_margin_top(10);
+ separator->set_margin_bottom(10);
+ table->attach(*Gtk::manage(separator),0,row,2,1);
+
+ ++row;
+
+ /******************** Search *************************/
+
+
+ search = Gtk::manage(new Gtk::SearchEntry()); // Search
+ search->set_tooltip_text(_("Return to start search."));
+ search->signal_key_press_event().connect_notify( sigc::mem_fun(*this, &SymbolsDialog::beforeSearch));
+ search->signal_key_release_event().connect_notify(sigc::mem_fun(*this, &SymbolsDialog::unsensitive));
+ search->set_margin_left(10);
+ search->set_margin_right(10);
+ search->set_margin_bottom(6);
+ search->signal_search_changed().connect(sigc::mem_fun(*this, &SymbolsDialog::clearSearch));
+ table->attach(*Gtk::manage(search),0,row,2,1);
+ search_str = "";
+
+ ++row;
+
+
+ /********************* Icon View **************************/
+ SymbolColumns* columns = getColumns();
+
+ icon_view = new Gtk::IconView(static_cast<Glib::RefPtr<Gtk::TreeModel> >(store));
+ //icon_view->set_text_column( columns->symbol_id );
+ icon_view->set_tooltip_column( 1 );
+ icon_view->set_pixbuf_column( columns->symbol_image );
+ // Giving the iconview a small minimum size will help users understand
+ // What the dialog does.
+ icon_view->set_size_request( 100, 250 );
+
+ std::vector< Gtk::TargetEntry > targets;
+ targets.push_back(Gtk::TargetEntry( "application/x-inkscape-paste"));
+
+ icon_view->enable_model_drag_source (targets, Gdk::BUTTON1_MASK, Gdk::ACTION_COPY);
+ icon_view->signal_drag_data_get().connect(
+ sigc::mem_fun(*this, &SymbolsDialog::iconDragDataGet));
+
+ sigc::connection connIconChanged;
+ connIconChanged = icon_view->signal_selection_changed().connect(
+ sigc::mem_fun(*this, &SymbolsDialog::iconChanged));
+ instanceConns.push_back(connIconChanged);
+
+ scroller = new Gtk::ScrolledWindow();
+ scroller->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS);
+ scroller->add(*Gtk::manage(icon_view));
+ scroller->set_hexpand();
+ scroller->set_vexpand();
+#if GTK_CHECK_VERSION(3,2,4)
+ overlay = new Gtk::Overlay();
+ overlay->set_hexpand();
+ overlay->set_vexpand();
+ overlay->add(* scroller);
+ scroller->set_size_request(100, 250);
+ table->attach(*Gtk::manage(overlay),0,row,2,1);
+#else
+ table->attach(*Gtk::manage(scroller),0,row,2,1);
+#endif
+ ++row;
+
+ /******************** Progress *******************************/
+ progress = new Gtk::HBox();
+ progress_bar = Gtk::manage(new Gtk::ProgressBar());
+ table->attach(*Gtk::manage(progress),0,row, 2, 1);
+ progress->pack_start(* progress_bar, Gtk::PACK_EXPAND_WIDGET);
+ progress->set_margin_top(15);
+ progress->set_margin_bottom(15);
+ progress->set_margin_left(20);
+ progress->set_margin_right(20);
+
+ ++row;
+
+ /******************** Tools *******************************/
+ tools = new Gtk::HBox();
+
+ //tools->set_layout( Gtk::BUTTONBOX_END );
+ scroller->set_hexpand();
+ table->attach(*Gtk::manage(tools),0,row,2,1);
+
+ auto add_symbol_image = Gtk::manage(new Gtk::Image());
+ add_symbol_image->set_from_icon_name("symbol-add", Gtk::ICON_SIZE_SMALL_TOOLBAR);
+
+ add_symbol = Gtk::manage(new Gtk::Button());
+ add_symbol->add(*add_symbol_image);
+ add_symbol->set_tooltip_text(_("Add Symbol from the current document."));
+ add_symbol->set_relief( Gtk::RELIEF_NONE );
+ add_symbol->set_focus_on_click( false );
+ add_symbol->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::insertSymbol));
+ tools->pack_start(* add_symbol, Gtk::PACK_SHRINK);
+
+ auto remove_symbolImage = Gtk::manage(new Gtk::Image());
+ remove_symbolImage->set_from_icon_name("symbol-remove", Gtk::ICON_SIZE_SMALL_TOOLBAR);
+
+ remove_symbol = Gtk::manage(new Gtk::Button());
+ remove_symbol->add(*remove_symbolImage);
+ remove_symbol->set_tooltip_text(_("Remove Symbol from the current document."));
+ remove_symbol->set_relief( Gtk::RELIEF_NONE );
+ remove_symbol->set_focus_on_click( false );
+ remove_symbol->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::revertSymbol));
+ tools->pack_start(* remove_symbol, Gtk::PACK_SHRINK);
+
+ Gtk::Label* spacer = Gtk::manage(new Gtk::Label(""));
+ tools->pack_start(* Gtk::manage(spacer));
+
+ // Pack size (controls display area)
+ pack_size = 2; // Default 32px
+
+ auto packMoreImage = Gtk::manage(new Gtk::Image());
+ packMoreImage->set_from_icon_name("pack-more", Gtk::ICON_SIZE_SMALL_TOOLBAR);
+
+ more = Gtk::manage(new Gtk::Button());
+ more->add(*packMoreImage);
+ more->set_tooltip_text(_("Display more icons in row."));
+ more->set_relief( Gtk::RELIEF_NONE );
+ more->set_focus_on_click( false );
+ more->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::packmore));
+ tools->pack_start(* more, Gtk::PACK_SHRINK);
+
+ auto packLessImage = Gtk::manage(new Gtk::Image());
+ packLessImage->set_from_icon_name("pack-less", Gtk::ICON_SIZE_SMALL_TOOLBAR);
+
+ fewer = Gtk::manage(new Gtk::Button());
+ fewer->add(*packLessImage);
+ fewer->set_tooltip_text(_("Display fewer icons in row."));
+ fewer->set_relief( Gtk::RELIEF_NONE );
+ fewer->set_focus_on_click( false );
+ fewer->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::packless));
+ tools->pack_start(* fewer, Gtk::PACK_SHRINK);
+
+ // Toggle scale to fit on/off
+ auto fit_symbolImage = Gtk::manage(new Gtk::Image());
+ fit_symbolImage->set_from_icon_name("symbol-fit", Gtk::ICON_SIZE_SMALL_TOOLBAR);
+
+ fit_symbol = Gtk::manage(new Gtk::ToggleButton());
+ fit_symbol->add(*fit_symbolImage);
+ fit_symbol->set_tooltip_text(_("Toggle 'fit' symbols in icon space."));
+ fit_symbol->set_relief( Gtk::RELIEF_NONE );
+ fit_symbol->set_focus_on_click( false );
+ fit_symbol->set_active( true );
+ fit_symbol->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::rebuild));
+ tools->pack_start(* fit_symbol, Gtk::PACK_SHRINK);
+
+ // Render size (scales symbols within display area)
+ scale_factor = 0; // Default 1:1 * pack_size/pack_size default
+ auto zoom_outImage = Gtk::manage(new Gtk::Image());
+ zoom_outImage->set_from_icon_name("symbol-smaller", Gtk::ICON_SIZE_SMALL_TOOLBAR);
+
+ zoom_out = Gtk::manage(new Gtk::Button());
+ zoom_out->add(*zoom_outImage);
+ zoom_out->set_tooltip_text(_("Make symbols smaller by zooming out."));
+ zoom_out->set_relief( Gtk::RELIEF_NONE );
+ zoom_out->set_focus_on_click( false );
+ zoom_out->set_sensitive( false );
+ zoom_out->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::zoomout));
+ tools->pack_start(* zoom_out, Gtk::PACK_SHRINK);
+
+ auto zoom_inImage = Gtk::manage(new Gtk::Image());
+ zoom_inImage->set_from_icon_name("symbol-bigger", Gtk::ICON_SIZE_SMALL_TOOLBAR);
+
+ zoom_in = Gtk::manage(new Gtk::Button());
+ zoom_in->add(*zoom_inImage);
+ zoom_in->set_tooltip_text(_("Make symbols bigger by zooming in."));
+ zoom_in->set_relief( Gtk::RELIEF_NONE );
+ zoom_in->set_focus_on_click( false );
+ zoom_in->set_sensitive( false );
+ zoom_in->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::zoomin));
+ tools->pack_start(* zoom_in, Gtk::PACK_SHRINK);
+
+ ++row;
+
+ sensitive = true;
+
+ current_desktop = SP_ACTIVE_DESKTOP;
+ current_document = current_desktop->getDocument();
+ preview_document = symbolsPreviewDoc(); /* Template to render symbols in */
+ preview_document->ensureUpToDate(); /* Necessary? */
+ key = SPItem::display_key_new(1);
+ renderDrawing.setRoot(preview_document->getRoot()->invoke_show(renderDrawing, key, SP_ITEM_SHOW_DISPLAY ));
+
+ // This might need to be a global variable so setTargetDesktop can modify it
+ SPDefs *defs = current_document->getDefs();
+
+ /*************************Overlays******************************/
+#if GTK_CHECK_VERSION(3,2,4)
+ //Loading
+ overlay_opacity = new Gtk::Image();
+ overlay_opacity->set(getOverlay(overlay_opacity, "overlay", 1000));
+ overlay_opacity->set_halign(Gtk::ALIGN_START );
+ overlay_opacity->set_valign(Gtk::ALIGN_START );
+ //No results
+ iconsize = Gtk::IconSize().register_new(Glib::ustring("ICON_SIZE_DIALOG_EXTRA"), 110, 110);
+ overlay_icon = new Gtk::Image();
+ overlay_icon->set_from_icon_name("none", iconsize);
+ overlay_icon = new Gtk::Image();
+ overlay_icon->set_halign(Gtk::ALIGN_CENTER );
+ overlay_icon->set_valign(Gtk::ALIGN_START );
+ overlay_icon->set_margin_top(45);
+ overlay_title = new Gtk::Label();
+ overlay_title->set_halign(Gtk::ALIGN_CENTER );
+ overlay_title->set_valign(Gtk::ALIGN_START );
+ overlay_title->set_justify(Gtk::JUSTIFY_CENTER);
+ overlay_title->set_margin_top(155);
+ overlay_title->set_markup(Glib::ustring("<span foreground=\"#333333\" size=\"large\">") + Glib::ustring(_("No results found")) + Glib::ustring("</span>"));
+ overlay_desc = new Gtk::Label();
+ overlay_desc->set_halign(Gtk::ALIGN_CENTER );
+ overlay_desc->set_valign(Gtk::ALIGN_START );
+ overlay_desc->set_margin_top(180);
+ overlay_desc->set_justify(Gtk::JUSTIFY_CENTER);
+ overlay_desc->set_markup(Glib::ustring("<span foreground=\"#333333\" size=\"small\">") + Glib::ustring(_("Try a another search or select other set")) + Glib::ustring("</span>"));
+ overlay->add_overlay(* overlay_opacity);
+ overlay->add_overlay(* overlay_icon);
+ overlay->add_overlay(* overlay_title);
+ overlay->add_overlay(* overlay_desc);
+#endif
+ sigc::connection defsModifiedConn = defs->connectModified(sigc::mem_fun(*this, &SymbolsDialog::defsModified));
+ instanceConns.push_back(defsModifiedConn);
+
+ sigc::connection selectionChangedConn = current_desktop->selection->connectChanged(
+ sigc::mem_fun(*this, &SymbolsDialog::selectionChanged));
+ instanceConns.push_back(selectionChangedConn);
+
+ sigc::connection documentReplacedConn = current_desktop->connectDocumentReplaced(
+ sigc::mem_fun(*this, &SymbolsDialog::documentReplaced));
+ instanceConns.push_back(documentReplacedConn);
+ getSymbolsFilename();
+ icons_found = false;
+
+ addSymbolsInDoc(current_document); /* Defaults to current document */
+ sigc::connection desktopChangeConn =
+ desk_track.connectDesktopChanged( sigc::mem_fun(*this, &SymbolsDialog::setTargetDesktop) );
+ instanceConns.push_back( desktopChangeConn );
+ desk_track.connect(GTK_WIDGET(gobj()));
+#if GTK_CHECK_VERSION(3,2,4)
+ overlay->hide();
+#endif
+}
+
+SymbolsDialog::~SymbolsDialog()
+{
+ for (std::vector<sigc::connection>::iterator it = instanceConns.begin(); it != instanceConns.end(); ++it) {
+ it->disconnect();
+ }
+ idleconn.disconnect();
+ instanceConns.clear();
+ desk_track.disconnect();
+}
+
+SymbolsDialog& SymbolsDialog::getInstance()
+{
+ return *new SymbolsDialog();
+}
+
+void SymbolsDialog::packless() {
+ if(pack_size < 4) {
+ pack_size++;
+ rebuild();
+ }
+}
+
+void SymbolsDialog::packmore() {
+ if(pack_size > 0) {
+ pack_size--;
+ rebuild();
+ }
+}
+
+void SymbolsDialog::zoomin() {
+ if(scale_factor < 4) {
+ scale_factor++;
+ rebuild();
+ }
+}
+
+void SymbolsDialog::zoomout() {
+ if(scale_factor > -8) {
+ scale_factor--;
+ rebuild();
+ }
+}
+
+void SymbolsDialog::rebuild() {
+
+ if (!sensitive) {
+ return;
+ }
+
+ if( fit_symbol->get_active() ) {
+ zoom_in->set_sensitive( false );
+ zoom_out->set_sensitive( false );
+ } else {
+ zoom_in->set_sensitive( true);
+ zoom_out->set_sensitive( true );
+ }
+ store->clear();
+ SPDocument* symbol_document = selectedSymbols();
+ icons_found = false;
+ //We are not in search all docs
+ if (search->get_text() != _("Searching...") &&
+ search->get_text() != _("Loading documents...") &&
+ search->get_text() != _("Documents done, searchig inside...") )
+ {
+ search_str = "";
+ search->set_text("");
+ }
+ if (symbol_document) {
+ addSymbolsInDoc(symbol_document);
+ } else {
+ idleconn.disconnect();
+ idleconn = Glib::signal_idle().connect( sigc::mem_fun(*this, &SymbolsDialog::callbackSymbols));
+ }
+}
+
+void SymbolsDialog::insertSymbol() {
+ Inkscape::Verb *verb = Inkscape::Verb::get( SP_VERB_EDIT_SYMBOL );
+ SPAction *action = verb->get_action(Inkscape::ActionContext( (Inkscape::UI::View::View *) current_desktop) );
+ sp_action_perform (action, NULL);
+}
+
+void SymbolsDialog::revertSymbol() {
+ Inkscape::Verb *verb = Inkscape::Verb::get( SP_VERB_EDIT_UNSYMBOL );
+ SPAction *action = verb->get_action(Inkscape::ActionContext( (Inkscape::UI::View::View *) current_desktop ) );
+ sp_action_perform (action, NULL);
+}
+
+void SymbolsDialog::iconDragDataGet(const Glib::RefPtr<Gdk::DragContext>& /*context*/, Gtk::SelectionData& data, guint /*info*/, guint /*time*/)
+{
+ auto iconArray = icon_view->get_selected_items();
+
+ if( iconArray.empty() ) {
+ //std::cout << " iconArray empty: huh? " << std::endl;
+ } else {
+ Gtk::TreeModel::Path const & path = *iconArray.begin();
+ Gtk::ListStore::iterator row = store->get_iter(path);
+ Glib::ustring symbol_id = (*row)[getColumns()->symbol_id];
+ GdkAtom dataAtom = gdk_atom_intern( "application/x-inkscape-paste", FALSE );
+ gtk_selection_data_set( data.gobj(), dataAtom, 9, (guchar*)symbol_id.c_str(), symbol_id.length() );
+ }
+
+}
+
+void SymbolsDialog::defsModified(SPObject * /*object*/, guint /*flags*/)
+{
+ Glib::ustring doc_title = symbol_set->get_active_text();
+ if (doc_title != _("All symbols sets") && !symbol_sets[symbol_set->get_active_text()] ) {
+ rebuild();
+ }
+}
+
+void SymbolsDialog::selectionChanged(Inkscape::Selection *selection) {
+ Glib::ustring symbol_id = selectedSymbolId();
+ Glib::ustring doc_title = selectedSymbolDocTitle();
+ if (!doc_title.empty()) {
+ SPDocument* symbol_document = symbol_sets[doc_title];
+ if (!symbol_document) {
+ //we are in global search so get the original symbol document by title
+ symbol_document = selectedSymbols();
+ }
+ if (symbol_document) {
+ SPObject* symbol = symbol_document->getObjectById(symbol_id);
+ if(symbol && !selection->includes(symbol)) {
+ icon_view->unselect_all();
+ }
+ }
+ }
+}
+
+void SymbolsDialog::documentReplaced(SPDesktop *desktop, SPDocument *document)
+{
+ current_desktop = desktop;
+ current_document = document;
+ rebuild();
+}
+
+SPDocument* SymbolsDialog::selectedSymbols() {
+ /* OK, we know symbol name... now we need to copy it to clipboard, bon chance! */
+ Glib::ustring doc_title = symbol_set->get_active_text();
+ if (doc_title == _("All symbols sets")) {
+ return NULL;
+ }
+ SPDocument* symbol_document = symbol_sets[doc_title];
+ if( !symbol_document ) {
+ symbol_document = getSymbolsSet(doc_title).second;
+ // Symbol must be from Current Document (this method of checking should be language independent).
+ if( !symbol_document ) {
+ // Symbol must be from Current Document (this method of
+ // checking should be language independent).
+ symbol_document = current_document;
+ add_symbol->set_sensitive( true );
+ remove_symbol->set_sensitive( true );
+ } else {
+ add_symbol->set_sensitive( false );
+ remove_symbol->set_sensitive( false );
+ }
+ }
+ return symbol_document;
+}
+
+Glib::ustring SymbolsDialog::selectedSymbolId() {
+
+ auto iconArray = icon_view->get_selected_items();
+
+ if( !iconArray.empty() ) {
+ Gtk::TreeModel::Path const & path = *iconArray.begin();
+ Gtk::ListStore::iterator row = store->get_iter(path);
+ return (*row)[getColumns()->symbol_id];
+ }
+ return Glib::ustring("");
+}
+
+Glib::ustring SymbolsDialog::selectedSymbolDocTitle() {
+
+ auto iconArray = icon_view->get_selected_items();
+
+ if( !iconArray.empty() ) {
+ Gtk::TreeModel::Path const & path = *iconArray.begin();
+ Gtk::ListStore::iterator row = store->get_iter(path);
+ return (*row)[getColumns()->symbol_doc_title];
+ }
+ return Glib::ustring("");
+}
+
+Glib::ustring SymbolsDialog::documentTitle(SPDocument* symbol_doc) {
+ Glib::ustring title = _("Untitled document");
+ if (symbol_doc) {
+ SPRoot * root = symbol_doc->getRoot();
+ if (root->title()) {
+ title = ellipsize(Glib::ustring(root->title()));
+ return title;
+ }
+ }
+ Glib::ustring current = symbol_set->get_active_text();
+ if (current == _("Current Document")) {
+ return current;
+ }
+ return title;
+}
+
+void SymbolsDialog::iconChanged() {
+
+ Glib::ustring symbol_id = selectedSymbolId();
+ SPDocument* symbol_document = selectedSymbols();
+ if (!symbol_document) {
+ //we are in global search so get the original symbol document by title
+ Glib::ustring doc_title = selectedSymbolDocTitle();
+ if (!doc_title.empty()) {
+ symbol_document = symbol_sets[doc_title];
+ }
+ }
+ if (symbol_document) {
+ SPObject* symbol = symbol_document->getObjectById(symbol_id);
+
+ if( symbol ) {
+ if( symbol_document == current_document ) {
+ // Select the symbol on the canvas so it can be manipulated
+ current_desktop->selection->set( symbol, false );
+ }
+ // Find style for use in <use>
+ // First look for default style stored in <symbol>
+ gchar const* style = symbol->getAttribute("inkscape:symbol-style");
+ if( !style ) {
+ // If no default style in <symbol>, look in documents.
+ if( symbol_document == current_document ) {
+ style = styleFromUse( symbol_id.c_str(), current_document );
+ } else {
+ style = symbol_document->getReprRoot()->attribute("style");
+ }
+ }
+
+ ClipboardManager *cm = ClipboardManager::get();
+ cm->copySymbol(symbol->getRepr(), style, symbol_document == current_document);
+ }
+ }
+}
+
+#ifdef WITH_LIBVISIO
+
+#if WITH_LIBVISIO01
+// Extend libvisio's native RVNGSVGDrawingGenerator with support for extracting stencil names (to be used as ID/title)
+class REVENGE_API RVNGSVGDrawingGenerator_WithTitle : public RVNGSVGDrawingGenerator {
+ public:
+ RVNGSVGDrawingGenerator_WithTitle(RVNGStringVector &output, RVNGStringVector &titles, const RVNGString &nmSpace)
+ : RVNGSVGDrawingGenerator(output, nmSpace)
+ , _titles(titles)
+ {}
+
+ void startPage(const RVNGPropertyList &propList)
+ {
+ RVNGSVGDrawingGenerator::startPage(propList);
+ if (propList["draw:name"]) {
+ _titles.append(propList["draw:name"]->getStr());
+ } else {
+ _titles.append("");
+ }
+ }
+
+ private:
+ RVNGStringVector &_titles;
+};
+#endif
+
+// Read Visio stencil files
+SPDocument* read_vss(Glib::ustring filename, Glib::ustring name ) {
+ gchar *fullname;
+ #ifdef WIN32
+ // RVNGFileStream uses fopen() internally which unfortunately only uses ANSI encoding on Windows
+ // therefore attempt to convert uri to the system codepage
+ // even if this is not possible the alternate short (8.3) file name will be used if available
+ fullname = g_win32_locale_filename_from_utf8(filename.c_str());
+ #else
+ filename.copy(fullname, filename.length());
+ #endif
+
+ RVNGFileStream input(fullname);
+ g_free(fullname);
+
+ if (!libvisio::VisioDocument::isSupported(&input)) {
+ return NULL;
+ }
+
+ RVNGStringVector output;
+ RVNGStringVector titles;
+#if WITH_LIBVISIO01
+ RVNGSVGDrawingGenerator_WithTitle generator(output, titles, "svg");
+
+ if (!libvisio::VisioDocument::parseStencils(&input, &generator)) {
+#else
+ if (!libvisio::VisioDocument::generateSVGStencils(&input, output)) {
+#endif
+ return NULL;
+ }
+
+ if (output.empty()) {
+ return NULL;
+ }
+
+ // prepare a valid title for the symbol file
+ Glib::ustring title = Glib::Markup::escape_text(name);
+ // prepare a valid id prefix for symbols libvisio doesn't give us a name for
+ Glib::RefPtr<Glib::Regex> regex1 = Glib::Regex::create("[^a-zA-Z0-9_-]");
+ Glib::ustring id = regex1->replace(name, 0, "_", Glib::REGEX_MATCH_PARTIAL);
+
+ Glib::ustring tmpSVGOutput;
+ tmpSVGOutput += "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n";
+ tmpSVGOutput += "<svg\n";
+ tmpSVGOutput += " xmlns=\"http://www.w3.org/2000/svg\"\n";
+ tmpSVGOutput += " xmlns:svg=\"http://www.w3.org/2000/svg\"\n";
+ tmpSVGOutput += " xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n";
+ tmpSVGOutput += " version=\"1.1\"\n";
+ tmpSVGOutput += " style=\"fill:none;stroke:#000000;stroke-width:2\">\n";
+ tmpSVGOutput += " <title>";
+ tmpSVGOutput += title;
+ tmpSVGOutput += "</title>\n";
+ tmpSVGOutput += " <defs>\n";
+
+ // Each "symbol" is in its own SVG file, we wrap with <symbol> and merge into one file.
+ for (unsigned i=0; i<output.size(); ++i) {
+
+ std::stringstream ss;
+ if (titles.size() == output.size() && titles[i] != "") {
+ // TODO: Do we need to check for duplicated titles?
+ ss << regex1->replace(titles[i].cstr(), 0, "_", Glib::REGEX_MATCH_PARTIAL);
+ } else {
+ ss << id << "_" << i;
+ }
+
+ tmpSVGOutput += " <symbol id=\"" + ss.str() + "\">\n";
+
+#if WITH_LIBVISIO01
+ if (titles.size() == output.size() && titles[i] != "") {
+ tmpSVGOutput += " <title>" + Glib::ustring(RVNGString::escapeXML(titles[i].cstr()).cstr()) + "</title>\n";
+ }
+#endif
+
+ std::istringstream iss( output[i].cstr() );
+ std::string line;
+ while( std::getline( iss, line ) ) {
+ if( line.find( "svg:svg" ) == std::string::npos ) {
+ tmpSVGOutput += " " + line + "\n";
+ }
+ }
+
+ tmpSVGOutput += " </symbol>\n";
+ }
+
+ tmpSVGOutput += " </defs>\n";
+ tmpSVGOutput += "</svg>\n";
+
+ return SPDocument::createNewDocFromMem( tmpSVGOutput.c_str(), strlen( tmpSVGOutput.c_str()), 0 );
+
+}
+#endif
+
+/* Hunts preference directories for symbol files */
+void SymbolsDialog::getSymbolsFilename() {
+
+ using namespace Inkscape::IO::Resource;
+ Glib::ustring title;
+ number_docs = 0;
+ for(auto &filename: get_filenames(SYMBOLS, {".svg", ".vss"})) {
+ if(Glib::str_has_suffix(filename, ".svg")) {
+ //TODO: find a way to get real title without loading all SPDocument
+ std::size_t found = filename.find_last_of("/\\");
+ filename = filename.substr(found+1);
+ title = filename.erase(filename.rfind('.'));
+ if(title.empty()) {
+ title = _("Unnamed Symbols");
+ }
+ symbol_sets[title]= NULL;
+ symbol_set->append(title);
+ ++number_docs;
+ }
+#ifdef WITH_LIBVISIO
+ if(Glib::str_has_suffix(filename, ".vss")) {
+ std::size_t found = filename.find_last_of("/\\");
+ filename = filename.substr(found+1);
+ title = filename.erase(filename.rfind('.'));
+ if(title.empty()) {
+ title = _("Unnamed Symbols");
+ }
+ symbol_sets[title]= NULL;
+ symbol_set->append(title);
+ ++number_docs;
+ }
+#endif
+ }
+}
+
+/* Hunts preference directories for symbol files */
+std::pair<Glib::ustring, SPDocument*>
+SymbolsDialog::getSymbolsSet(Glib::ustring title)
+{
+ if (symbol_sets[title]) {
+ return std::make_pair(title, symbol_sets[title]);
+ }
+ using namespace Inkscape::IO::Resource;
+ SPDocument* symbol_doc = NULL;
+ Glib::ustring new_title;
+ size_t i = 0;
+ for(auto &filename: get_filenames(SYMBOLS, {".svg", ".vss"})) {
+ std::size_t pos = filename.find_last_of("/\\");
+ if (pos != std::string::npos) {
+ Glib::ustring filename_short = filename.substr(pos+1);
+ if(filename_short == title + ".svg") {
+ symbol_doc = SPDocument::createNewDoc(filename.c_str(), FALSE);
+ if(symbol_doc) {
+ new_title = documentTitle(symbol_doc);
+ }
+ }
+ if(Glib::str_has_suffix(filename, ".svg")) {
+ i++;
+ }
+#ifdef WITH_LIBVISIO
+ if(filename_short == title + ".vss") {
+ symbol_doc = read_vss(filename, title);
+ if(symbol_doc) {
+ new_title = documentTitle(symbol_doc);
+ }
+ }
+ if(Glib::str_has_suffix(filename, ".vss")) {
+ i++;
+ }
+#endif
+ if(symbol_doc) {
+ symbol_sets.erase(title);
+ symbol_sets[new_title]= symbol_doc;
+ sensitive = false;
+ symbol_set->remove_text(i+1);
+ symbol_set->insert (i+1, new_title);
+ symbol_set->set_active(i+1);
+ symbol_set->set_active_text(new_title);
+ sensitive = true;
+ break;
+ }
+ }
+ }
+ return std::make_pair(new_title, symbol_doc);
+}
+
+void SymbolsDialog::symbolsInDocRecursive (SPObject *r, std::vector<std::pair<Glib::ustring, SPSymbol*> > &l, Glib::ustring doc_title)
+{
+ if(!r) return;
+
+ // Stop multiple counting of same symbol
+ if ( dynamic_cast<SPUse *>(r) ) {
+ return;
+ }
+
+ if ( dynamic_cast<SPSymbol *>(r) ) {
+ l.push_back(std::make_pair(doc_title,dynamic_cast<SPSymbol *>(r)));
+ }
+ for (auto& child: r->children) {
+ symbolsInDocRecursive(&child, l, doc_title);
+ }
+}
+
+std::vector<std::pair<Glib::ustring, SPSymbol*> >
+SymbolsDialog::symbolsInDoc( SPDocument* symbol_document, Glib::ustring doc_title)
+{
+
+ std::vector<std::pair<Glib::ustring, SPSymbol*> > l;
+ if (symbol_document) {
+ symbolsInDocRecursive (symbol_document->getRoot(), l , doc_title);
+ }
+ return l;
+}
+
+void SymbolsDialog::useInDoc (SPObject *r, std::vector<SPUse*> &l)
+{
+
+ if ( dynamic_cast<SPUse *>(r) ) {
+ l.push_back(dynamic_cast<SPUse *>(r));
+ }
+
+ for (auto& child: r->children) {
+ useInDoc( &child, l );
+ }
+}
+
+std::vector<SPUse*> SymbolsDialog::useInDoc( SPDocument* useDocument) {
+ std::vector<SPUse*> l;
+ useInDoc (useDocument->getRoot(), l);
+ return l;
+}
+
+// Returns style from first <use> element found that references id.
+// This is a last ditch effort to find a style.
+gchar const* SymbolsDialog::styleFromUse( gchar const* id, SPDocument* document) {
+
+ gchar const* style = 0;
+ std::vector<SPUse*> l = useInDoc( document );
+ for( auto use:l ) {
+ if ( use ) {
+ gchar const *href = use->getRepr()->attribute("xlink:href");
+ if( href ) {
+ Glib::ustring href2(href);
+ Glib::ustring id2(id);
+ id2 = "#" + id2;
+ if( !href2.compare(id2) ) {
+ style = use->getRepr()->attribute("style");
+ break;
+ }
+ }
+ }
+ }
+ return style;
+}
+
+void SymbolsDialog::clearSearch()
+{
+ if(search->get_text().empty() && sensitive) {
+ enableWidgets(false);
+ search_str = "";
+ store->clear();
+ SPDocument* symbol_document = selectedSymbols();
+ if (symbol_document) {
+ //We are not in search all docs
+ icons_found = false;
+ addSymbolsInDoc(symbol_document);
+ } else {
+ idleconn.disconnect();
+ idleconn = Glib::signal_idle().connect( sigc::mem_fun(*this, &SymbolsDialog::callbackSymbols));
+ enableWidgets(true);
+ }
+ }
+}
+
+void SymbolsDialog::enableWidgets(bool enable)
+{
+ symbol_set->set_sensitive(enable);
+ search->set_sensitive(enable);
+ tools ->set_sensitive(enable);
+}
+
+void SymbolsDialog::beforeSearch(GdkEventKey* evt)
+{
+ sensitive = false;
+ search_str = search->get_text().lowercase();
+ if (evt->keyval != GDK_KEY_Return) {
+ return;
+ }
+ progress_bar->set_fraction(0.0);
+ enableWidgets(false);
+ SPDocument* symbol_document = selectedSymbols();
+ if (symbol_document) {
+ //We are not in search all docs
+ search->set_text(_("Searching..."));
+ store->clear();
+ icons_found = false;
+ addSymbolsInDoc(symbol_document);
+ } else {
+ idleconn.disconnect();
+ idleconn = Glib::signal_idle().connect( sigc::mem_fun(*this, &SymbolsDialog::callbackSymbols));
+ search->set_text(_("Loading documents..."));
+ }
+}
+
+void SymbolsDialog::unsensitive(GdkEventKey* evt)
+{
+ sensitive = true;
+}
+
+bool SymbolsDialog::callbackSymbols(){
+ Glib::ustring current = symbol_set->get_active_text();
+
+#if GTK_CHECK_VERSION(3,2,4)
+if (current == _("All symbols sets") && search->get_text() != _("Loading documents...") && !l.size())
+ {
+ if (!all_docs_processed ) {
+ overlay_title->set_markup(Glib::ustring("<span foreground=\"#333333\" size=\"large\">") + Glib::ustring(_("Searching in all symbol sets ...")) + Glib::ustring("</span>"));
+ overlay_desc->set_markup(Glib::ustring("<span foreground=\"#333333\" size=\"small\">") + Glib::ustring(_("When run for the first time,\n search will be slow.\nPlease wait ...")) + Glib::ustring("</span>"));
+ } else {
+ overlay_title->set_markup(Glib::ustring("<span foreground=\"#333333\" size=\"large\">") + Glib::ustring(_("All symbol sets ...")) + Glib::ustring("</span>"));
+ overlay_desc->set_markup(Glib::ustring("<span foreground=\"#333333\" size=\"small\">") + Glib::ustring(_("We have all symbols preloaded,\n search is faster now ...")) + Glib::ustring("</span>"));
+ }
+ overlay_opacity->show();
+ overlay_icon->set_from_icon_name("none", iconsize);
+ overlay_icon->show();
+ overlay_title->show();
+ overlay_desc->show();
+ return false;
+ }
+#endif
+ if (current == _("All symbols sets") && search->get_text() == _("Loading documents...")) {
+#if GTK_CHECK_VERSION(3,2,4)
+ overlay_opacity->show();
+#endif
+ if (!all_docs_processed) {
+#if GTK_CHECK_VERSION(3,2,4)
+ overlay_title->set_markup(Glib::ustring("<span foreground=\"#333333\" size=\"large\">") + Glib::ustring(_("Loading all symbol sets ...")) + Glib::ustring("</span>"));
+ overlay_desc->set_markup(Glib::ustring("<span foreground=\"#333333\" size=\"small\">")+ Glib::ustring(_("When run for the first time, search will be slow.\nPlease wait ...")) + Glib::ustring("</span>"));
+ overlay_icon->show();
+ overlay_title->show();
+ overlay_icon->set_from_icon_name("searching", iconsize);
+ overlay_desc->show();
+#endif
+ }
+ size_t counter = 0;
+ for(auto const &symbol_document_map : symbol_sets) {
+ ++counter;
+ SPDocument* symbol_document = symbol_document_map.second;
+ if (symbol_document) {
+ continue;
+ }
+ symbol_document = getSymbolsSet(symbol_document_map.first).second;
+ symbol_set->set_active_text(_("All symbols sets"));
+ if (!symbol_document) {
+ continue;
+ }
+ progress_bar->set_fraction(((100.0/number_docs) * counter)/100.0);
+ return true;
+ }
+#if GTK_CHECK_VERSION(3,2,4)
+ overlay_icon->hide();
+ overlay_title->hide();
+ overlay_desc->hide();
+#endif
+ progress_bar->set_fraction(1.0);
+ all_docs_processed = true;
+ addSymbols();
+ search->set_text("Documents done, searchig inside...");
+ return true;
+ } else if (l.size()) {
+#if GTK_CHECK_VERSION(3,2,4)
+ overlay_opacity->show();
+ overlay_icon->hide();
+ overlay_title->hide();
+ overlay_desc->hide();
+#endif
+ for (auto symbol_data = l.begin(); symbol_data != l.end();) {
+ Glib::ustring doc_title = symbol_data->first;
+ SPSymbol * symbol = symbol_data->second;
+ counter_symbols ++;
+ gchar const *symbol_title_char = symbol->title();
+ gchar const *symbol_desc_char = symbol->description();
+ bool found = false;
+ if (symbol_title_char) {
+ Glib::ustring symbol_title = Glib::ustring(symbol_title_char).lowercase();
+ auto pos = symbol_title.rfind(search_str);
+ if (pos != std::string::npos) {
+ found = true;
+ }
+ if (!found && symbol_desc_char) {
+ Glib::ustring symbol_desc = Glib::ustring(symbol_desc_char).lowercase();
+ auto pos = symbol_desc.rfind(search_str);
+ if (pos != std::string::npos) {
+ found = true;
+ }
+ }
+ }
+ if (symbol && (search_str.empty() || found || (search_str.empty() && !symbol_title_char))) {
+ addSymbol( symbol, doc_title);
+ icons_found = true;
+ }
+
+ progress_bar->set_fraction(((100.0/number_symbols) * counter_symbols)/100.0);
+ symbol_data = l.erase(l.begin());
+ //to get more items and best performance
+ int modulus = number_symbols > 200 ? 50 : (number_symbols/4);
+ if (modulus && counter_symbols % modulus == 0 && !l.empty()) {
+ return true;
+ }
+ }
+#if GTK_CHECK_VERSION(3,2,4)
+ if (!icons_found && !search_str.empty()) {
+ overlay_title->set_markup(Glib::ustring("<span foreground=\"#333333\" size=\"large\">") + Glib::ustring(_("No results found")) + Glib::ustring("</span>"));
+ overlay_desc->set_markup(Glib::ustring("<span foreground=\"#333333\" size=\"small\">") + Glib::ustring(_("You could try a different search term,\nor switch to a different symbol set.")) + Glib::ustring("</span>"));
+ overlay_icon->set_from_icon_name("none", iconsize);
+ overlay_icon->show();
+ overlay_title->show();
+ overlay_desc->show();
+ } else {
+ overlay_opacity->hide();
+ }
+#endif
+ sensitive = false;
+ search->set_text(search_str);
+ sensitive = true;
+ enableWidgets(true);
+ return false;
+ }
+ return true;
+}
+
+Glib::ustring SymbolsDialog::ellipsize(Glib::ustring data, size_t limit) {
+ if (data.length() > limit) {
+ return data.substr(0,limit-3) + "...";
+ }
+ return data;
+}
+
+void SymbolsDialog::addSymbolsInDoc(SPDocument* symbol_document) {
+
+ if (!symbol_document) {
+ return; //Search all
+ }
+ Glib::ustring doc_title = documentTitle(symbol_document);
+ progress_bar->set_fraction(0.0);
+ counter_symbols = 0;
+ std::vector<std::pair<Glib::ustring, SPSymbol*> > container_symbols_tmp = symbolsInDoc(symbol_document, doc_title);
+ number_symbols = container_symbols_tmp.size();
+ l = container_symbols_tmp;
+ container_symbols_tmp.clear();
+ if (!number_symbols) {
+#if GTK_CHECK_VERSION(3,2,4)
+ overlay_icon->set_from_icon_name("none", iconsize);
+ overlay_opacity->show();
+ overlay_icon->show();
+ overlay_title->show();
+ overlay_desc->show();
+#endif
+ sensitive = false;
+ search->set_text(search_str);
+ sensitive = true;
+ enableWidgets(true);
+ idleconn.disconnect();
+ } else {
+ idleconn.disconnect();
+ idleconn = Glib::signal_idle().connect( sigc::mem_fun(*this, &SymbolsDialog::callbackSymbols));
+ }
+#if GTK_CHECK_VERSION(3,2,4)
+ Glib::ustring current = symbol_set->get_active_text();
+ if (!number_symbols && (current != _("Current Document") || !search_str.empty())) {
+ overlay_title->set_markup(Glib::ustring("<span foreground=\"#333333\" size=\"large\">") + Glib::ustring(_("No results found")) + Glib::ustring("</span>"));
+ overlay_desc->set_markup(Glib::ustring("<span foreground=\"#333333\" size=\"small\">") + Glib::ustring(_("You could try a different search term,\nor switch to a different symbol set.")) + Glib::ustring("</span>"));
+ } else if (!number_symbols) {
+ overlay_title->set_markup(Glib::ustring("<span foreground=\"#333333\"size=\"large\">") + Glib::ustring(_("No symbols found")) + Glib::ustring("</span>"));
+ overlay_desc->set_markup(Glib::ustring("<span foreground=\"#333333\" size=\"small\">") + Glib::ustring(_("No symbols in current document.\nYou could create in the current document\n or add into from other different symbol set.")) + Glib::ustring("</span>"));
+ }
+#endif
+}
+
+void SymbolsDialog::addSymbols() {
+ store->clear();
+ icons_found = false;
+ std::vector<std::pair<Glib::ustring, SPSymbol*> > container_symbols;
+ for(auto const &symbol_document_map : symbol_sets) {
+ SPDocument* symbol_document = symbol_document_map.second;
+ if (!symbol_document) {
+ continue;
+ }
+ Glib::ustring doc_title = documentTitle(symbol_document);
+ std::vector<std::pair<Glib::ustring, SPSymbol*> > container_symbols_tmp = symbolsInDoc(symbol_document, doc_title);
+ container_symbols.insert(container_symbols.end(), std::make_move_iterator(container_symbols_tmp.begin()), std::make_move_iterator(container_symbols_tmp.end()));
+ container_symbols_tmp.clear();
+ }
+ counter_symbols = 0;
+ progress_bar->set_fraction(0.0);
+ number_symbols = container_symbols.size();
+ l = container_symbols;
+ container_symbols.clear();
+ if (!number_symbols) {
+#if GTK_CHECK_VERSION(3,2,4)
+ overlay_icon->set_from_icon_name("none", iconsize);
+ overlay_title->set_markup(Glib::ustring("<span foreground=\"#333333\" size=\"large\">") + Glib::ustring(_("No results found")) + Glib::ustring("</span>"));
+ overlay_desc->set_markup(Glib::ustring("<span foreground=\"#333333\" size=\"small\">") + Glib::ustring(_("You could try a different search term,\nor switch to a different symbol set.")) + Glib::ustring("</span>"));
+ overlay_icon->show();
+ overlay_title->show();
+ overlay_desc->show();
+#endif
+ idleconn.disconnect();
+ sensitive = false;
+ search->set_text(search_str);
+ sensitive = true;
+ enableWidgets(true);
+ }
+}
+
+void SymbolsDialog::addSymbol( SPObject* symbol, Glib::ustring doc_title) {
+
+ SymbolColumns* columns = getColumns();
+
+ gchar const *id = symbol->getRepr()->attribute("id");
+ gchar const *title = symbol->title(); // From title element
+ if( !title ) {
+ title = id;
+ }
+ Glib::ustring symbol_title = Glib::Markup::escape_text(Glib::ustring( g_dpgettext2(NULL, "Symbol", title) ));
+ if (doc_title.empty()) {
+ doc_title = _("Current Document");
+ }
+ symbol_title = symbol_title + Glib::Markup::escape_text(Glib::ustring(g_dpgettext2(NULL, "Symbol", (Glib::ustring(" (") + doc_title + Glib::ustring(")")).c_str())));
+ Glib::RefPtr<Gdk::Pixbuf> pixbuf = drawSymbol( symbol );
+
+ if( pixbuf ) {
+ Gtk::ListStore::iterator row = store->append();
+ (*row)[columns->symbol_id] = Glib::ustring( id );
+ (*row)[columns->symbol_title] = symbol_title;
+ (*row)[columns->symbol_doc_title] = Glib::Markup::escape_text(doc_title);
+ (*row)[columns->symbol_image] = pixbuf;
+ }
+
+ delete columns;
+}
+
+/*
+ * Returns image of symbol.
+ *
+ * Symbols normally are not visible. They must be referenced by a
+ * <use> element. A temporary document is created with a dummy
+ * <symbol> element and a <use> element that references the symbol
+ * element. Each real symbol is swapped in for the dummy symbol and
+ * the temporary document is rendered.
+ */
+Glib::RefPtr<Gdk::Pixbuf>
+SymbolsDialog::drawSymbol(SPObject *symbol, unsigned force_psize)
+{
+ // Create a copy repr of the symbol with id="the_symbol"
+ Inkscape::XML::Document *xml_doc = preview_document->getReprDoc();
+ Inkscape::XML::Node *repr = symbol->getRepr()->duplicate(xml_doc);
+ repr->setAttribute("id", "the_symbol");
+
+ // Replace old "the_symbol" in preview_document by new.
+ Inkscape::XML::Node *root = preview_document->getReprRoot();
+ SPObject *symbol_old = preview_document->getObjectById("the_symbol");
+ if (symbol_old) {
+ symbol_old->deleteObject(false);
+ }
+
+ // First look for default style stored in <symbol>
+ gchar const* style = repr->attribute("inkscape:symbol-style");
+ if( !style ) {
+ // If no default style in <symbol>, look in documents.
+ if( symbol->document == current_document ) {
+ gchar const *id = symbol->getRepr()->attribute("id");
+ style = styleFromUse( id, symbol->document );
+ } else {
+ style = symbol->document->getReprRoot()->attribute("style");
+ }
+ }
+ // Last ditch effort to provide some default styling
+ if( !style ) style = "fill:#bbbbbb;stroke:#808080";
+
+ // This is for display in Symbols dialog only
+ if( style ) repr->setAttribute( "style", style );
+
+ // BUG: Symbols don't work if defined outside of <defs>. Causes Inkscape
+ // crash when trying to read in such a file.
+ root->appendChild(repr);
+ //defsrepr->appendChild(repr);
+ Inkscape::GC::release(repr);
+
+ // Uncomment this to get the preview_document documents saved (useful for debugging)
+ // FILE *fp = fopen (g_strconcat(id, ".svg", NULL), "w");
+ // sp_repr_save_stream(preview_document->getReprDoc(), fp);
+ // fclose (fp);
+
+ // Make sure preview_document is up-to-date.
+ preview_document->getRoot()->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+ preview_document->ensureUpToDate();
+
+ // Make sure we have symbol in preview_document
+ SPObject *object_temp = preview_document->getObjectById( "the_use" );
+ preview_document->getRoot()->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+ preview_document->ensureUpToDate();
+
+ SPItem *item = dynamic_cast<SPItem *>(object_temp);
+ g_assert(item != NULL);
+ unsigned psize = SYMBOL_ICON_SIZES[pack_size];
+
+ Glib::RefPtr<Gdk::Pixbuf> pixbuf(NULL);
+ // We could use cache here, but it doesn't really work with the structure
+ // of this user interface and we've already cached the pixbuf in the gtklist
+
+ // Find object's bbox in document.
+ // Note symbols can have own viewport... ignore for now.
+ //Geom::OptRect dbox = item->geometricBounds();
+ Geom::OptRect dbox = item->documentVisualBounds();
+
+ if (dbox) {
+ /* Scale symbols to fit */
+ double scale = 1.0;
+ double width = dbox->width();
+ double height = dbox->height();
+
+ if( width == 0.0 ) width = 1.0;
+ if( height == 0.0 ) height = 1.0;
+
+ if( fit_symbol->get_active() )
+ scale = psize / ceil(std::max(width, height));
+ else
+ scale = pow( 2.0, scale_factor/2.0 ) * psize / 32.0;
+
+ if (force_psize > 0) {
+ psize = force_psize;
+ scale = psize / ceil(std::max(width, height));
+ }
+
+ pixbuf = Glib::wrap(render_pixbuf(renderDrawing, scale, *dbox, psize));
+ }
+
+ return pixbuf;
+}
+
+/*
+ * Return empty doc to render symbols in.
+ * Symbols are by default not rendered so a <use> element is
+ * provided.
+ */
+SPDocument* SymbolsDialog::symbolsPreviewDoc()
+{
+ // BUG: <symbol> must be inside <defs>
+ gchar const *buffer =
+"<svg xmlns=\"http://www.w3.org/2000/svg\""
+" xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\""
+" xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\""
+" xmlns:xlink=\"http://www.w3.org/1999/xlink\">"
+" <defs id=\"defs\">"
+" <symbol id=\"the_symbol\"/>"
+" </defs>"
+" <use id=\"the_use\" xlink:href=\"#the_symbol\"/>"
+"</svg>";
+ return SPDocument::createNewDocFromMem( buffer, strlen(buffer), FALSE );
+}
+
+/*
+ * Update image widgets
+ */
+Glib::RefPtr<Gdk::Pixbuf>
+SymbolsDialog::getOverlay(Gtk::Image* image, gchar const * icon_title, unsigned psize)
+{
+gchar const *buffer =
+"<svg xmlns=\"http://www.w3.org/2000/svg\""
+" xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\""
+" xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\""
+" xmlns:xlink=\"http://www.w3.org/1999/xlink\">"
+" <title>Inkscape</title> "
+" <defs id=\"defs\">"
+" <symbol"
+" id=\"overlay\">"
+" <title"
+" id=\"overlay_title\">Overlay</title>"
+" <desc"
+" id=\"overlay_desc\">Overlay Square</desc>"
+" <path"
+" style=\"fill:#ffffff;opacity:0.75;stroke:none\""
+" d=\"M 0,1 H 1 V 2 H 0 Z\""
+" id=\"overlay_shape_1\" />"
+" </symbol>"
+" </defs>"
+"</svg>";
+
+ SPDocument* doc = SPDocument::createNewDocFromMem( buffer, strlen(buffer), FALSE );
+ std::vector<std::pair<Glib::ustring, SPSymbol*> > symbols_data = symbolsInDoc(doc, "Overlay Doc");
+ Glib::RefPtr<Gdk::Pixbuf> pixbuf(NULL);
+ for(auto data:symbols_data) {
+ Glib::ustring doc_title = data.first;
+ SPSymbol * symbol = data.second;
+ if (!strcmp(symbol->getId(), icon_title)) {
+ pixbuf = drawSymbol(symbol, psize);
+ return pixbuf;
+ }
+ }
+ return pixbuf;
+}
+
+void SymbolsDialog::setTargetDesktop(SPDesktop *desktop)
+{
+ if (this->current_desktop != desktop) {
+ this->current_desktop = desktop;
+ if( !symbol_sets[symbol_set->get_active_text()] ) {
+ // Symbol set is from Current document, update
+ rebuild();
+ }
+ }
+}
+
+} //namespace Dialogs
+} //namespace UI
+} //namespace Inkscape
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-basic-offset:2
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=2:tabstop=8:softtabstop=2:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/dialog/symbols.cpp.rej b/src/ui/dialog/symbols.cpp.rej
new file mode 100644
index 000000000..fe32c8bad
--- /dev/null
+++ b/src/ui/dialog/symbols.cpp.rej
@@ -0,0 +1,384 @@
+--- src/ui/dialog/symbols.cpp
++++ src/ui/dialog/symbols.cpp
+@@ -348,38 +374,8 @@ SymbolsDialog::SymbolsDialog( gchar const* prefsPath ) :
+
+ // This might need to be a global variable so setTargetDesktop can modify it
+ SPDefs *defs = current_document->getDefs();
+-
+- /*************************Overlays******************************/
+ #if GTK_CHECK_VERSION(3,2,4)
+- //Loading
+- overlay_opacity = new Gtk::Image();
+ overlay_opacity->set(getOverlay(overlay_opacity, "overlay", 1000));
+- overlay_opacity->set_halign(Gtk::ALIGN_START );
+- overlay_opacity->set_valign(Gtk::ALIGN_START );
+- //No results
+- iconsize = Gtk::IconSize().register_new(Glib::ustring("ICON_SIZE_DIALOG_EXTRA"), 110, 110);
+- overlay_icon = new Gtk::Image();
+- overlay_icon->set_from_icon_name("none", iconsize);
+- overlay_icon = new Gtk::Image();
+- overlay_icon->set_halign(Gtk::ALIGN_CENTER );
+- overlay_icon->set_valign(Gtk::ALIGN_START );
+- overlay_icon->set_margin_top(45);
+- overlay_title = new Gtk::Label();
+- overlay_title->set_halign(Gtk::ALIGN_CENTER );
+- overlay_title->set_valign(Gtk::ALIGN_START );
+- overlay_title->set_justify(Gtk::JUSTIFY_CENTER);
+- overlay_title->set_margin_top(155);
+- overlay_title->set_markup(Glib::ustring("<span foreground=\"#333333\" size=\"x-large\">") + Glib::ustring(_("No results found")) + Glib::ustring("</span>"));
+- overlay_desc = new Gtk::Label();
+- overlay_desc->set_halign(Gtk::ALIGN_CENTER );
+- overlay_desc->set_valign(Gtk::ALIGN_START );
+- overlay_desc->set_margin_top(180);
+- overlay_desc->set_justify(Gtk::JUSTIFY_CENTER);
+- overlay_desc->set_markup(Glib::ustring("<span foreground=\"#333333\" size=\"medium\">") + Glib::ustring(_("Try a another search or select other set")) + Glib::ustring("</span>"));
+- overlay->add_overlay(* overlay_opacity);
+- overlay->add_overlay(* overlay_icon);
+- overlay->add_overlay(* overlay_title);
+- overlay->add_overlay(* overlay_desc);
+ #endif
+ sigc::connection defsModifiedConn = defs->connectModified(sigc::mem_fun(*this, &SymbolsDialog::defsModified));
+ instanceConns.push_back(defsModifiedConn);
+@@ -394,16 +390,11 @@ SymbolsDialog::SymbolsDialog( gchar const* prefsPath ) :
+ getSymbolsFilename();
+ icons_found = false;
+
+- Glib::signal_idle().connect( sigc::mem_fun(*this, &SymbolsDialog::callbackSymbols));
+-
+ addSymbolsInDoc(current_document); /* Defaults to current document */
+ sigc::connection desktopChangeConn =
+ desk_track.connectDesktopChanged( sigc::mem_fun(*this, &SymbolsDialog::setTargetDesktop) );
+ instanceConns.push_back( desktopChangeConn );
+ desk_track.connect(GTK_WIDGET(gobj()));
+-#if GTK_CHECK_VERSION(3,2,4)
+- overlay->hide();
+-#endif
+ }
+
+ SymbolsDialog::~SymbolsDialog()
+@@ -411,6 +402,7 @@ SymbolsDialog::~SymbolsDialog()
+ for (std::vector<sigc::connection>::iterator it = instanceConns.begin(); it != instanceConns.end(); ++it) {
+ it->disconnect();
+ }
++ idleconn.disconnect();
+ instanceConns.clear();
+ desk_track.disconnect();
+ }
+@@ -474,9 +466,68 @@ void SymbolsDialog::rebuild() {
+ }
+ if (symbol_document) {
+ addSymbolsInDoc(symbol_document);
++ } else {
++ showOverlay();
+ }
+ }
++void SymbolsDialog::showOverlay() {
++#if GTK_CHECK_VERSION(3,2,4)
++Glib::ustring current = Glib::Markup::escape_text(symbol_set->get_active_text());
++ if (current == ALLDOCS &&
++ search->get_text() != _("Loading documents...") &&
++ !l.size())
++ {
++ if (!all_docs_processed ) {
++ overlay_title->set_markup(Glib::ustring("<span foreground=\"#333333\" size=\"large\">") + Glib::ustring(_("Searching in all symbol sets ...")) + Glib::ustring("</span>"));
++ overlay_desc->set_markup(Glib::ustring("<span foreground=\"#333333\" size=\"small\">") + Glib::ustring(_("When run for the first time,\n search will be slow.\nPlease wait ...")) + Glib::ustring("</span>"));
++ } else if (!icons_found && !search_str.empty()) {
++ overlay_title->set_markup(Glib::ustring("<span foreground=\"#333333\" size=\"large\">") + Glib::ustring(_("No results found ...")) + Glib::ustring("</span>"));
++ overlay_desc->set_markup(Glib::ustring("<span foreground=\"#333333\" size=\"small\">") + Glib::ustring(_("We have all symbols preloaded,\n search is faster now ...")) + Glib::ustring("</span>"));
++ } else {
++ overlay_title->set_markup(Glib::ustring("<span foreground=\"#333333\" size=\"large\">") + Glib::ustring(_("All symbol sets ...")) + Glib::ustring("</span>"));
++ overlay_desc->set_markup(Glib::ustring("<span foreground=\"#333333\" size=\"small\">") + Glib::ustring(_("We have all symbols preloaded,\n search is faster now ...")) + Glib::ustring("</span>"));
++ }
++ } else if (current == ALLDOCS && search->get_text() == _("Loading documents...")) {
++ if (!all_docs_processed) {
++ overlay_title->set_markup(Glib::ustring("<span foreground=\"#333333\" size=\"large\">") + Glib::ustring(_("Loading all symbol sets ...")) + Glib::ustring("</span>"));
++ overlay_desc->set_markup(Glib::ustring("<span foreground=\"#333333\" size=\"small\">")+ Glib::ustring(_("When run for the first time, search will be slow.\nPlease wait ...")) + Glib::ustring("</span>"));
++ overlay_icon->show();
++ overlay_title->show();
++ overlay_icon->set_from_icon_name("searching", iconsize);
++ overlay_desc->show();
++ }
++ } else if (!number_symbols && (current != CURRENTDOC || !search_str.empty())) {
++ overlay_title->set_markup(Glib::ustring("<span foreground=\"#333333\" size=\"large\">") + Glib::ustring(_("No results found")) + Glib::ustring("</span>"));
++ overlay_desc->set_markup(Glib::ustring("<span foreground=\"#333333\" size=\"small\">") + Glib::ustring(_("You could try a different search term,\nor switch to a different symbol set.")) + Glib::ustring("</span>"));
++ } else if (!number_symbols && current == CURRENTDOC) {
++ overlay_title->set_markup(Glib::ustring("<span foreground=\"#333333\"size=\"large\">") + Glib::ustring(_("No symbols found")) + Glib::ustring("</span>"));
++ overlay_desc->set_markup(Glib::ustring("<span foreground=\"#333333\" size=\"small\">") + Glib::ustring(_("No symbols in current document.\nYou could create in the current document\n or add into from other different symbol set.")) + Glib::ustring("</span>"));
++ } else if (!icons_found && !search_str.empty()) {
++ overlay_title->set_markup(Glib::ustring("<span foreground=\"#333333\" size=\"large\">") + Glib::ustring(_("No results found")) + Glib::ustring("</span>"));
++ overlay_desc->set_markup(Glib::ustring("<span foreground=\"#333333\" size=\"small\">") + Glib::ustring(_("You could try a different search term,\nor switch to a different symbol set.")) + Glib::ustring("</span>"));
++ }
++ overlay_opacity->show();
++ overlay_icon->set_from_icon_name("none", iconsize);
++ overlay_icon->show();
++ overlay_title->show();
++ overlay_desc->show();
++ if (l.size()) {
++ overlay_opacity->show();
++ overlay_icon->hide();
++ overlay_title->hide();
++ overlay_desc->hide();
++ }
++#endif
++}
+
++void SymbolsDialog::hideOverlay() {
++#if GTK_CHECK_VERSION(3,2,4)
++ overlay_opacity->hide();
++ overlay_icon->hide();
++ overlay_title->hide();
++ overlay_desc->hide();
++#endif
++}
+ void SymbolsDialog::insertSymbol() {
+ Inkscape::Verb *verb = Inkscape::Verb::get( SP_VERB_EDIT_SYMBOL );
+ SPAction *action = verb->get_action(Inkscape::ActionContext( (Inkscape::UI::View::View *) current_desktop) );
+@@ -934,6 +995,7 @@ void SymbolsDialog::clearSearch()
+ icons_found = false;
+ addSymbolsInDoc(symbol_document);
+ } else {
++ showOverlay();
+ enableWidgets(true);
+ }
+ }
+@@ -963,6 +1025,8 @@ void SymbolsDialog::beforeSearch(GdkEventKey* evt)
+ icons_found = false;
+ addSymbolsInDoc(symbol_document);
+ } else {
++ idleconn.disconnect();
++ idleconn = Glib::signal_idle().connect( sigc::mem_fun(*this, &SymbolsDialog::callbackAllSymbols));
+ search->set_text(_("Loading documents..."));
+ }
+ }
+@@ -973,84 +1037,11 @@ void SymbolsDialog::unsensitive(GdkEventKey* evt)
+ }
+
+ bool SymbolsDialog::callbackSymbols(){
+- Glib::ustring current = symbol_set->get_active_text();
+-#if GTK_CHECK_VERSION(3,2,4)
+- if (current == _("All symbols sets") &&
+- search->get_text() != _("Loading documents..."))
+- {
+- if (!all_docs_processed) {
+- overlay_opacity->show();
+- overlay_icon->set_from_icon_name("none", iconsize);
+- overlay_icon->show();
+- overlay_title->show();
+- overlay_desc->show();
+- overlay_title->set_markup(Glib::ustring("<span foreground=\"#333333\" size=\"x-large\">") + Glib::ustring(_("Searching in all symbol sets ...")) + Glib::ustring("</span>"));
+- overlay_desc->set_markup(Glib::ustring("<span foreground=\"#333333\" size=\"medium\">") + Glib::ustring(_("When run for the first time, search will be slow.\nPlease wait ...")) + Glib::ustring("</span>"));
+- }
+- }
+- if (current == _("Current Document") && !icons_found) {
+- if (!all_docs_processed) {
+- overlay_icon->set_from_icon_name("none", iconsize);
+- overlay_opacity->show();
+- overlay_icon->show();
+- overlay_title->show();
+- overlay_desc->show();
+- overlay_title->set_markup(Glib::ustring("<span foreground=\"#333333\" size=\"x-large\">") + Glib::ustring(_("No results found")) + Glib::ustring("</span>"));
+- overlay_desc->set_markup(Glib::ustring("<span foreground=\"#333333\" size=\"medium\">") + Glib::ustring(_("You could try a different search term,\nor switch to a different symbol set.")) + Glib::ustring("</span>"));
+- }
+- }
+-#endif
+- if (current == _("All symbols sets") &&
+- search->get_text() == _("Loading documents...") )
+- {
+-#if GTK_CHECK_VERSION(3,2,4)
+- overlay_opacity->show();
+-#endif
+- if (!all_docs_processed) {
+-#if GTK_CHECK_VERSION(3,2,4)
+- overlay_title->set_markup(Glib::ustring("<span foreground=\"#333333\" size=\"x-large\">") + Glib::ustring(_("Loading all symbol sets ...")) + Glib::ustring("</span>"));
+- overlay_desc->set_markup(Glib::ustring("<span foreground=\"#333333\" size=\"medium\">") + Glib::ustring(_("When run for the first time, search will be slow.\nPlease wait ...")) + Glib::ustring("</span>"));
+- overlay_icon->show();
+- overlay_title->show();
+- overlay_icon->set_from_icon_name("searching", iconsize);
+- overlay_desc->show();
+-#endif
+- }
+- size_t counter = 0;
+- for(auto const &symbol_document_map : symbol_sets) {
+- ++counter;
+- SPDocument* symbol_document = symbol_document_map.second;
+- if (symbol_document) {
+- continue;
+- }
+- symbol_document = getSymbolsSet(symbol_document_map.first).second;
+- symbol_set->set_active_text(_("All symbols sets"));
+- if (!symbol_document) {
+- continue;
+- }
+- progress_bar->set_fraction(((100.0/number_docs) * counter)/100.0);
+- return true;
+- }
+-#if GTK_CHECK_VERSION(3,2,4)
+- overlay_icon->hide();
+- overlay_title->hide();
+- overlay_desc->hide();
+-#endif
+- progress_bar->set_fraction(1.0);
+- all_docs_processed = true;
+- addSymbols();
+- search->set_text("Documents done, searchig inside...");
+- return true;
+- } else if (l.size()) {
+-#if GTK_CHECK_VERSION(3,2,4)
+- overlay_opacity->show();
+- overlay_icon->hide();
+- overlay_title->hide();
+- overlay_desc->hide();
+-#endif
++ if (l.size()) {
++ showOverlay();
+ for (auto symbol_data = l.begin(); symbol_data != l.end();) {
+- Glib::ustring doc_title = symbol_data->first;
+- SPSymbol * symbol = symbol_data->second;
++ Glib::ustring doc_title = symbol_data->second.first;
++ SPSymbol * symbol = symbol_data->second.second;
+ counter_symbols ++;
+ gchar const *symbol_title_char = symbol->title();
+ gchar const *symbol_desc_char = symbol->description();
+@@ -1082,30 +1073,54 @@ bool SymbolsDialog::callbackSymbols(){
+ return true;
+ }
+ }
+-#if GTK_CHECK_VERSION(3,2,4)
+ if (!icons_found && !search_str.empty()) {
+- overlay_title->set_markup(Glib::ustring("<span foreground=\"#333333\" size=\"x-large\">") + Glib::ustring(_("No results found")) + Glib::ustring("</span>"));
+- overlay_desc->set_markup(Glib::ustring("<span foreground=\"#333333\" size=\"medium\">") + Glib::ustring(_("You could try a different search term,\nor switch to a different symbol set.")) + Glib::ustring("</span>"));
+- overlay_icon->set_from_icon_name("none", iconsize);
+- overlay_icon->show();
+- overlay_title->show();
+- overlay_desc->show();
++ showOverlay();
+ } else {
+- overlay_opacity->hide();
++ hideOverlay();
+ }
+-#endif
+ sensitive = false;
+ search->set_text(search_str);
+ sensitive = true;
+ enableWidgets(true);
+- return true;
++ return false;
++ }
++ return true;
++}
++
++bool SymbolsDialog::callbackAllSymbols(){
++ Glib::ustring current = symbol_set->get_active_text();
++ if (current == ALLDOCS && search->get_text() == _("Loading documents...")) {
++ size_t counter = 0;
++ std::map<Glib::ustring, SPDocument*> symbol_sets_tmp = symbol_sets;
++ for(auto const &symbol_document_map : symbol_sets_tmp) {
++ ++counter;
++ SPDocument* symbol_document = symbol_document_map.second;
++ if (symbol_document) {
++ continue;
++ }
++ symbol_document = getSymbolsSet(symbol_document_map.first).second;
++ symbol_set->set_active_text(ALLDOCS);
++ if (!symbol_document) {
++ continue;
++ }
++ progress_bar->set_fraction(((100.0/number_docs) * counter)/100.0);
++ return true;
++ }
++ symbol_sets_tmp.clear();
++ hideOverlay();
++ progress_bar->set_fraction(1.0);
++ all_docs_processed = true;
++ addSymbols();
++ search->set_text("Documents done, searchig inside...");
++ return false;
+ }
+ return true;
+ }
+
+ Glib::ustring SymbolsDialog::ellipsize(Glib::ustring data, size_t limit) {
+ if (data.length() > limit) {
+- return data.substr(0,limit-3) + "...";
++ data = data.substr(0, limit-3);
++ return data + "...";
+ }
+ return data;
+ }
+@@ -1118,58 +1133,49 @@ void SymbolsDialog::addSymbolsInDoc(SPDocument* symbol_document) {
+ Glib::ustring doc_title = documentTitle(symbol_document);
+ progress_bar->set_fraction(0.0);
+ counter_symbols = 0;
+- std::vector<std::pair<Glib::ustring, SPSymbol*> > container_symbols_tmp = symbolsInDoc(symbol_document, doc_title);
+- number_symbols = container_symbols_tmp.size();
+- l = container_symbols_tmp;
+- container_symbols_tmp.clear();
++ l = symbolsInDoc(symbol_document, doc_title);
++ number_symbols = l.size();
+ if (!number_symbols) {
+-#if GTK_CHECK_VERSION(3,2,4)
+- overlay_icon->set_from_icon_name("none", iconsize);
+- overlay_icon->show();
+- overlay_title->set_markup(Glib::ustring("<span foreground=\"#333333\" size=\"x-large\">") + Glib::ustring(_("No results found")) + Glib::ustring("</span>"));
+- overlay_desc->set_markup(Glib::ustring("<span foreground=\"#333333\" size=\"medium\">") + Glib::ustring(_("You could try a different search term,\nor switch to a different symbol set.")) + Glib::ustring("</span>"));
+- overlay_title->show();
+- overlay_desc->show();
+-#endif
+ sensitive = false;
+ search->set_text(search_str);
+ sensitive = true;
+ enableWidgets(true);
++ idleconn.disconnect();
++ showOverlay();
++ } else {
++ idleconn.disconnect();
++ idleconn = Glib::signal_idle().connect( sigc::mem_fun(*this, &SymbolsDialog::callbackSymbols));
+ }
+ }
+
+ void SymbolsDialog::addSymbols() {
+ store->clear();
+ icons_found = false;
+- std::vector<std::pair<Glib::ustring, SPSymbol*> > container_symbols;
+ for(auto const &symbol_document_map : symbol_sets) {
+ SPDocument* symbol_document = symbol_document_map.second;
+ if (!symbol_document) {
+ continue;
+ }
+ Glib::ustring doc_title = documentTitle(symbol_document);
+- std::vector<std::pair<Glib::ustring, SPSymbol*> > container_symbols_tmp = symbolsInDoc(symbol_document, doc_title);
+- container_symbols.insert(container_symbols.end(), std::make_move_iterator(container_symbols_tmp.begin()), std::make_move_iterator(container_symbols_tmp.end()));
+- container_symbols_tmp.clear();
++ std::map<Glib::ustring, std::pair<Glib::ustring, SPSymbol*> > l_tmp = symbolsInDoc(symbol_document, doc_title);
++ for(auto &p : l_tmp ) {
++ l[p.first] = p.second;
++ }
++ l_tmp.clear();
+ }
+ counter_symbols = 0;
+ progress_bar->set_fraction(0.0);
+- number_symbols = container_symbols.size();
+- l = container_symbols;
+- container_symbols.clear();
++ number_symbols = l.size();
+ if (!number_symbols) {
+-#if GTK_CHECK_VERSION(3,2,4)
+- overlay_icon->set_from_icon_name("none", iconsize);
+- overlay_title->set_markup(Glib::ustring("<span foreground=\"#333333\" size=\"x-large\">") + Glib::ustring(_("No results found")) + Glib::ustring("</span>"));
+- overlay_desc->set_markup(Glib::ustring("<span foreground=\"#333333\" size=\"medium\">") + Glib::ustring(_("You could try a different search term,\nor switch to a different symbol set.")) + Glib::ustring("</span>"));
+- overlay_icon->show();
+- overlay_title->show();
+- overlay_desc->show();
+-#endif
++ showOverlay();
++ idleconn.disconnect();
+ sensitive = false;
+ search->set_text(search_str);
+ sensitive = true;
+ enableWidgets(true);
++ } else {
++ idleconn.disconnect();
++ idleconn = Glib::signal_idle().connect( sigc::mem_fun(*this, &SymbolsDialog::callbackSymbols));
+ }
+ }
+
diff --git a/src/ui/dialog/symbols.h.orig b/src/ui/dialog/symbols.h.orig
new file mode 100644
index 000000000..8255877b8
--- /dev/null
+++ b/src/ui/dialog/symbols.h.orig
@@ -0,0 +1,172 @@
+/** @file
+ * @brief Symbols dialog
+ */
+/* Authors:
+ * Tavmjong Bah, Martin Owens
+ *
+ * Copyright (C) 2012 Tavmjong Bah
+ * 2013 Martin Owens
+ * 2017 Jabiertxo Arraiza
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifndef INKSCAPE_UI_DIALOG_SYMBOLS_H
+#define INKSCAPE_UI_DIALOG_SYMBOLS_H
+#include <gtkmm.h>
+
+#include "display/drawing.h"
+#include "ui/dialog/desktop-tracker.h"
+#include "ui/widget/panel.h"
+#include "sp-symbol.h"
+#include "sp-use.h"
+#include <vector>
+
+class SPObject;
+
+namespace Inkscape {
+namespace UI {
+namespace Dialog {
+
+class SymbolColumns; // For Gtk::ListStore
+
+/**
+ * A dialog that displays selectable symbols and allows users to drag or paste
+ * those symbols from the dialog into the document.
+ *
+ * Symbol documents are loaded from the preferences paths and displayed in a
+ * drop-down list to the user. The user then selects which of the symbols
+ * documents they want to get symbols from. The first document in the list is
+ * always the current document.
+ *
+ * This then updates an icon-view with all the symbols available. Selecting one
+ * puts it onto the clipboard. Dragging it or pasting it onto the canvas copies
+ * the symbol from the symbol document, into the current document and places a
+ * new <use element at the correct location on the canvas.
+ *
+ * Selected groups on the canvas can be added to the current document's symbols
+ * table, and symbols can be removed from the current document. This allows
+ * new symbols documents to be constructed and if saved in the prefs folder will
+ * make those symbols available for all future documents.
+ */
+
+const int SYMBOL_ICON_SIZES[] = {16, 24, 32, 48, 64};
+
+class SymbolsDialog : public UI::Widget::Panel {
+
+public:
+ SymbolsDialog( gchar const* prefsPath = "/dialogs/symbols" );
+ virtual ~SymbolsDialog();
+
+ static SymbolsDialog& getInstance();
+
+private:
+ SymbolsDialog(SymbolsDialog const &); // no copy
+ SymbolsDialog &operator=(SymbolsDialog const &); // no assign
+
+ static SymbolColumns *getColumns();
+
+ void packless();
+ void packmore();
+ void zoomin();
+ void zoomout();
+ void rebuild();
+ void insertSymbol();
+ void revertSymbol();
+ void defsModified(SPObject *object, guint flags);
+ void selectionChanged(Inkscape::Selection *selection);
+ void documentReplaced(SPDesktop *desktop, SPDocument *document);
+ SPDocument* selectedSymbols();
+ Glib::ustring selectedSymbolId();
+ Glib::ustring selectedSymbolDocTitle();
+ void iconChanged();
+ void iconDragDataGet(const Glib::RefPtr<Gdk::DragContext>& context, Gtk::SelectionData& selection_data, guint info, guint time);
+ void getSymbolsFilename();
+ Glib::ustring documentTitle(SPDocument* doc);
+ std::pair<Glib::ustring, SPDocument*> getSymbolsSet(Glib::ustring title);
+ void addSymbol( SPObject* symbol, Glib::ustring doc_title);
+ SPDocument* symbolsPreviewDoc();
+ void symbolsInDocRecursive (SPObject *r, std::vector<std::pair<Glib::ustring, SPSymbol*> > &l, Glib::ustring doc_title);
+ std::vector<std::pair<Glib::ustring, SPSymbol*> > symbolsInDoc( SPDocument* document, Glib::ustring doc_title);
+ void useInDoc(SPObject *r, std::vector<SPUse*> &l);
+ std::vector<SPUse*> useInDoc( SPDocument* document);
+ void beforeSearch(GdkEventKey* evt);
+ void unsensitive(GdkEventKey* evt);
+ void addSymbols();
+ void addSymbolsInDoc(SPDocument* document);
+ void clearSearch();
+ bool callbackSymbols();
+ void enableWidgets(bool enable);
+ Glib::ustring ellipsize(Glib::ustring data, size_t limit = 40);
+ gchar const* styleFromUse( gchar const* id, SPDocument* document);
+ Glib::RefPtr<Gdk::Pixbuf> drawSymbol(SPObject *symbol, unsigned force_psize = 0);
+ Glib::RefPtr<Gdk::Pixbuf> getOverlay(Gtk::Image* image, gchar const * icon_title, unsigned psize);
+ /* Keep track of all symbol template documents */
+ std::map<Glib::ustring, SPDocument*> symbol_sets;
+ std::vector<std::pair<Glib::ustring, SPSymbol*> > l;
+ // Index into sizes which is selected
+ int pack_size;
+ // Scale factor
+ int scale_factor;
+ bool sensitive;
+ bool all_docs_processed;
+ size_t number_docs;
+ size_t number_symbols;
+ size_t counter_symbols;
+ bool icons_found;
+ Glib::RefPtr<Gtk::ListStore> store;
+ Glib::ustring search_str;
+ Gtk::ComboBoxText* symbol_set;
+ Gtk::ProgressBar* progress_bar;
+ Gtk::HBox* progress;
+ Gtk::SearchEntry* search;
+ Gtk::IconView* icon_view;
+ Gtk::Button* add_symbol;
+ Gtk::Button* remove_symbol;
+ Gtk::Button* zoom_in;
+ Gtk::Button* zoom_out;
+ Gtk::Button* more;
+ Gtk::Button* fewer;
+ Gtk::HBox* tools;
+#if GTK_CHECK_VERSION(3,2,4)
+ Gtk::Overlay* overlay;
+#endif
+ Gtk::Image* overlay_icon;
+ Gtk::Image* overlay_opacity;
+ Gtk::Label* overlay_title;
+ Gtk::Label* overlay_desc;
+ Gtk::ScrolledWindow *scroller;
+ Gtk::ToggleButton* fit_symbol;
+ Gtk::IconSize iconsize;
+ void setTargetDesktop(SPDesktop *desktop);
+ SPDesktop* current_desktop;
+ DesktopTracker desk_track;
+ SPDocument* current_document;
+ SPDocument* preview_document; /* Document to render single symbol */
+
+ sigc::connection idleconn;
+
+ /* For rendering the template drawing */
+ unsigned key;
+ Inkscape::Drawing renderDrawing;
+
+ std::vector<sigc::connection> instanceConns;
+};
+
+} //namespace Dialogs
+} //namespace UI
+} //namespace Inkscape
+
+
+#endif // INKSCAPE_UI_DIALOG_SYMBOLS_H
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/dialog/symbols.h.rej b/src/ui/dialog/symbols.h.rej
new file mode 100644
index 000000000..72cb5b299
--- /dev/null
+++ b/src/ui/dialog/symbols.h.rej
@@ -0,0 +1,19 @@
+--- src/ui/dialog/symbols.h
++++ src/ui/dialog/symbols.h
+@@ -141,13 +144,14 @@ private:
+ Gtk::ScrolledWindow *scroller;
+ Gtk::ToggleButton* fit_symbol;
+ Gtk::IconSize iconsize;
+-
+ void setTargetDesktop(SPDesktop *desktop);
+ SPDesktop* current_desktop;
+ DesktopTracker desk_track;
+ SPDocument* current_document;
+ SPDocument* preview_document; /* Document to render single symbol */
+-
++
++ sigc::connection idleconn;
++
+ /* For rendering the template drawing */
+ unsigned key;
+ Inkscape::Drawing renderDrawing;
diff --git a/src/ui/widget/page-sizer.cpp b/src/ui/widget/page-sizer.cpp
index 7427ad4e2..06d54b682 100644
--- a/src/ui/widget/page-sizer.cpp
+++ b/src/ui/widget/page-sizer.cpp
@@ -219,6 +219,7 @@ PageSizer::PageSizer(Registry & _wr)
_dimensionUnits( _("U_nits:"), "units", _wr ),
_dimensionWidth( _("_Width:"), _("Width of paper"), "width", _dimensionUnits, _wr ),
_dimensionHeight( _("_Height:"), _("Height of paper"), "height", _dimensionUnits, _wr ),
+ _marginLock( _("L_ock"), _("Lock margins"), "lock-margins", _wr ),
_marginTop( _("T_op margin:"), _("Top margin"), "fit-margin-top", _wr ),
_marginLeft( _("L_eft:"), _("Left margin"), "fit-margin-left", _wr),
_marginRight( _("Ri_ght:"), _("Right margin"), "fit-margin-right", _wr),
@@ -376,27 +377,33 @@ PageSizer::PageSizer(Registry & _wr)
_marginTop.set_halign(Gtk::ALIGN_CENTER);
_marginTop.set_hexpand();
_marginTop.set_vexpand();
- _marginTable.attach(_marginTop, 0, 0, 2, 1);
+
+ _marginTable.attach(_marginTop, 0, 0, 3, 1);
- _marginLeft.set_halign(Gtk::ALIGN_START);
+ _marginLeft.set_halign(Gtk::ALIGN_CENTER);
_marginLeft.set_hexpand();
_marginLeft.set_vexpand();
_marginTable.attach(_marginLeft, 0, 1, 1, 1);
-
- _marginRight.set_halign(Gtk::ALIGN_END);
+
+ _marginLock.set_halign(Gtk::ALIGN_CENTER);
+ _marginLock.set_hexpand();
+ _marginLock.set_vexpand();
+ _marginTable.attach(_marginLock, 1, 1, 1, 1);
+
+ _marginRight.set_halign(Gtk::ALIGN_CENTER);
_marginRight.set_hexpand();
_marginRight.set_vexpand();
- _marginTable.attach(_marginRight, 1, 1, 1, 1);
-
+ _marginTable.attach(_marginRight, 2, 1, 1, 1);
+
_marginBottom.set_halign(Gtk::ALIGN_CENTER);
_marginBottom.set_hexpand();
_marginBottom.set_vexpand();
- _marginTable.attach(_marginBottom, 0, 2, 2, 1);
+ _marginTable.attach(_marginBottom, 0, 2, 3, 1);
_fitPageButton.set_halign(Gtk::ALIGN_CENTER);
_fitPageButton.set_hexpand();
_fitPageButton.set_vexpand();
- _marginTable.attach(_fitPageButton, 0, 3, 2, 1);
+ _marginTable.attach(_fitPageButton, 0, 3, 3, 1);
_fitPageButton.set_use_underline();
_fitPageButton.set_label(_("_Resize page to drawing or selection (Ctrl+Shift+R)"));
@@ -474,6 +481,10 @@ PageSizer::init ()
_changedvy_connection = _viewboxY.signal_value_changed().connect (sigc::mem_fun (*this, &PageSizer::on_viewbox_changed));
_changedvw_connection = _viewboxW.signal_value_changed().connect (sigc::mem_fun (*this, &PageSizer::on_viewbox_changed));
_changedvh_connection = _viewboxH.signal_value_changed().connect (sigc::mem_fun (*this, &PageSizer::on_viewbox_changed));
+ _changedmt_connection = _marginTop.signal_value_changed().connect (sigc::bind<RegisteredScalar*>(sigc::mem_fun (*this, &PageSizer::on_margin_changed), &_marginTop));
+ _changedmb_connection = _marginBottom.signal_value_changed().connect (sigc::bind<RegisteredScalar*>(sigc::mem_fun (*this, &PageSizer::on_margin_changed), &_marginBottom));
+ _changedml_connection = _marginLeft.signal_value_changed().connect (sigc::bind<RegisteredScalar*>(sigc::mem_fun (*this, &PageSizer::on_margin_changed), &_marginLeft));
+ _changedmr_connection = _marginRight.signal_value_changed().connect (sigc::bind<RegisteredScalar*>(sigc::mem_fun (*this, &PageSizer::on_margin_changed), &_marginRight));
show_all_children();
}
@@ -892,6 +903,24 @@ PageSizer::on_viewbox_changed()
}
}
+/**
+ * Callback for viewbox widgets
+ */
+void
+PageSizer::on_margin_changed(RegisteredScalar* widg)
+{
+ double value = widg->getValue();
+ if (_widgetRegistry->isUpdating()) return;
+ if (_marginLock.get_active() && !_marginLocked) {
+ _marginLocked = true;
+ _marginLeft.setValue(value);
+ _marginRight.setValue(value);
+ _marginTop.setValue(value);
+ _marginBottom.setValue(value);
+ _marginLocked = false;
+ }
+}
+
} // namespace Widget
} // namespace UI
} // namespace Inkscape
diff --git a/src/ui/widget/page-sizer.h b/src/ui/widget/page-sizer.h
index 329ecfc6d..7cf8bacfd 100644
--- a/src/ui/widget/page-sizer.h
+++ b/src/ui/widget/page-sizer.h
@@ -161,7 +161,11 @@ public:
* of the ui widgets to match the xml).
*/
void updateFitMarginsUI(Inkscape::XML::Node *nv_repr);
-
+
+ /**
+ * Updates the margin widgets. If lock widget is active
+ */
+ void on_margin_changed(RegisteredScalar* widg);
/**
* Updates the scale widgets. (Just changes the values of the ui widgets.)
*/
@@ -225,13 +229,15 @@ protected:
//### Fit Page options
Gtk::Expander _fitPageMarginExpander;
- Gtk::Grid _marginTable;
- RegisteredScalar _marginTop;
- RegisteredScalar _marginLeft;
- RegisteredScalar _marginRight;
- RegisteredScalar _marginBottom;
- Gtk::Button _fitPageButton;
- bool _lockMarginUpdate;
+ Gtk::Grid _marginTable;
+ RegisteredCheckButton _marginLock;
+ RegisteredScalar _marginTop;
+ RegisteredScalar _marginLeft;
+ RegisteredScalar _marginRight;
+ RegisteredScalar _marginBottom;
+ Gtk::Button _fitPageButton;
+ bool _lockMarginUpdate;
+ bool _marginLocked;
// Document scale
Gtk::Frame _scaleFrame;
@@ -265,6 +271,10 @@ protected:
sigc::connection _changedvy_connection;
sigc::connection _changedvw_connection;
sigc::connection _changedvh_connection;
+ sigc::connection _changedmt_connection;
+ sigc::connection _changedmb_connection;
+ sigc::connection _changedml_connection;
+ sigc::connection _changedmr_connection;
Registry *_widgetRegistry;