~moduli16/inkscape/recolor

« back to all changes in this revision

Viewing changes to src/ui/dialog/symbols.cpp

  • Committer: tavmjong-free
  • Date: 2012-10-11 17:54:14 UTC
  • Revision ID: tavmjong@free.fr-20121011175414-j1i7huls4h70n91n
Add symbols dialog. See: http://wiki.inkscape.org/wiki/index.php/SymbolsDialog

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 * @file
 
3
 * Symbols dialog.
 
4
 */
 
5
/* Authors:
 
6
 * Copyright (C) 2012 Tavmjong Bah
 
7
 *
 
8
 * Released under GNU GPL, read the file 'COPYING' for more information
 
9
 */
 
10
 
 
11
#ifdef HAVE_CONFIG_H
 
12
# include "config.h"
 
13
#endif
 
14
 
 
15
#include <iostream>
 
16
#include <algorithm>
 
17
 
 
18
#include <gtkmm/buttonbox.h>
 
19
#include <gtkmm/label.h>
 
20
#include <gtkmm/table.h>
 
21
#include <gtkmm/scrolledwindow.h>
 
22
#include <gtkmm/comboboxtext.h>
 
23
#include <gtkmm/iconview.h>
 
24
#include <gtkmm/liststore.h>
 
25
#include <gtkmm/treemodelcolumn.h>
 
26
#include <gtkmm/clipboard.h>
 
27
 
 
28
#include "path-prefix.h"
 
29
#include "io/sys.h"
 
30
 
 
31
#include "ui/cache/svg_preview_cache.h"
 
32
#include "ui/clipboard.h"
 
33
 
 
34
#include "symbols.h"
 
35
 
 
36
#include "desktop.h"
 
37
#include "desktop-handles.h"
 
38
#include "document.h"
 
39
#include "inkscape.h"
 
40
#include "sp-root.h"
 
41
#include "sp-use.h"
 
42
#include "sp-symbol.h"
 
43
 
 
44
#include "verbs.h"
 
45
#include "xml/repr.h"
 
