Code

GSoC C++-ificiation merge and cleanup.
[inkscape.git] / src / ui / dialog / svg-fonts-dialog.cpp
index abdf4c3aeb64009648266891d93f1211f275130e..042acb6e1b3e16a4e22620d16115998f2b164d20 100644 (file)
@@ -2,7 +2,9 @@
  * @brief SVG Fonts dialog - implementation
  */
 /* Authors:
- *   Felipe C. da S. Sanches <felipe.sanches@gmail.com>
+ *   Felipe C. da S. Sanches <juca@members.fsf.org>
+ *   Jon A. Cruz <jon@joncruz.org>
+ *   Abhishek Sharma
  *
  * Copyright (C) 2008 Authors
  * Released under GNU GPLv2 (or later).  Read the file 'COPYING' for more information.
 
 #ifdef ENABLE_SVG_FONTS
 
+#include <2geom/pathvector.h>
 #include "document-private.h"
 #include <gtkmm/notebook.h>
 #include <glibmm/i18n.h>
+#include <message-stack.h>
 #include "selection.h"
 #include <string.h>
+#include "svg/svg.h"
 #include "svg-fonts-dialog.h"
 #include "xml/node.h"
 #include "xml/repr.h"
-#include "svg/svg.h"
-#include <2geom/pathvector.h>
 
 SvgFontDrawingArea::SvgFontDrawingArea(){
-       this->text = "";
-       this->svgfont = NULL;
+    this->text = "";
+    this->svgfont = NULL;
 }
 
 void SvgFontDrawingArea::set_svgfont(SvgFont* svgfont){
-       this->svgfont = svgfont;
+    this->svgfont = svgfont;
 }
 
 void SvgFontDrawingArea::set_text(Glib::ustring text){
-       this->text = text;
-       redraw();
+    this->text = text;
+    redraw();
 }
 
 void SvgFontDrawingArea::set_size(int x, int y){
@@ -46,10 +49,10 @@ void SvgFontDrawingArea::set_size(int x, int y){
 }
 
 void SvgFontDrawingArea::redraw(){
-       ((Gtk::Widget*) this)->queue_draw();
+    ((Gtk::Widget*) this)->queue_draw();
 }
 
-bool SvgFontDrawingArea::on_expose_event (GdkEventExpose *event){
+bool SvgFontDrawingArea::on_expose_event (GdkEventExpose */*event*/){
   if (this->svgfont){
     Glib::RefPtr<Gdk::Window> window = get_window();
     Cairo::RefPtr<Cairo::Context> cr = window->create_cairo_context();
@@ -89,40 +92,40 @@ SvgFontsDialog::AttrEntry::AttrEntry(SvgFontsDialog* d, gchar* lbl, const SPAttr
 }
 
 void SvgFontsDialog::AttrEntry::set_text(char* t){
-       if (!t) return;
-       entry.set_text(t);
+    if (!t) return;
+    entry.set_text(t);
 }
 
 void SvgFontsDialog::AttrEntry::on_attr_changed(){
 
-       SPObject* o = NULL;
-        for(SPObject* node = this->dialog->get_selected_spfont()->children; node; node=node->next){
-            switch(this->attr){
-               case SP_PROP_FONT_FAMILY:
-                       if (SP_IS_FONTFACE(node)){
-                               o = node;
-                               continue;
-                       }
-                       break;
-               default:
-                       o = NULL;
-           }
+    SPObject* o = NULL;
+    for(SPObject* node = this->dialog->get_selected_spfont()->children; node; node=node->next){
+        switch(this->attr){
+            case SP_PROP_FONT_FAMILY:
+                if (SP_IS_FONTFACE(node)){
+                    o = node;
+                    continue;
+                }
+                break;
+            default:
+                o = NULL;
         }
+    }
 
-       const gchar* name = (const gchar*)sp_attribute_name(this->attr);
-        if(name && o) {
-            SP_OBJECT_REPR(o)->setAttribute((const gchar*) name, this->entry.get_text().c_str());
-            o->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
+    const gchar* name = (const gchar*)sp_attribute_name(this->attr);
+    if(name && o) {
+        SP_OBJECT_REPR(o)->setAttribute((const gchar*) name, this->entry.get_text().c_str());
+        o->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
 
-            Glib::ustring undokey = "svgfonts:";
-            undokey += name;
-            sp_document_maybe_done(o->document, undokey.c_str(), SP_VERB_DIALOG_SVG_FONTS,
-                                   _("Set SVG Font attribute"));
-        }
+        Glib::ustring undokey = "svgfonts:";
+        undokey += name;
+        DocumentUndo::maybeDone(o->document, undokey.c_str(), SP_VERB_DIALOG_SVG_FONTS,
+                                _("Set SVG Font attribute"));
+    }
 
 }
 
-Gtk::HBox* SvgFontsDialog::AttrCombo(gchar* lbl, const SPAttributeEnum attr){
+Gtk::HBox* SvgFontsDialog::AttrCombo(gchar* lbl, const SPAttributeEnum /*attr*/){
     Gtk::HBox* hbox = Gtk::manage(new Gtk::HBox());
     hbox->add(* Gtk::manage(new Gtk::Label(lbl)) );
     hbox->add(* Gtk::manage(new Gtk::ComboBox()) );
@@ -145,10 +148,10 @@ GlyphComboBox::GlyphComboBox(){
 }
 
 void GlyphComboBox::update(SPFont* spfont){
-    if (!spfont) return 
+    if (!spfont) return
 //TODO: figure out why do we need to append_text("") before clearing items properly...
 
-       this->append_text(""); //Gtk is refusing to clear the combobox when I comment out this line
+    this->append_text(""); //Gtk is refusing to clear the combobox when I comment out this line
     this->clear_items();
 
     for(SPObject* node = spfont->children; node; node=node->next){
@@ -159,20 +162,22 @@ void GlyphComboBox::update(SPFont* spfont){
 }
 
 void SvgFontsDialog::on_kerning_value_changed(){
-       if (!this->kerning_pair) return;
-       SPDocument* document = sp_desktop_document(this->getDesktop());
+    if (!this->kerning_pair) return;
+    SPDocument* document = sp_desktop_document(this->getDesktop());
 
-       //TODO: I am unsure whether this is the correct way of calling sp_document_maybe_done
+    //TODO: I am unsure whether this is the correct way of calling SPDocumentUndo::maybe_done
     Glib::ustring undokey = "svgfonts:hkern:k:";
     undokey += this->kerning_pair->u1->attribute_string();
     undokey += ":";
     undokey += this->kerning_pair->u2->attribute_string();
 
-       //slider values increase from right to left so that they match the kerning pair preview
-    this->kerning_pair->repr->setAttribute("k", Glib::Ascii::dtostr(get_selected_spfont()->horiz_adv_x - kerning_slider.get_value()).c_str());
-    sp_document_maybe_done(document, undokey.c_str(), SP_VERB_DIALOG_SVG_FONTS, _("Adjust kerning value"));
+    //slider values increase from right to left so that they match the kerning pair preview
 
-       //populate_kerning_pairs_box();
+    //XML Tree being directly used here while it shouldn't be.
+    this->kerning_pair->getRepr()->setAttribute("k", Glib::Ascii::dtostr(get_selected_spfont()->horiz_adv_x - kerning_slider.get_value()).c_str());
+    DocumentUndo::maybeDone(document, undokey.c_str(), SP_VERB_DIALOG_SVG_FONTS, _("Adjust kerning value"));
+
+    //populate_kerning_pairs_box();
     kerning_preview.redraw();
     _font_da.redraw();
 }
@@ -234,7 +239,7 @@ void SvgFontsDialog::update_sensitiveness(){
         global_vbox.set_sensitive(false);
         glyphs_vbox.set_sensitive(false);
         kerning_vbox.set_sensitive(false);
-       }
+    }
 }
 
 /* Add all fonts in the document to the combobox. */
@@ -242,7 +247,7 @@ void SvgFontsDialog::update_fonts()
 {
     SPDesktop* desktop = this->getDesktop();
     SPDocument* document = sp_desktop_document(desktop);
-    const GSList* fonts = sp_document_get_resource_list(document, "font");
+    const GSList* fonts = document->getResourceList("font");
 
     _model->clear();
     for(const GSList *l = fonts; l; l = l->next) {
@@ -251,11 +256,11 @@ void SvgFontsDialog::update_fonts()
         row[_columns.spfont] = f;
         row[_columns.svgfont] = new SvgFont(f);
         const gchar* lbl = f->label();
-        const gchar* id = SP_OBJECT_ID(f);
+        const gchar* id = f->getId();
         row[_columns.label] = lbl ? lbl : (id ? id : "font");
     }
 
-       update_sensitiveness();
+    update_sensitiveness();
 }
 
 void SvgFontsDialog::on_preview_text_changed(){
@@ -264,32 +269,32 @@ void SvgFontsDialog::on_preview_text_changed(){
 }
 
 void SvgFontsDialog::on_kerning_pair_selection_changed(){
-       SPGlyphKerning* kern = get_selected_kerning_pair();
-       if (!kern) {
-               kerning_preview.set_text("");
-               return;
-       }
-       Glib::ustring str;
-       str += kern->u1->sample_glyph();
-       str += kern->u2->sample_glyph();
+    SPGlyphKerning* kern = get_selected_kerning_pair();
+    if (!kern) {
+        kerning_preview.set_text("");
+        return;
+    }
+    Glib::ustring str;
+    str += kern->u1->sample_glyph();
+    str += kern->u2->sample_glyph();
 
-       kerning_preview.set_text(str);
-       this->kerning_pair = kern;
+    kerning_preview.set_text(str);
+    this->kerning_pair = kern;
 
-       //slider values increase from right to left so that they match the kerning pair preview
-       kerning_slider.set_value(get_selected_spfont()->horiz_adv_x - kern->k);
+    //slider values increase from right to left so that they match the kerning pair preview
+    kerning_slider.set_value(get_selected_spfont()->horiz_adv_x - kern->k);
 }
 
 void SvgFontsDialog::update_global_settings_tab(){
-       SPFont* font = get_selected_spfont();
-       if (!font) return;
+    SPFont* font = get_selected_spfont();
+    if (!font) return;
 
-       SPObject* obj;
-       for (obj=font->children; obj; obj=obj->next){
-               if (SP_IS_FONTFACE(obj)){
-                       _familyname_entry->set_text(((SPFontFace*) obj)->font_family);
-               }
-       }
+    SPObject* obj;
+    for (obj=font->children; obj; obj=obj->next){
+        if (SP_IS_FONTFACE(obj)){
+            _familyname_entry->set_text(((SPFontFace*) obj)->font_family);
+        }
+    }
 }
 
 void SvgFontsDialog::on_font_selection_changed(){
@@ -310,10 +315,10 @@ void SvgFontsDialog::on_font_selection_changed(){
     kerning_slider.set_draw_value(false);
     kerning_slider.set_value(0);
 
-       update_global_settings_tab();
-       populate_glyphs_box();
-       populate_kerning_pairs_box();
-       update_sensitiveness();
+    update_global_settings_tab();
+    populate_glyphs_box();
+    populate_kerning_pairs_box();
+    update_sensitiveness();
 }
 
 void SvgFontsDialog::on_setwidth_changed(){
@@ -321,8 +326,8 @@ void SvgFontsDialog::on_setwidth_changed(){
     if (spfont){
         spfont->horiz_adv_x = setwidth_spin.get_value();
         //TODO: tell cairo that the glyphs cache has to be invalidated
-               //              The current solution is to recreate the whole cairo svgfont.
-               //              This is not a good solution to the issue because big fonts will result in poor performance.
+        //    The current solution is to recreate the whole cairo svgfont.
+        //    This is not a good solution to the issue because big fonts will result in poor performance.
         update_glyphs();
     }
 }
@@ -375,7 +380,7 @@ Gtk::VBox* SvgFontsDialog::global_settings_tab(){
 
     setwidth_spin.signal_changed().connect(sigc::mem_fun(*this, &SvgFontsDialog::on_setwidth_changed));
     setwidth_spin.set_range(0, 4096);
-    setwidth_spin.set_increments(10, 100);
+    setwidth_spin.set_increments(10, 0);
     global_vbox.pack_start(*setwidth_hbox, false, false);
 
     return &global_vbox;
@@ -384,45 +389,45 @@ Gtk::VBox* SvgFontsDialog::global_settings_tab(){
 void
 SvgFontsDialog::populate_glyphs_box()
 {
-       if (!_GlyphsListStore) return;
+    if (!_GlyphsListStore) return;
     _GlyphsListStore->clear();
 
-       SPFont* spfont = this->get_selected_spfont();
-       _glyphs_observer.set(spfont);
+    SPFont* spfont = this->get_selected_spfont();
+    _glyphs_observer.set(spfont);
 
     for(SPObject* node = spfont->children; node; node=node->next){
-               if (SP_IS_GLYPH(node)){
-                   Gtk::TreeModel::Row row = *(_GlyphsListStore->append());
-                   row[_GlyphsListColumns.glyph_node] = (SPGlyph*) node;
-                   row[_GlyphsListColumns.glyph_name] = ((SPGlyph*) node)->glyph_name;
-                   row[_GlyphsListColumns.unicode] = ((SPGlyph*) node)->unicode;
-               }
+        if (SP_IS_GLYPH(node)){
+            Gtk::TreeModel::Row row = *(_GlyphsListStore->append());
+            row[_GlyphsListColumns.glyph_node] = (SPGlyph*) node;
+            row[_GlyphsListColumns.glyph_name] = ((SPGlyph*) node)->glyph_name;
+            row[_GlyphsListColumns.unicode] = ((SPGlyph*) node)->unicode;
+        }
     }
 }
 
 void
 SvgFontsDialog::populate_kerning_pairs_box()
 {
-       if (!_KerningPairsListStore) return;
+    if (!_KerningPairsListStore) return;
     _KerningPairsListStore->clear();
 
-       SPFont* spfont = this->get_selected_spfont();
+    SPFont* spfont = this->get_selected_spfont();
 
     for(SPObject* node = spfont->children; node; node=node->next){
-               if (SP_IS_HKERN(node)){
-                   Gtk::TreeModel::Row row = *(_KerningPairsListStore->append());
-                   row[_KerningPairsListColumns.first_glyph] = ((SPGlyphKerning*) node)->u1->attribute_string().c_str();
-                   row[_KerningPairsListColumns.second_glyph] = ((SPGlyphKerning*) node)->u2->attribute_string().c_str();
-                   row[_KerningPairsListColumns.kerning_value] = ((SPGlyphKerning*) node)->k;
-                   row[_KerningPairsListColumns.spnode] = (SPGlyphKerning*) node;
-               }
+        if (SP_IS_HKERN(node)){
+            Gtk::TreeModel::Row row = *(_KerningPairsListStore->append());
+            row[_KerningPairsListColumns.first_glyph] = ((SPGlyphKerning*) node)->u1->attribute_string().c_str();
+            row[_KerningPairsListColumns.second_glyph] = ((SPGlyphKerning*) node)->u2->attribute_string().c_str();
+            row[_KerningPairsListColumns.kerning_value] = ((SPGlyphKerning*) node)->k;
+            row[_KerningPairsListColumns.spnode] = (SPGlyphKerning*) node;
+        }
     }
 }
 
 SPGlyph *new_glyph(SPDocument* document, SPFont *font, const int count)
 {
     g_return_val_if_fail(font != NULL, NULL);
-    Inkscape::XML::Document *xml_doc = sp_document_repr_doc(document);
+    Inkscape::XML::Document *xml_doc = document->getReprDoc();
 
     // create a new glyph
     Inkscape::XML::Node *repr;
@@ -438,7 +443,7 @@ SPGlyph *new_glyph(SPDocument* document, SPFont *font, const int count)
 
     // get corresponding object
     SPGlyph *g = SP_GLYPH( document->getObjectByRepr(repr) );
-    
+
     g_assert(g != NULL);
     g_assert(SP_IS_GLYPH(g));
 
@@ -446,13 +451,13 @@ SPGlyph *new_glyph(SPDocument* document, SPFont *font, const int count)
 }
 
 void SvgFontsDialog::update_glyphs(){
-       SPFont* font = get_selected_spfont();
-       if (!font) return;
+    SPFont* font = get_selected_spfont();
+    if (!font) return;
     populate_glyphs_box();
     populate_kerning_pairs_box();
     first_glyph.update(font);
     second_glyph.update(font);
-       get_selected_svgfont()->refresh();
+    get_selected_svgfont()->refresh();
     _font_da.redraw();
 }
 
@@ -461,93 +466,158 @@ void SvgFontsDialog::add_glyph(){
     SPDocument* doc = sp_desktop_document(this->getDesktop());
     /* SPGlyph* glyph =*/ new_glyph(doc, get_selected_spfont(), count+1);
 
-    sp_document_done(doc, SP_VERB_DIALOG_SVG_FONTS, _("Add glyph"));
+    DocumentUndo::done(doc, SP_VERB_DIALOG_SVG_FONTS, _("Add glyph"));
 
-       update_glyphs();
+    update_glyphs();
 }
 
 void SvgFontsDialog::set_glyph_description_from_selected_path(){
-    SPDocument* doc = sp_desktop_document(this->getDesktop());
-    Inkscape::Selection* sel = sp_desktop_selection(this->getDesktop());
-    if (sel->isEmpty()) return;
+    SPDesktop* desktop = this->getDesktop();
+    if (!desktop) {
+        g_warning("SvgFontsDialog: No active desktop");
+        return;
+    }
+
+    Inkscape::MessageStack *msgStack = sp_desktop_message_stack(desktop);
+    SPDocument* doc = sp_desktop_document(desktop);
+    Inkscape::Selection* sel = sp_desktop_selection(desktop);
+    if (sel->isEmpty()){
+        char *msg = _("Select a <b>path</b> to define the curves of a glyph");
+        msgStack->flash(Inkscape::ERROR_MESSAGE, msg);
+        return;
+    }
+
     Inkscape::XML::Node* node = (Inkscape::XML::Node*) g_slist_nth_data((GSList *)sel->reprList(), 0);
-    if (!node || !node->matchAttributeName("d")) return;
-       if (!node->attribute("d")) return; //TODO: give a message to the user
+    if (!node) return;//TODO: should this be an assert?
+    if (!node->matchAttributeName("d") || !node->attribute("d")){
+        char *msg = _("The selected object does not have a <b>path</b> description.");
+        msgStack->flash(Inkscape::ERROR_MESSAGE, msg);
+        return;
+    } //TODO: //Is there a better way to tell it to to the user?
 
-       Geom::PathVector pathv = sp_svg_read_pathv(node->attribute("d"));
+    Geom::PathVector pathv = sp_svg_read_pathv(node->attribute("d"));
 
-       //This matrix flips the glyph vertically
+    //This matrix flips the glyph vertically
     Geom::Matrix m(Geom::Coord(1),Geom::Coord(0),Geom::Coord(0),Geom::Coord(-1),Geom::Coord(0),Geom::Coord(0));
-       pathv*=m;
-       //then we offset it
-       pathv+=Geom::Point(Geom::Coord(0),Geom::Coord(get_selected_spfont()->horiz_adv_x));
-
-       get_selected_glyph()->repr->setAttribute("d", (char*) sp_svg_write_path (pathv));
-       sp_document_done(doc, SP_VERB_DIALOG_SVG_FONTS, _("Set glyph curves"));
+    pathv*=m;
+    //then we offset it
+    pathv+=Geom::Point(Geom::Coord(0),Geom::Coord(get_selected_spfont()->horiz_adv_x));
+
+    SPGlyph* glyph = get_selected_glyph();
+    if (!glyph){
+        char *msg = _("No glyph selected in the SVGFonts dialog.");
+        msgStack->flash(Inkscape::ERROR_MESSAGE, msg);
+        return;
+    }
+       //XML Tree being directly used here while it shouldn't be.
+    glyph->getRepr()->setAttribute("d", (char*) sp_svg_write_path (pathv));
+    DocumentUndo::done(doc, SP_VERB_DIALOG_SVG_FONTS, _("Set glyph curves"));
 
-       update_glyphs();
+    update_glyphs();
 }
 
 void SvgFontsDialog::missing_glyph_description_from_selected_path(){
-    SPDocument* doc = sp_desktop_document(this->getDesktop());
-    Inkscape::Selection* sel = sp_desktop_selection(this->getDesktop());
-    if (sel->isEmpty()) return;
+    SPDesktop* desktop = this->getDesktop();
+    if (!desktop) {
+        g_warning("SvgFontsDialog: No active desktop");
+        return;
+    }
+
+    Inkscape::MessageStack *msgStack = sp_desktop_message_stack(desktop);
+    SPDocument* doc = sp_desktop_document(desktop);
+    Inkscape::Selection* sel = sp_desktop_selection(desktop);
+    if (sel->isEmpty()){
+        char *msg = _("Select a <b>path</b> to define the curves of a glyph");
+        msgStack->flash(Inkscape::ERROR_MESSAGE, msg);
+        return;
+    }
+
     Inkscape::XML::Node* node = (Inkscape::XML::Node*) g_slist_nth_data((GSList *)sel->reprList(), 0);
-    if (!node || !node->matchAttributeName("d")) return;
-       if (!node->attribute("d")) return; //TODO: give a message to the user
+    if (!node) return;//TODO: should this be an assert?
+    if (!node->matchAttributeName("d") || !node->attribute("d")){
+        char *msg = _("The selected object does not have a <b>path</b> description.");
+        msgStack->flash(Inkscape::ERROR_MESSAGE, msg);
+        return;
+    } //TODO: //Is there a better way to tell it to to the user?
 
-       Geom::PathVector pathv = sp_svg_read_pathv(node->attribute("d"));
+    Geom::PathVector pathv = sp_svg_read_pathv(node->attribute("d"));
 
-       //This matrix flips the glyph vertically
+    //This matrix flips the glyph vertically
     Geom::Matrix m(Geom::Coord(1),Geom::Coord(0),Geom::Coord(0),Geom::Coord(-1),Geom::Coord(0),Geom::Coord(0));
-       pathv*=m;
-       //then we offset it
-//     pathv+=Geom::Point(Geom::Coord(0),Geom::Coord(get_selected_spfont()->horiz_adv_x));
-       pathv+=Geom::Point(Geom::Coord(0),Geom::Coord(1000));//TODO: use here the units-per-em attribute?
+    pathv*=m;
+    //then we offset it
+//  pathv+=Geom::Point(Geom::Coord(0),Geom::Coord(get_selected_spfont()->horiz_adv_x));
+    pathv+=Geom::Point(Geom::Coord(0),Geom::Coord(1000));//TODO: use here the units-per-em attribute?
+
+    SPObject* obj;
+    for (obj = get_selected_spfont()->children; obj; obj=obj->next){
+        if (SP_IS_MISSING_GLYPH(obj)){
+
+            //XML Tree being directly used here while it shouldn't be.
+            obj->getRepr()->setAttribute("d", (char*) sp_svg_write_path (pathv));
+            DocumentUndo::done(doc, SP_VERB_DIALOG_SVG_FONTS, _("Set glyph curves"));
+        }
+    }
 
-       SPObject* obj;
-       for (obj = get_selected_spfont()->children; obj; obj=obj->next){
-               if (SP_IS_MISSING_GLYPH(obj)){
-                       obj->repr->setAttribute("d", (char*) sp_svg_write_path (pathv));
-                       sp_document_done(doc, SP_VERB_DIALOG_SVG_FONTS, _("Set glyph curves"));
-               }
-       }
+    update_glyphs();
+}
+
+void SvgFontsDialog::reset_missing_glyph_description(){
+    SPDesktop* desktop = this->getDesktop();
+    if (!desktop) {
+        g_warning("SvgFontsDialog: No active desktop");
+        return;
+    }
 
-       update_glyphs();
+    SPDocument* doc = sp_desktop_document(desktop);
+    SPObject* obj;
+    for (obj = get_selected_spfont()->children; obj; obj=obj->next){
+        if (SP_IS_MISSING_GLYPH(obj)){
+            //XML Tree being directly used here while it shouldn't be.
+            obj->getRepr()->setAttribute("d", (char*) "M0,0h1000v1024h-1000z");
+            DocumentUndo::done(doc, SP_VERB_DIALOG_SVG_FONTS, _("Reset missing-glyph"));
+        }
+    }
+
+    update_glyphs();
 }
 
 void SvgFontsDialog::glyph_name_edit(const Glib::ustring&, const Glib::ustring& str){
-       Gtk::TreeModel::iterator i = _GlyphsList.get_selection()->get_selected();
-       if (!i) return;
+    Gtk::TreeModel::iterator i = _GlyphsList.get_selection()->get_selected();
+    if (!i) return;
 
-       SPGlyph* glyph = (*i)[_GlyphsListColumns.glyph_node];
-       glyph->repr->setAttribute("glyph-name", str.c_str());
+    SPGlyph* glyph = (*i)[_GlyphsListColumns.glyph_node];
+    //XML Tree being directly used here while it shouldn't be.
+    glyph->getRepr()->setAttribute("glyph-name", str.c_str());
 
     SPDocument* doc = sp_desktop_document(this->getDesktop());
-       sp_document_done(doc, SP_VERB_DIALOG_SVG_FONTS, _("Edit glyph name"));
+    DocumentUndo::done(doc, SP_VERB_DIALOG_SVG_FONTS, _("Edit glyph name"));
 
-       update_glyphs();
+    update_glyphs();
 }
 
 void SvgFontsDialog::glyph_unicode_edit(const Glib::ustring&, const Glib::ustring& str){
-       Gtk::TreeModel::iterator i = _GlyphsList.get_selection()->get_selected();
-       if (!i) return;
+    Gtk::TreeModel::iterator i = _GlyphsList.get_selection()->get_selected();
+    if (!i) return;
 
-       SPGlyph* glyph = (*i)[_GlyphsListColumns.glyph_node];
-       glyph->repr->setAttribute("unicode", str.c_str());
+    SPGlyph* glyph = (*i)[_GlyphsListColumns.glyph_node];
+    //XML Tree being directly used here while it shouldn't be.
+    glyph->getRepr()->setAttribute("unicode", str.c_str());
 
     SPDocument* doc = sp_desktop_document(this->getDesktop());
-       sp_document_done(doc, SP_VERB_DIALOG_SVG_FONTS, _("Set glyph unicode"));
+    DocumentUndo::done(doc, SP_VERB_DIALOG_SVG_FONTS, _("Set glyph unicode"));
 
-       update_glyphs();
+    update_glyphs();
 }
 
 void SvgFontsDialog::remove_selected_font(){
-       SPFont* font = get_selected_spfont();
+    SPFont* font = get_selected_spfont();
+    if (!font) return;
 
-    sp_repr_unparent(font->repr);
+    //XML Tree being directly used here while it shouldn't be.
+    sp_repr_unparent(font->getRepr());
     SPDocument* doc = sp_desktop_document(this->getDesktop());
-    sp_document_done(doc, SP_VERB_DIALOG_SVG_FONTS, _("Remove font"));
+    DocumentUndo::done(doc, SP_VERB_DIALOG_SVG_FONTS, _("Remove font"));
 
     update_fonts();
 }
@@ -558,11 +628,13 @@ void SvgFontsDialog::remove_selected_glyph(){
     Gtk::TreeModel::iterator i = _GlyphsList.get_selection()->get_selected();
     if(!i) return;
 
-       SPGlyph* glyph = (*i)[_GlyphsListColumns.glyph_node];
-    sp_repr_unparent(glyph->repr);
+    SPGlyph* glyph = (*i)[_GlyphsListColumns.glyph_node];
+
+       //XML Tree being directly used here while it shouldn't be.
+    sp_repr_unparent(glyph->getRepr());
 
     SPDocument* doc = sp_desktop_document(this->getDesktop());
-    sp_document_done(doc, SP_VERB_DIALOG_SVG_FONTS, _("Remove glyph"));
+    DocumentUndo::done(doc, SP_VERB_DIALOG_SVG_FONTS, _("Remove glyph"));
 
     update_glyphs();
 }
@@ -573,11 +645,13 @@ void SvgFontsDialog::remove_selected_kerning_pair(){
     Gtk::TreeModel::iterator i = _KerningPairsList.get_selection()->get_selected();
     if(!i) return;
 
-       SPGlyphKerning* pair = (*i)[_KerningPairsListColumns.spnode];
-    sp_repr_unparent(pair->repr);
+    SPGlyphKerning* pair = (*i)[_KerningPairsListColumns.spnode];
+
+       //XML Tree being directly used here while it shouldn't be.
+    sp_repr_unparent(pair->getRepr());
 
     SPDocument* doc = sp_desktop_document(this->getDesktop());
-    sp_document_done(doc, SP_VERB_DIALOG_SVG_FONTS, _("Remove kerning pair"));
+    DocumentUndo::done(doc, SP_VERB_DIALOG_SVG_FONTS, _("Remove kerning pair"));
 
     update_glyphs();
 }
@@ -588,54 +662,58 @@ Gtk::VBox* SvgFontsDialog::glyphs_tab(){
 
     Gtk::HBox* missing_glyph_hbox = Gtk::manage(new Gtk::HBox());
     Gtk::Label* missing_glyph_label = Gtk::manage(new Gtk::Label(_("Missing Glyph:")));
-       missing_glyph_hbox->pack_start(*missing_glyph_label, false,false);
-       missing_glyph_hbox->pack_start(missing_glyph_button, false,false);
-       missing_glyph_button.set_label(_("From selection..."));
+    missing_glyph_hbox->pack_start(*missing_glyph_label, false,false);
+    missing_glyph_hbox->pack_start(missing_glyph_button, false,false);
+    missing_glyph_hbox->pack_start(missing_glyph_reset_button, false,false);
+    missing_glyph_button.set_label(_("From selection..."));
     missing_glyph_button.signal_clicked().connect(sigc::mem_fun(*this, &SvgFontsDialog::missing_glyph_description_from_selected_path));
-       glyphs_vbox.pack_start(*missing_glyph_hbox, false,false);
+    missing_glyph_reset_button.set_label(_("Reset"));
+    missing_glyph_reset_button.signal_clicked().connect(sigc::mem_fun(*this, &SvgFontsDialog::reset_missing_glyph_description));
 
-       glyphs_vbox.add(_GlyphsListScroller);
-       _GlyphsListScroller.set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_ALWAYS);
+    glyphs_vbox.pack_start(*missing_glyph_hbox, false,false);
+
+    glyphs_vbox.add(_GlyphsListScroller);
+    _GlyphsListScroller.set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_ALWAYS);
     _GlyphsListScroller.set_size_request(-1, 290);//It seems that is does not work. Why? I want a box with larger height
-       _GlyphsListScroller.add(_GlyphsList);
+    _GlyphsListScroller.add(_GlyphsList);
     _GlyphsListStore = Gtk::ListStore::create(_GlyphsListColumns);
     _GlyphsList.set_model(_GlyphsListStore);
-    _GlyphsList.append_column_editable(_("Glyph Name"), _GlyphsListColumns.glyph_name);
-    _GlyphsList.append_column_editable(_("Unicode"), _GlyphsListColumns.unicode);
+    _GlyphsList.append_column_editable(_("Glyph name"), _GlyphsListColumns.glyph_name);
+    _GlyphsList.append_column_editable(_("Matching string"), _GlyphsListColumns.unicode);
 
     Gtk::HBox* hb = Gtk::manage(new Gtk::HBox());
-       add_glyph_button.set_label(_("Add Glyph"));
-       add_glyph_button.signal_clicked().connect(sigc::mem_fun(*this, &SvgFontsDialog::add_glyph));
+    add_glyph_button.set_label(_("Add Glyph"));
+    add_glyph_button.signal_clicked().connect(sigc::mem_fun(*this, &SvgFontsDialog::add_glyph));
 
-       hb->pack_start(add_glyph_button, false,false);
-       hb->pack_start(glyph_from_path_button, false,false);
+    hb->pack_start(add_glyph_button, false,false);
+    hb->pack_start(glyph_from_path_button, false,false);
 
-       glyphs_vbox.pack_start(*hb, false, false);
-       glyph_from_path_button.set_label(_("Get curves from selection..."));
+    glyphs_vbox.pack_start(*hb, false, false);
+    glyph_from_path_button.set_label(_("Get curves from selection..."));
     glyph_from_path_button.signal_clicked().connect(sigc::mem_fun(*this, &SvgFontsDialog::set_glyph_description_from_selected_path));
 
-       dynamic_cast<Gtk::CellRendererText*>( _GlyphsList.get_column_cell_renderer(0))->signal_edited().connect(
-                        sigc::mem_fun(*this, &SvgFontsDialog::glyph_name_edit));
+    dynamic_cast<Gtk::CellRendererText*>( _GlyphsList.get_column_cell_renderer(0))->signal_edited().connect(
+        sigc::mem_fun(*this, &SvgFontsDialog::glyph_name_edit));
 
-       dynamic_cast<Gtk::CellRendererText*>( _GlyphsList.get_column_cell_renderer(1))->signal_edited().connect(
-                        sigc::mem_fun(*this, &SvgFontsDialog::glyph_unicode_edit));
+    dynamic_cast<Gtk::CellRendererText*>( _GlyphsList.get_column_cell_renderer(1))->signal_edited().connect(
+        sigc::mem_fun(*this, &SvgFontsDialog::glyph_unicode_edit));
 
-       _glyphs_observer.signal_changed().connect(sigc::mem_fun(*this, &SvgFontsDialog::update_glyphs));
+    _glyphs_observer.signal_changed().connect(sigc::mem_fun(*this, &SvgFontsDialog::update_glyphs));
 
     return &glyphs_vbox;
 }
 
 void SvgFontsDialog::add_kerning_pair(){
-       if (first_glyph.get_active_text() == "" ||
-               second_glyph.get_active_text() == "") return;
+    if (first_glyph.get_active_text() == "" ||
+        second_glyph.get_active_text() == "") return;
 
     //look for this kerning pair on the currently selected font
     this->kerning_pair = NULL;
     for(SPObject* node = this->get_selected_spfont()->children; node; node=node->next){
-               //TODO: It is not really correct to get only the first byte of each string.
-               //TODO: We should also support vertical kerning
+        //TODO: It is not really correct to get only the first byte of each string.
+        //TODO: We should also support vertical kerning
         if (SP_IS_HKERN(node) && ((SPGlyphKerning*)node)->u1->contains((gchar) first_glyph.get_active_text().c_str()[0])
-                                  && ((SPGlyphKerning*)node)->u2->contains((gchar) second_glyph.get_active_text().c_str()[0]) ){
+            && ((SPGlyphKerning*)node)->u2->contains((gchar) second_glyph.get_active_text().c_str()[0]) ){
             this->kerning_pair = (SPGlyphKerning*)node;
             continue;
         }
@@ -643,25 +721,24 @@ void SvgFontsDialog::add_kerning_pair(){
 
     if (this->kerning_pair) return; //We already have this kerning pair
 
-       SPDocument* document = sp_desktop_document(this->getDesktop());
-       Inkscape::XML::Document *xml_doc = sp_document_repr_doc(document);
+    SPDocument* document = sp_desktop_document(this->getDesktop());
+    Inkscape::XML::Document *xml_doc = document->getReprDoc();
 
     // create a new hkern node
-       Inkscape::XML::Node *repr;
-    repr = xml_doc->createElement("svg:hkern");
+    Inkscape::XML::Node *repr = xml_doc->createElement("svg:hkern");
 
-       repr->setAttribute("u1", first_glyph.get_active_text().c_str());
-       repr->setAttribute("u2", second_glyph.get_active_text().c_str());
-       repr->setAttribute("k", "0");
+    repr->setAttribute("u1", first_glyph.get_active_text().c_str());
+    repr->setAttribute("u2", second_glyph.get_active_text().c_str());
+    repr->setAttribute("k", "0");
 
     // Append the new hkern node to the current font
-       SP_OBJECT_REPR(get_selected_spfont())->appendChild(repr);
-       Inkscape::GC::release(repr);
+    SP_OBJECT_REPR(get_selected_spfont())->appendChild(repr);
+    Inkscape::GC::release(repr);
 
-       // get corresponding object
+    // get corresponding object
     this->kerning_pair = SP_HKERN( document->getObjectByRepr(repr) );
 
-    sp_document_done(document, SP_VERB_DIALOG_SVG_FONTS, _("Add kerning pair"));
+    DocumentUndo::done(document, SP_VERB_DIALOG_SVG_FONTS, _("Add kerning pair"));
 }
 
 Gtk::VBox* SvgFontsDialog::kerning_tab(){
@@ -669,23 +746,23 @@ Gtk::VBox* SvgFontsDialog::kerning_tab(){
     create_kerning_pairs_popup_menu(_KerningPairsList, sigc::mem_fun(*this, &SvgFontsDialog::remove_selected_kerning_pair));
 
 //Kerning Setup:
-    kerning_vbox.add(*Gtk::manage(new Gtk::Label(_("Kerning Setup:"))));
+    kerning_vbox.add(*Gtk::manage(new Gtk::Label(_("Kerning Setup"))));
     Gtk::HBox* kerning_selector = Gtk::manage(new Gtk::HBox());
     kerning_selector->add(*Gtk::manage(new Gtk::Label(_("1st Glyph:"))));
     kerning_selector->add(first_glyph);
     kerning_selector->add(*Gtk::manage(new Gtk::Label(_("2nd Glyph:"))));
     kerning_selector->add(second_glyph);
     kerning_selector->add(add_kernpair_button);
-       add_kernpair_button.set_label(_("Add pair"));
-       add_kernpair_button.signal_clicked().connect(sigc::mem_fun(*this, &SvgFontsDialog::add_kerning_pair));
+    add_kernpair_button.set_label(_("Add pair"));
+    add_kernpair_button.signal_clicked().connect(sigc::mem_fun(*this, &SvgFontsDialog::add_kerning_pair));
     _KerningPairsList.get_selection()->signal_changed().connect(sigc::mem_fun(*this, &SvgFontsDialog::on_kerning_pair_selection_changed));
     kerning_slider.signal_value_changed().connect(sigc::mem_fun(*this, &SvgFontsDialog::on_kerning_value_changed));
 
     kerning_vbox.pack_start(*kerning_selector, false,false);
 
-       kerning_vbox.add(_KerningPairsListScroller);
-       _KerningPairsListScroller.set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_ALWAYS);
-       _KerningPairsListScroller.add(_KerningPairsList);
+    kerning_vbox.add(_KerningPairsListScroller);
+    _KerningPairsListScroller.set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_ALWAYS);
+    _KerningPairsListScroller.add(_KerningPairsList);
     _KerningPairsListStore = Gtk::ListStore::create(_KerningPairsListColumns);
     _KerningPairsList.set_model(_KerningPairsListStore);
     _KerningPairsList.append_column(_("First Unicode range"), _KerningPairsListColumns.first_glyph);
@@ -711,33 +788,32 @@ SPFont *new_font(SPDocument *document)
 
     SPDefs *defs = (SPDefs *) SP_DOCUMENT_DEFS(document);
 
-    Inkscape::XML::Document *xml_doc = sp_document_repr_doc(document);
+    Inkscape::XML::Document *xml_doc = document->getReprDoc();
 
     // create a new font
-    Inkscape::XML::Node *repr;
-    repr = xml_doc->createElement("svg:font");
-       
-       //By default, set the horizontal advance to 1024 units  
-       repr->setAttribute("horiz-adv-x", "1024");
+    Inkscape::XML::Node *repr = xml_doc->createElement("svg:font");
+
+    //By default, set the horizontal advance to 1024 units
+    repr->setAttribute("horiz-adv-x", "1024");
 
     // Append the new font node to defs
     SP_OBJECT_REPR(defs)->appendChild(repr);
 
-       //create a missing glyph
+    //create a missing glyph
     Inkscape::XML::Node *fontface;
     fontface = xml_doc->createElement("svg:font-face");
-       fontface->setAttribute("units-per-em", "1024");
+    fontface->setAttribute("units-per-em", "1024");
     repr->appendChild(fontface);
 
-       //create a missing glyph
+    //create a missing glyph
     Inkscape::XML::Node *mg;
     mg = xml_doc->createElement("svg:missing-glyph");
-       mg->setAttribute("d", "M0,0h1020v1024h-1020z");
+    mg->setAttribute("d", "M0,0h1000v1024h-1000z");
     repr->appendChild(mg);
 
     // get corresponding object
     SPFont *f = SP_FONT( document->getObjectByRepr(repr) );
-    
+
     g_assert(f != NULL);
     g_assert(SP_IS_FONT(f));
     Inkscape::GC::release(mg);
@@ -746,15 +822,16 @@ SPFont *new_font(SPDocument *document)
 }
 
 void set_font_family(SPFont* font, char* str){
-       if (!font) return;
-       SPObject* obj;
-       for (obj=font->children; obj; obj=obj->next){
-               if (SP_IS_FONTFACE(obj)){
-                       obj->repr->setAttribute("font-family", str);
-               }
-       }
+    if (!font) return;
+    SPObject* obj;
+    for (obj=font->children; obj; obj=obj->next){
+        if (SP_IS_FONTFACE(obj)){
+            //XML Tree being directly used here while it shouldn't be.
+            obj->getRepr()->setAttribute("font-family", str);
+        }
+    }
 
-    sp_document_done(font->document, SP_VERB_DIALOG_SVG_FONTS, _("Set font family"));
+    DocumentUndo::done(font->document, SP_VERB_DIALOG_SVG_FONTS, _("Set font family"));
 }
 
 void SvgFontsDialog::add_font(){
@@ -767,17 +844,18 @@ void SvgFontsDialog::add_font(){
     font->setLabel(os.str().c_str());
 
     os2 << "SVGFont " << count;
-       SPObject* obj;
-       for (obj=font->children; obj; obj=obj->next){
-               if (SP_IS_FONTFACE(obj)){
-                       obj->repr->setAttribute("font-family", os2.str().c_str());
-               }
-       }
+    SPObject* obj;
+    for (obj=font->children; obj; obj=obj->next){
+        if (SP_IS_FONTFACE(obj)){
+            //XML Tree being directly used here while it shouldn't be.
+            obj->getRepr()->setAttribute("font-family", os2.str().c_str());
+        }
+    }
 
     update_fonts();
 //    select_font(font);
 
-    sp_document_done(doc, SP_VERB_DIALOG_SVG_FONTS, _("Add font"));
+    DocumentUndo::done(doc, SP_VERB_DIALOG_SVG_FONTS, _("Add font"));
 }
 
 SvgFontsDialog::SvgFontsDialog()
@@ -814,8 +892,8 @@ SvgFontsDialog::SvgFontsDialog()
 //Text Preview:
     _preview_entry.signal_changed().connect(sigc::mem_fun(*this, &SvgFontsDialog::on_preview_text_changed));
     _getContents()->add((Gtk::Widget&) _font_da);
-    _preview_entry.set_text("Sample Text");
-    _font_da.set_text("Sample Text");
+    _preview_entry.set_text(_("Sample Text"));
+    _font_da.set_text(_("Sample Text"));
 
     Gtk::HBox* preview_entry_hbox = Gtk::manage(new Gtk::HBox());
     _getContents()->add(*preview_entry_hbox);
@@ -824,9 +902,9 @@ SvgFontsDialog::SvgFontsDialog()
 
     _FontsList.signal_button_release_event().connect_notify(sigc::mem_fun(*this, &SvgFontsDialog::fonts_list_button_release));
     create_fonts_popup_menu(_FontsList, sigc::mem_fun(*this, &SvgFontsDialog::remove_selected_font));
-       
-       _defs_observer.set(SP_DOCUMENT_DEFS(sp_desktop_document(this->getDesktop())));
-       _defs_observer.signal_changed().connect(sigc::mem_fun(*this, &SvgFontsDialog::update_fonts));
+
+    _defs_observer.set(SP_DOCUMENT_DEFS(sp_desktop_document(this->getDesktop())));
+    _defs_observer.signal_changed().connect(sigc::mem_fun(*this, &SvgFontsDialog::update_fonts));
 
     _getContents()->show_all();
 }
@@ -838,3 +916,14 @@ SvgFontsDialog::~SvgFontsDialog(){}
 } // namespace Inkscape
 
 #endif //#ifdef ENABLE_SVG_FONTS
+
+/*
+  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 :