46
 
 
47
namespace Inkscape {
 
48
namespace UI {
 
49
 
 
50
static Cache::SvgPreview svg_preview_cache;
 
51
 
 
52
namespace Dialog {
 
53
 
 
54
  // See: http://developer.gnome.org/gtkmm/stable/classGtk_1_1TreeModelColumnRecord.html
 
55
class SymbolColumns : public Gtk::TreeModel::ColumnRecord
 
56
{
 
57
public:
 
58
 
 
59
  Gtk::TreeModelColumn<Glib::ustring>                symbol_id;
 
60
  Gtk::TreeModelColumn<Glib::ustring>                symbol_title;
 
61
  Gtk::TreeModelColumn< Glib::RefPtr<Gdk::Pixbuf> >  symbol_image;
 
62
 
 
63
  SymbolColumns() {
 
64
    add(symbol_id);
 
65
    add(symbol_title);
 
66
    add(symbol_image);
 
67
  }
 
68
};
 
69
 
 
70
SymbolColumns* SymbolsDialog::getColumns()
 
71
{
 
72
  SymbolColumns* columns = new SymbolColumns();
 
73
  return columns;
 
74
}
 
75
 
 
76
/**
 
77
 * Constructor
 
78
 */
 
79
SymbolsDialog::SymbolsDialog( gchar const* prefsPath ) :
 
80
  UI::Widget::Panel("", prefsPath, SP_VERB_DIALOG_SYMBOLS),
 
81
  store(Gtk::ListStore::create(*getColumns())),
 
82
  iconView(0),
 
83
  previewScale(0),
 
84
  previewSize(0),
 
85
  currentDesktop(0),
 
86
  deskTrack(),
 
87
  currentDocument(0),
 
88
  previewDocument(0),
 
89
  instanceConns()
 
90
{
 
91
 
 
92
  /********************    Table    *************************/
 
93
  // Replace by Grid for GTK 3.0
 
94
  Gtk::Table *table = new Gtk::Table(2, 4, false);
 
95
  // panel is a cloked Gtk::VBox
 
96
  _getContents()->pack_start(*Gtk::manage(table), Gtk::PACK_EXPAND_WIDGET);
 
97
  guint row = 0;
 
98
 
 
99
  /******************** Symbol Sets *************************/
 
100
  Gtk::Label* labelSet = new Gtk::Label("Symbol set: ");
 
101
  table->attach(*Gtk::manage(labelSet),0,1,row,row+1,Gtk::SHRINK,Gtk::SHRINK);
 
102
 
 
103
  symbolSet = new Gtk::ComboBoxText();  // Fill in later
 
104
  symbolSet->append("Current Document");
 
105
  symbolSet->set_active_text("Current Document");
 
106
  table->attach(*Gtk::manage(symbolSet),1,2,row,row+1,Gtk::FILL|Gtk::EXPAND,Gtk::SHRINK);
 
107
 
 
108
  sigc::connection connSet =
 
109
    symbolSet->signal_changed().connect(sigc::mem_fun(*this, &SymbolsDialog::rebuild));
 
110
  instanceConns.push_back(connSet);
 
111
  
 
112
  ++row;
 
113
 
 
114
  /********************* Icon View **************************/
 
115
  SymbolColumns* columns = getColumns();
 
116
 
 
117
  iconView = new Gtk::IconView(static_cast<Glib::RefPtr<Gtk::TreeModel> >(store));
 
118
  //iconView->set_text_column(  columns->symbol_id  );
 
119
  iconView->set_tooltip_column( 1 );
 
120
  iconView->set_pixbuf_column(  columns->symbol_image );
 
121
 
 
122
  sigc::connection connIconChanged;
 
123
  connIconChanged =
 
124
    iconView->signal_selection_changed().connect(sigc::mem_fun(*this, &SymbolsDialog::iconChanged));
 
125
  instanceConns.push_back(connIconChanged);
 
126
 
 
127
  Gtk::ScrolledWindow *scroller = new Gtk::ScrolledWindow();
 
128
  scroller->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS);
 
129
  scroller->add(*Gtk::manage(iconView));
 
130
  table->attach(*Gtk::manage(scroller),0,2,row,row+1,Gtk::EXPAND|Gtk::FILL,Gtk::EXPAND|Gtk::FILL);
 
131
 
 
132
  ++row;
 
133
 
 
134
  /******************** Preview Scale ***********************/
 
135
  Gtk::Label* labelScale = new Gtk::Label("Preview scale: ");
 
136
  table->attach(*Gtk::manage(labelScale),0,1,row,row+1,Gtk::SHRINK,Gtk::SHRINK);
 
137
 
 
138
  previewScale = new Gtk::ComboBoxText();
 
139
  const gchar *scales[] =
 
140
    {"Fit", "Fit to width", "Fit to height", "0.1", "0.2", "0.5", "1.0", "2.0", "5.0", NULL};
 
141
  for( int i = 0; scales[i]; ++i ) {
 
142
    previewScale->append(scales[i]);
 
143
  }
 
144
  previewScale->set_active_text(scales[0]);
 
145
  table->attach(*Gtk::manage(previewScale),1,2,row,row+1,Gtk::FILL|Gtk::EXPAND,Gtk::SHRINK);
 
146
 
 
147
  sigc::connection connScale =
 
148
    previewScale->signal_changed().connect(sigc::mem_fun(*this, &SymbolsDialog::rebuild));
 
149
  instanceConns.push_back(connScale);
 
150
  
 
151
  ++row;
 
152
 
 
153
  /******************** Preview Size ************************/
 
154
  Gtk::Label* labelSize = new Gtk::Label("Preview size: ");
 
155
  table->attach(*Gtk::manage(labelSize),0,1,row,row+1,Gtk::SHRINK,Gtk::SHRINK);
 
156
 
 
157
  previewSize = new Gtk::ComboBoxText();
 
158
  const gchar *sizes[] = {"16", "24", "32", "48", "64", NULL};
 
159
  for( int i = 0; sizes[i]; ++i ) {
 
160
    previewSize->append(sizes[i]);
 
161
  }
 
162
  previewSize->set_active_text(sizes[2]);
 
163
  table->attach(*Gtk::manage(previewSize),1,2,row,row+1,Gtk::FILL|Gtk::EXPAND,Gtk::SHRINK);
 
164
 
 
165
  sigc::connection connSize =
 
166
    previewSize->signal_changed().connect(sigc::mem_fun(*this, &SymbolsDialog::rebuild));
 
167
  instanceConns.push_back(connSize);
 
168
  
 
169
  ++row;
 
170
 
 
171
  /**********************************************************/
 
172
  currentDesktop  = inkscape_active_desktop();
 
173
  currentDocument = sp_desktop_document(currentDesktop);
 
174
 
 
175
  previewDocument = symbols_preview_doc(); /* Template to render symbols in */
 
176
  previewDocument->ensureUpToDate(); /* Necessary? */
 
177
 
 
178
  key = SPItem::display_key_new(1);
 
179
  renderDrawing.setRoot(previewDocument->getRoot()->invoke_show(renderDrawing, key, SP_ITEM_SHOW_DISPLAY ));
 
180
 
 
181
  get_symbols();
 
182
  draw_symbols( currentDocument ); /* Defaults to current document */
 
183
 
 
184
  desktopChangeConn =
 
185
    deskTrack.connectDesktopChanged( sigc::mem_fun(*this, &SymbolsDialog::setTargetDesktop) );
 
186
  instanceConns.push_back( desktopChangeConn );
 
187
  deskTrack.connect(GTK_WIDGET(gobj()));
 
188
}
 
189
 
 
190
SymbolsDialog::~SymbolsDialog()
 
191
{
 
192
  for (std::vector<sigc::connection>::iterator it =  instanceConns.begin(); it != instanceConns.end(); ++it) {
 
193
      it->disconnect();
 
194
  }
 
195
  instanceConns.clear();
 
196
  deskTrack.disconnect();
 
197
}
 
198
 
 
199
SymbolsDialog& SymbolsDialog::getInstance()
 
200
{
 
201
  return *new SymbolsDialog();
 
202
}
 
203
 
 
204
void SymbolsDialog::rebuild() {
 
205
 
 
206
  store->clear();
 
207
  Glib::ustring symbolSetString = symbolSet->get_active_text();
 
208
 
 
209
  SPDocument* symbolDocument = symbolSets[symbolSetString];
 
210
  if( !symbolDocument ) {
 
211
    // Symbol must be from Current Document (this method of
 
212
    // checking should be language independent).
 
213
    symbolDocument = currentDocument;
 
214
  }
 
215
  draw_symbols( symbolDocument );
 
216
}
 
217
 
 
218
void SymbolsDialog::iconChanged() {
 
219
#if WITH_GTKMM_3_0
 
220
  std::vector<Gtk::TreePath> iconArray = iconView->get_selected_items();
 
221
#else
 
222
  Gtk::IconView::ArrayHandle_TreePaths iconArray = iconView->get_selected_items();
 
223
#endif
 
224
 
 
225
  if( iconArray.empty() ) {
 
226
    //std::cout << "  iconArray empty: huh? " << std::endl;
 
227
  } else {
 
228
    Gtk::TreeModel::Path const & path = *iconArray.begin();
 
229
    Gtk::ListStore::iterator row = store->get_iter(path);
 
230
    Glib::ustring symbol_id = (*row)[getColumns()->symbol_id];
 
231
 
 
232
    /* OK, we know symbol name... now we need to copy it to clipboard, bon chance! */
 
233
    Glib::ustring symbolSetString = symbolSet->get_active_text();
 
234
 
 
235
    SPDocument* symbolDocument = symbolSets[symbolSetString];
 
236
    if( !symbolDocument ) {
 
237
      // Symbol must be from Current Document (this method of
 
238
      // checking should be language independent).
 
239
      symbolDocument = currentDocument;
 
240
    }
 
241
 
 
242
    SPObject* symbol = symbolDocument->getObjectById(symbol_id);
 
243
    if( symbol ) {
 
244
 
 
245
      // Find style for use in <use>
 
246
      // First look for default style stored in <symbol>
 
247
      gchar const* style = symbol->getAttribute("inkscape:symbol-style");
 
248
      if( !style ) {
 
249
        // If no default style in <symbol>, look in documents.
 
250
        if( symbolDocument == currentDocument ) {
 
251
          style = style_from_use( symbol_id.c_str(), currentDocument );
 
252
        } else {
 
253
          style = symbolDocument->getReprRoot()->attribute("style");
 
254
        }
 
255
      }
 
256
 
 
257
      ClipboardManager *cm = ClipboardManager::get();
 
258
      cm->copySymbol(symbol->getRepr(), style);
 
259
    }
 
260
  }
 
261
}
 
262
 
 
263
/* Hunts preference directories for symbol files */
 
264
void SymbolsDialog::get_symbols() {
 
265
 
 
266
  std::list<Glib::ustring> directories;
 
267
 
 
268
  if( Inkscape::IO::file_test( INKSCAPE_SYMBOLSDIR, G_FILE_TEST_EXISTS ) &&
 
269
        Inkscape::IO::file_test( INKSCAPE_SYMBOLSDIR, G_FILE_TEST_IS_DIR ) ) {
 
270
    directories.push_back( INKSCAPE_SYMBOLSDIR );
 
271
  }
 
272
  if( Inkscape::IO::file_test( profile_path("symbols"), G_FILE_TEST_EXISTS ) &&
 
273
        Inkscape::IO::file_test( profile_path("symbols"), G_FILE_TEST_IS_DIR ) ) {
 
274
    directories.push_back( profile_path("symbols") );
 
275
  }
 
276
 
 
277
  std::list<Glib::ustring>::iterator it;
 
278
  for( it = directories.begin(); it != directories.end(); ++it ) {
 
279
 
 
280
    GError *err = 0;
 
281
    GDir *dir = g_dir_open( (*it).c_str(), 0, &err );
 
282
    if( dir ) {
 
283
 
 
284
        gchar *filename = 0;
 
285
        while( (filename = (gchar *)g_dir_read_name( dir ) ) != NULL) {
 
286
 
 
287
          gchar *fullname = g_build_filename((*it).c_str(), filename, NULL);
 
288
 
 
289
          if ( !Inkscape::IO::file_test( fullname, G_FILE_TEST_IS_DIR ) ) {
 
290
 
 
291
            SPDocument* symbol_doc = SPDocument::createNewDoc( fullname, FALSE );
 
292
            if( symbol_doc ) {
 
293
              symbolSets[Glib::ustring(filename)]= symbol_doc;
 
294
              symbolSet->append(filename);
 
295
            }
 
296
          }
 
297
          g_free( fullname );
 
298
        }
 
299
        g_dir_close( dir );
 
300
    }
 
301
  }
 
302
}
 
303
 
 
304
GSList* SymbolsDialog::symbols_in_doc_recursive (SPObject *r, GSList *l)
 
305
 
306
 
 
307
  // Stop multiple counting of same symbol
 
308
  if( SP_IS_USE(r) ) {
 
309
    return l;
 
310
  }
 
311
 
 
312
  if( SP_IS_SYMBOL(r) ) {
 
313
    l = g_slist_prepend (l, r);
 
314
  }
 
315
 
 
316
  for (SPObject *child = r->firstChild(); child; child = child->getNext()) {
 
317
    l = symbols_in_doc_recursive( child, l );
 
318
  }
 
319
 
 
320
  return l;
 
321
}
 
322
 
 
323
GSList* SymbolsDialog::symbols_in_doc( SPDocument* symbolDocument ) {
 
324
 
 
325
  GSList *l = NULL;
 
326
  l = symbols_in_doc_recursive (symbolDocument->getRoot(), l );
 
327
  return l;
 
328
}
 
329
 
 
330
GSList* SymbolsDialog::use_in_doc_recursive (SPObject *r, GSList *l)
 
331
 
332
 
 
333
  if( SP_IS_USE(r) ) {
 
334
    l = g_slist_prepend (l, r);
 
335
  }
 
336
 
 
337
  for (SPObject *child = r->firstChild(); child; child = child->getNext()) {
 
338
    l = use_in_doc_recursive( child, l );
 
339
  }
 
340
 
 
341
  return l;
 
342
}
 
343
 
 
344
GSList* SymbolsDialog::use_in_doc( SPDocument* useDocument ) {
 
345
 
 
346
  GSList *l = NULL;
 
347
  l = use_in_doc_recursive (useDocument->getRoot(), l );
 
348
  return l;
 
349
}
 
350
 
 
351
// Returns style from first <use> element found that references id.
 
352
// This is a last ditch effort to find a style.
 
353
gchar const* SymbolsDialog::style_from_use( gchar const* id, SPDocument* document) {
 
354
 
 
355
  gchar const* style = 0;
 
356
  GSList* l = use_in_doc( document );
 
357
  for( ; l != NULL; l = l->next ) {
 
358
    SPObject* use = SP_OBJECT(l->data);
 
359
    if( SP_IS_USE( use ) ) {
 
360
        gchar const *href = use->getRepr()->attribute("xlink:href");
 
361
        if( href ) {
 
362
          Glib::ustring href2(href);
 
363
          Glib::ustring id2(id);
 
364
          id2 = "#" + id2;
 
365
          if( !href2.compare(id2) ) {
 
366
            style = use->getRepr()->attribute("style");
 
367
            break;
 
368
          }
 
369
        }
 
370
    }
 
371
  }
 
372
  return style;
 
373
}
 
374
 
 
375
void SymbolsDialog::draw_symbols( SPDocument* symbolDocument ) {
 
376
 
 
377
 
 
378
  SymbolColumns* columns = getColumns();
 
379
 
 
380
  GSList* l = symbols_in_doc( symbolDocument );
 
381
  for( ; l != NULL; l = l->next ) {
 
382
 
 
383
    SPObject* symbol = SP_OBJECT(l->data);
 
384
    if (!SP_IS_SYMBOL(symbol)) {
 
385
        //std::cout << "  Error: not symbol" << std::endl;
 
386
        continue;
 
387
    }
 
388
 
 
389
    gchar const *id    = symbol->getRepr()->attribute("id");
 
390
    gchar const *title = symbol->title(); // From title element
 
391
    if( !title ) {
 
392
        title = id;
 
393
    }
 
394
 
 
395
    Glib::RefPtr<Gdk::Pixbuf> pixbuf = create_symbol_image(id, symbolDocument, &renderDrawing, key );
 
396
    if( pixbuf ) {
 
397
 
 
398
        Gtk::ListStore::iterator row = store->append();
 
399
        (*row)[columns->symbol_id]    = Glib::ustring( id );
 
400
        (*row)[columns->symbol_title] = Glib::ustring( title );
 
401
        (*row)[columns->symbol_image] = pixbuf;
 
402
    }
 
403
  }
 
404
}
 
405
 
 
406
/*
 
407
 * Returns image of symbol.
 
408
 *
 
409
 * Symbols normally are not visible. They must be referenced by a
 
410
 * <use> element.  A temporary document is created with a dummy
 
411
 * <symbol> element and a <use> element that references the symbol
 
412
 * element. Each real symbol is swapped in for the dummy symbol and
 
413
 * the temporary document is rendered.
 
414
 */
 
415
Glib::RefPtr<Gdk::Pixbuf>
 
416
SymbolsDialog::create_symbol_image(gchar const *symbol_id,
 
417
                                     SPDocument *source, 
 
418
                                     Inkscape::Drawing* drawing,
 
419
                                     unsigned /*visionkey*/)
 
420
{
 
421
 
 
422
  // Retrieve the symbol named 'symbol_id' from the source SVG document
 
423
  SPObject const* symbol = source->getObjectById(symbol_id);
 
424
  if (symbol == NULL) {
 
425
    //std::cout << "  Failed to find symbol: " << symbol_id << std::endl;
 
426
    //return 0;
 
427
  }
 
428
 
 
429
  // Create a copy repr of the symbol with id="the_symbol"
 
430
  Inkscape::XML::Document *xml_doc = previewDocument->getReprDoc();
 
431
  Inkscape::XML::Node *repr = symbol->getRepr()->duplicate(xml_doc);
 
432
  repr->setAttribute("id", "the_symbol");
 
433
 
 
434
  // Replace old "the_symbol" in previewDocument by new.
 
435
  Inkscape::XML::Node *root = previewDocument->getReprRoot();
 
436
  SPObject *symbol_old = previewDocument->getObjectById("the_symbol");
 
437
  if (symbol_old) {
 
438
      symbol_old->deleteObject(false);
 
439
  }
 
440
 
 
441
  // First look for default style stored in <symbol>
 
442
  gchar const* style = repr->attribute("inkscape:symbol-style");
 
443
  if( !style ) {
 
444
    // If no default style in <symbol>, look in documents.
 
445
    if( source == currentDocument ) {
 
446
        style = style_from_use( symbol_id, source );
 
447
    } else {
 
448
        style = source->getReprRoot()->attribute("style");
 
449
    }
 
450
  }
 
451
 
 
452
  // This is for display in Symbols dialog only
 
453
  if( style ) {
 
454
    repr->setAttribute( "style", style );
 
455
  }
 
456
 
 
457
  // BUG: Symbols don't work if defined outside of <defs>. Causes Inkscape
 
458
  // crash when trying to read in such a file.
 
459
  root->appendChild(repr);
 
460
  //defsrepr->appendChild(repr);
 
461
  Inkscape::GC::release(repr);
 
462
 
 
463
  // Uncomment this to get the previewDocument documents saved (useful for debugging)
 
464
  // FILE *fp = fopen (g_strconcat(symbol_id, ".svg", NULL), "w");
 
465
  // sp_repr_save_stream(previewDocument->getReprDoc(), fp);
 
466
  // fclose (fp);
 
467
 
 
468
  // Make sure previewDocument is up-to-date.
 
469
  previewDocument->getRoot()->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
 
470
  previewDocument->ensureUpToDate();
 
471
 
 
472
  // Make sure we have symbol in previewDocument
 
473
  SPObject *object_temp = previewDocument->getObjectById( "the_use" );
 
474
  previewDocument->getRoot()->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
 
475
  previewDocument->ensureUpToDate();
 
476
 
 
477
  // if( object_temp == NULL || !SP_IS_ITEM(object_temp) ) {
 
478
  //   //std::cout << "  previewDocument broken?" << std::endl;
 
479
  //   //return 0;
 
480
  // }
 
481
 
 
482
  SPItem *item = SP_ITEM(object_temp);
 
483
 
 
484
  // Find object's bbox in document.
 
485
  // Note symbols can have own viewport... ignore for now.
 
486
  //Geom::OptRect dbox = item->geometricBounds();
 
487
  Geom::OptRect dbox = item->documentVisualBounds();
 
488
  // if (!dbox) {
 
489
  //   //std::cout << "  No dbox" << std::endl;
 
490
  //   //return NULL;
 
491
  // }
 
492
 
 
493
  Glib::ustring previewSizeString = previewSize->get_active_text();
 
494
  unsigned psize = atol( previewSizeString.c_str() );
 
495
 
 
496
  Glib::ustring previewScaleString = previewScale->get_active_text();
 
497
  int previewScaleRow = previewScale->get_active_row_number();
 
498
 
 
499
  /* Update to renderable state */
 
500
  Glib::ustring key = svg_preview_cache.cache_key(previewDocument->getURI(), symbol_id, psize);
 
501
  //std::cout << "  Key: " << key << std::endl;
 
502
  // FIX ME
 
503
  //Glib::RefPtr<Gdk::Pixbuf> pixbuf = Glib::wrap(svg_preview_cache.get_preview_from_cache(key));
 
504
  Glib::RefPtr<Gdk::Pixbuf> pixbuf = Glib::RefPtr<Gdk::Pixbuf>(0);
 
505
 
 
506
  if (!pixbuf) {
 
507
 
 
508
    /* Scale symbols to fit */
 
509
    double scale = 1.0;
 
510
    switch (previewScaleRow) {
 
511
    case 0:
 
512
        /* Fit */
 
513
        scale = psize/std::max(dbox->width(),dbox->height());
 
514
        break;
 
515
    case 1:
 
516
        /* Fit width */
 
517
        scale = psize/dbox->width();
 
518
        break;
 
519
    case 2:
 
520
        /* Fit height */
 
521
        scale = psize/dbox->height();
 
522
        break;
 
523
    default:
 
524
        scale = atof( previewScaleString.c_str() );
 
525
    }
 
526
 
 
527
    pixbuf = Glib::wrap(render_pixbuf(*drawing, scale, *dbox, psize));
 
528
    svg_preview_cache.set_preview_in_cache(key, pixbuf->gobj());
 
529
  }
 
530
 
 
531
  return pixbuf;
 
532
}
 
533
 
 
534
/*
 
535
 * Return empty doc to render symbols in.
 
536
 * Symbols are by default not rendered so a <use> element is
 
537
 * provided.
 
538
 */
 
539
SPDocument* SymbolsDialog::symbols_preview_doc()
 
540
{
 
541
  // BUG: <symbol> must be inside <defs>
 
542
  gchar const *buffer =
 
543
"<svg xmlns=\"http://www.w3.org/2000/svg\""
 
544
"     xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\""
 
545
"     xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\""
 
546
"     xmlns:xlink=\"http://www.w3.org/1999/xlink\""
 
547
"     style=\"fill:none;stroke:black;stroke-width:2\">"
 
548
"  <defs id=\"defs\">"  
 
549
"    <symbol id=\"the_symbol\"/>"
 
550
"  </defs>"
 
551
"  <use id=\"the_use\" xlink:href=\"#the_symbol\"/>"
 
552
"</svg>";
 
553
 
 
554
  return SPDocument::createNewDocFromMem( buffer, strlen(buffer), FALSE );
 
555
}
 
556
 
 
557
void SymbolsDialog::setTargetDesktop(SPDesktop *desktop)
 
558
{
 
559
  if (this->currentDesktop != desktop) {
 
560
    this->currentDesktop = desktop;
 
561
    if( !symbolSets[symbolSet->get_active_text()] ) {
 
562
        // Symbol set is from Current document, update
 
563
        rebuild();
 
564
    }
 
565
  }
 
566
}
 
567
 
 
568
 
 
569
} //namespace Dialogs
 
570
} //namespace UI
 
571
} //namespace Inkscape
 
572
 
 
573
 
 
574