示例#1
0
文件: Search.cpp 项目: cnirrad/ViLike
//
// Protected
//
bool
SearchSupport::find_all( const Glib::ustring &pattern )
{
    m_matches.clear();

    Glib::ustring text = m_buffer->get_text();

    GRegex *regex;
    GMatchInfo *match_info;
    GRegexCompileFlags compile_flags;
    GRegexMatchFlags match_options;
    GError *error = NULL;

    regex = g_regex_new( pattern.data(), 
                         compile_flags, 
                         match_options, &error );

    if ( error )
    {
        g_print("Error while creating regex: %s\n", error->message);
        return false;
    }

    
    if (!g_regex_match( regex, text.data(), 
                        match_options, &match_info ))
    {
        return false;
    }

    gint start, end;

    int idx=0;
    while (g_match_info_matches(match_info))
    {
        if (!g_match_info_fetch_pos( match_info, 0, &start, &end ))
        {
            m_matches.clear();
            return false;
        }

        MatchInfo *info = new MatchInfo();
        info->start_pos = start;
        info->end_pos = end;
        m_matches.push_back( info );

        g_match_info_next( match_info, NULL ); 
    }

    g_match_info_free( match_info );
    g_regex_unref( regex );

    return true;
}
示例#2
0
void Preferences::_errorDialog(Glib::ustring const &msg, Glib::ustring const &secondary)
{
    if (_quiet) return;
    if (_use_gui) {
        Gtk::MessageDialog err(
            msg, false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_OK, true);
        err.set_secondary_text(secondary);
        err.run();
    } else {
        g_message("%s", msg.data());
        g_message("%s", secondary.data());
    }
}
示例#3
0
/**
 * Set the string value of a key/name registry entry
 */ 
bool RegistryTool::setStringValue(const Glib::ustring &keyNameArg,
                                  const Glib::ustring &valueName,
                                  const Glib::ustring &value)
{
    Glib::ustring keyName = keyNameArg;
    bool ret = false;

    HKEY rootKey = HKEY_LOCAL_MACHINE; //default root
    //Trim out the root key if necessary
    for (KeyTableEntry *entry = keyTable; entry->key; entry++)
        {
        if (keyName.compare(0, entry->strlen, entry->str)==0)
            {
            rootKey = entry->key;
            keyName = keyName.substr(entry->strlen);
            }
        }
    //printf("trimmed string: '%s'\n", keyName.c_str());

    //Get or create the key
    gunichar2 *keyw       = g_utf8_to_utf16(keyName.data(), -1, 0,0,0);
    gunichar2 *valuenamew = g_utf8_to_utf16(valueName.data(), -1, 0,0,0);

    HKEY key;
    if (RegCreateKeyExW(rootKey, (WCHAR*) keyw,
                       0, NULL, REG_OPTION_NON_VOLATILE,
                       KEY_WRITE, NULL, &key, NULL))
    {
       fprintf(stderr, "RegistryTool: Could not create the registry key '%s'\n", keyName.c_str());
       goto fail;
    }

    // Set the value
    if (RegSetValueExW(key, (WCHAR*) valuenamew,
          0,  REG_SZ, (LPBYTE) value.data(), (DWORD) (value.size() + 1)))
    {
       fprintf(stderr, "RegistryTool: Could not set the value '%s'\n", value.c_str());
       goto failkey;
    }

    ret = true;
    
    failkey:
    RegCloseKey(key);
    
    fail:
    g_free(keyw);
    g_free(valuenamew);
    return ret;
}
示例#4
0
/**
 * A function to set the \c _value.
 *
 * This function sets ONLY the internal value, but it also sets the value
 * in the preferences structure.  To put it in the right place, \c PREF_DIR
 *  and \c pref_name() are used.
 *
 * To copy the data into _value the old memory must be free'd first.
 * It is important to note that \c g_free handles \c NULL just fine.  Then
 * the passed in value is duplicated using \c g_strdup().
 *
 * @param  in   The value to set.
 * @param  doc  A document that should be used to set the value.
 * @param  node The node where the value may be placed.
 */
const gchar *ParamComboBox::set(const gchar * in, SPDocument * /*doc*/, Inkscape::XML::Node * /*node*/)
{
    if (in == NULL) {
        return NULL; /* Can't have NULL string */
    }

    Glib::ustring settext;
    for (GSList * list = choices; list != NULL; list = g_slist_next(list)) {
        enumentry * entr = reinterpret_cast<enumentry *>(list->data);
        if ( !entr->guitext.compare(in) ) {
            settext = entr->value;
            break;  // break out of for loop
        }
    }
    if (!settext.empty()) {
        if (_value != NULL) {
            g_free(_value);
        }
        _value = g_strdup(settext.data());
        gchar * prefname = this->pref_name();
        Inkscape::Preferences *prefs = Inkscape::Preferences::get();
        prefs->setString(extension_pref_root + prefname, _value);
        g_free(prefname);
    }

    return _value;
}
示例#5
0
void
sp_action_set_name (SPAction *action, Glib::ustring const &name)
{
    g_free(action->name);
    action->name = g_strdup(name.data());
    action->signal_set_name.emit(name);
}
示例#6
0
void Inkscape::IO::dump_fopen_call( char const *utf8name, char const *id )
{
#ifdef INK_DUMP_FOPEN
    Glib::ustring str;
    for ( int i = 0; utf8name[i]; i++ )
    {
        if ( utf8name[i] == '\\' )
        {
            str += "\\\\";
        }
        else if ( (utf8name[i] >= 0x20) && ((0x0ff & utf8name[i]) <= 0x7f) )
        {
            str += utf8name[i];
        }
        else
        {
            gchar tmp[32];
            g_snprintf( tmp, sizeof(tmp), "\\x%02x", (0x0ff & utf8name[i]) );
            str += tmp;
        }
    }
    g_message( "fopen call %s for [%s]", id, str.data() );
#else
    (void)utf8name;
    (void)id;
#endif
}
示例#7
0
void ViCommandMode::execute_search(const Glib::ustring &cmd, char begin )
{
    //
    //     /{pattern}/{offset}<CR>
    // search forward for the [count]'th occurrence of
    // {pattern} and go {offset} lines up or down.
    //
    int count = 1;              
    int offset = 0;
    Glib::ustring pattern;

    int idx = cmd.find( begin ); 
    if (idx > 0)
    {
        Glib::ustring rest = cmd.substr(idx+1);
        offset = convert<int>(rest);

        pattern = cmd.substr(0, idx);
    }
    else
    {
        pattern = cmd;
    }

    Direction dir = Forward;
    if (begin == '?')  
        dir = Backward;

    g_print("Searching for %s with offset %i\n", pattern.data(), offset);

    Editor *ed = Application::get()->get_current_editor();
    ed->search(pattern, dir);
    
}
示例#8
0
URI URI::fromUtf8( gchar const* path ) throw (BadURIException) {
    if ( !path ) {
        throw MalformedURIException();
    }
    Glib::ustring tmp;
    for ( int i = 0; path[i]; i++ )
    {
        gint one = 0x0ff & path[i];
        if ( ('a' <= one && one <= 'z')
             || ('A' <= one && one <= 'Z')
             || ('0' <= one && one <= '9')
             || one == '_'
             || one == '-'
             || one == '!'
             || one == '.'
             || one == '~'
             || one == '\''
             || one == '('
             || one == ')'
             || one == '*'
            ) {
            tmp += (gunichar)one;
        } else {
            gchar scratch[4];
            g_snprintf( scratch, 4, "%c%02X", '%', one );
            tmp.append( scratch );
        }
    }
    const gchar *uri = tmp.data();
    URI result(uri);
    return result;
}
示例#9
0
文件: path.cpp 项目: myutwo/inkscape
void
PathParam::on_paste_button_click()
{
    Inkscape::UI::ClipboardManager *cm = Inkscape::UI::ClipboardManager::get();
    Glib::ustring svgd = cm->getPathParameter(SP_ACTIVE_DESKTOP);
    paste_param_path(svgd.data());
    DocumentUndo::done(param_effect->getSPDoc(), SP_VERB_DIALOG_LIVE_PATH_EFFECT,
                       _("Paste path parameter"));
}
示例#10
0
void PSXMLProtocol::encode(Document * in) {
  unsigned int s = _encoder_residual.size();
  Glib::ustring out = in->write_to_string();
  _encoder_residual.resize(s+out.bytes()+sizeof(__psxml_header_t));
  __psxml_header_t h = { "psxml",htonl(out.bytes()) };
  memcpy(&_encoder_residual[0]+s,&h,sizeof(__psxml_header_t));
  memcpy(&_encoder_residual[0]+s+sizeof(__psxml_header_t),
    out.data(),out.bytes());
}
示例#11
0
void ReplWindow::evaluate(Glib::ustring &expression)
{
    Scheme *scm = Application::get()->get_scheme();
    if (!expression.empty())
    {
        const char *errmsg;
        s7_pointer old_port, result;                
        int gc_loc = -1;

        //
        //  Open a port to catch error info
        //
        old_port = s7_set_current_error_port(scm, 
                s7_open_output_string(scm));
        if (old_port != s7_nil(scm))
        {
            gc_loc = s7_gc_protect(scm, old_port);
        }

        result = s7_eval_c_string(scm, expression.data());

        errmsg = s7_get_output_string(scm, s7_current_error_port(scm));

        append_text( "\n" );

        if ((errmsg) && (*errmsg))
        {
            append_text(errmsg);
        }
        else
        {
            char *result_as_string;
            result_as_string = s7_object_to_c_string(scm, result);
            if (result_as_string)
            {
                append_text(result_as_string);        
                free(result_as_string);
            }
        }

        s7_close_output_port(scm, s7_current_error_port(scm));
        s7_set_current_error_port(scm, old_port);
        if (gc_loc != -1)
            s7_gc_unprotect_at(scm, gc_loc);
    }
}
示例#12
0
bool
ReplWindow::on_key(GdkEventKey *e)
{

    g_print("ReplWindow key press\n");

    if (e->keyval == GDK_Return)
    {
        Glib::ustring exp = get_current_expression(); 
        evaluate(exp);

        g_print("expression: %s\n", exp.data());
        set_prompt();
    }

    return false;
}
示例#13
0
void CLGUI::on_cl_button_click_event()
{
   Glib::ustring utxt = txtGet->get_text();
   int len = utxt.size();
   const char* chtxt = utxt.data();

   String* str = new String(chtxt);
   delete[] chtxt;
   int index = str->a_to_i();
   delete str;

   int size = cl->size();
   if (index >= 1 && index <= size)
   {
      cl->remove(index);
   }
   update();
}
示例#14
0
bool mainwnd::open_file(const Glib::ustring& fn, bool setlist_mode)
{
    bool result;

    stop_playing();

    /*We aren't using a playlist if we've opened a file*/
    set_wsetlist_mode(setlist_mode);

    m_mainperf->clear_all();

    midifile f(fn);
    result = f.parse(m_mainperf, 0);
    m_modified = !result;

    if (!result) {
    	if(setlist_mode){
    		//We don't want dialog boxes in setlist mode!
    		printf("Error reading file: %s\n",fn.data());
    	}
    	else{
		    Gtk::MessageDialog errdialog(*this,
		            "Error reading file: " + fn, false,
		            Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
		    errdialog.run();
        }
        return false;
    }

    last_used_dir = fn.substr(0, fn.rfind("/") + 1);
    global_filename = fn;
    update_window_title();

    m_main_wid->reset();
    m_entry_notes->set_text(*m_mainperf->get_screen_set_notepad(
                m_mainperf->get_screenset()));
    m_adjust_bpm->set_value( m_mainperf->get_bpm());

    //Check what the max tick is
    m_mainperf->update_max_tick();

    return true;
}
示例#15
0
static gchar* getImageEditorName() {
    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
    gchar* value = 0;
    Glib::ustring choices = prefs->getString("/options/bitmapeditor/choices");
    if (!choices.empty()) {
        gchar** splits = g_strsplit(choices.data(), ",", 0);
        gint numIems = g_strv_length(splits);

        int setting = prefs->getIntLimited("/options/bitmapeditor/value", 0, 0, numIems);
        value = g_strdup(splits[setting]);

        g_strfreev(splits);
    }

    if (!value) {
        value = g_strdup("gimp");
    }
    return value;
}
示例#16
0
static void sp_spl_tb_value_changed(GtkAdjustment *adj, GObject *tbl, Glib::ustring const &value_name)
{
    SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( tbl, "desktop" ));

    if (DocumentUndo::getUndoSensitive(desktop->getDocument())) {
        Inkscape::Preferences *prefs = Inkscape::Preferences::get();
        prefs->setDouble("/tools/shapes/spiral/" + value_name,
            gtk_adjustment_get_value(adj));
    }

    // quit if run by the attr_changed listener
    if (g_object_get_data( tbl, "freeze" )) {
        return;
    }

    // in turn, prevent listener from responding
    g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) );

    gchar* namespaced_name = g_strconcat("sodipodi:", value_name.data(), NULL);

    bool modmade = false;
    std::vector<SPItem*> itemlist=desktop->getSelection()->itemList();
    for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end(); ++i){
        SPItem *item = *i;
        if (SP_IS_SPIRAL(item)) {
            Inkscape::XML::Node *repr = item->getRepr();
            sp_repr_set_svg_double( repr, namespaced_name,
                gtk_adjustment_get_value(adj) );
            item->updateRepr();
            modmade = true;
        }
    }

    g_free(namespaced_name);

    if (modmade) {
        DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_SPIRAL,
                           _("Change spiral"));
    }

    g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) );
}
示例#17
0
文件: init.cpp 项目: Drooids/inkscape
/**
 * \return    none
 * \brief     Examines the given string preference and checks to see
 *            that at least one of the registered extensions matches
 *            it.  If not, a default is assigned.
 * \param     pref_path        Preference path to update
 * \param     pref_default     Default string to set
 * \param     extension_family List of extensions to search
 */
static void
update_pref(Glib::ustring const &pref_path,
            gchar const *pref_default) // , GSList *extension_family)
{
    Glib::ustring pref = Inkscape::Preferences::get()->getString(pref_path);
    /*
    gboolean missing=TRUE;
    for (GSList *list = extension_family; list; list = g_slist_next(list)) {
        g_assert( list->data );

        Inkscape::Extension *extension;
        extension = reinterpret_cast<Inkscape::Extension *>(list->data);

        if (!strcmp(extension->get_id(),pref)) missing=FALSE;
    }
    */
    if (!Inkscape::Extension::db.get( pref.data() ) /*missing*/) {
        Inkscape::Preferences::get()->setString(pref_path, pref_default);
    }
}
示例#18
0
void ViCommandMode::execute_command(const Glib::ustring &cmd_line)
{
    // TODO: more intelligent parsing
    Glib::ustring cmd;
    int idx = cmd_line.find_first_of(' ');
    if (idx > 0)
    {
        m_cmd_params = cmd_line.substr(idx+1);
        cmd = cmd_line.substr(0, idx);
    }
    else
    {
        cmd = cmd_line;
        m_cmd_params = "";
    }

    g_print("Command %s with params '%s'\n", cmd.data(), m_cmd_params.data());

    ExecutableAction *act = m_commandMap[cmd];
    if (act)
    {
        act->execute();
    }
}
void dialog::on_bok_click(Gtk::Entry *bvalue,int j)
{
    const char* c;
    unsigned int i;
    int t=0;
    bool correctco=true;
    Glib::ustring s;
    s=bvalue->get_text();
    c=s.data();
    if(strlen(c)==0)
        {
            Gtk::MessageDialog dlg("You cannot leave values empty", false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_OK, true);
            dlg.set_title("Empty Box");
            dlg.run();
            correctco=false;
        }
    if(correctco==true)
    {
            for(i=0;i<strlen(c);i++)
            {
                if(!(((c[i]>='0')&&(c[i]<='9'))||((c[i]=='-')&&(i==0)&&((j==1)||(j==3)))))
                {
                    Gtk::MessageDialog dlg("Please enter a integer value", false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_OK, true);
                    dlg.set_title("Non Integer Value");
                    dlg.run();
                    correctco=false;
                    break;
                }
            }
    }
    if(correctco==true)
    {
        sscanf(c,"%d",&t);
        switch(j)
        {
            case 1: if(t<-255||t>255)
                    {
                        Gtk::MessageDialog dlg("Please enter a integer value between -255 and 255", false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_OK, true);
                        dlg.set_title("Value not in limits");
                        dlg.run();
                        correctco=false;
                    }
                    if(correctco==true)
                    im->brightness(t);
                    im->addprocess(5,t);
                    break;
            case 2: if(t<1||t>20)
                    {
                        Gtk::MessageDialog dlg("Please enter a integer value between 1 and 20", false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_OK, true);
                        dlg.set_title("Value not in limits");
                        dlg.run();
                        correctco=false;
                    }
                    if(correctco==true)
                    im->blur(t);
                    im->addprocess(4,t);
                    break;
            case 3: if(t<-360||t>360)
                    {
                        Gtk::MessageDialog dlg("Please enter a integer value between -360 and 360", false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_OK, true);
                        dlg.set_title("Value not in limits");
                        dlg.run();
                        correctco=false;
                    }
                    if(correctco==true)
                    im->rotate(t);
                    im->addprocess(7,t);
                    break;
            case 4: if(t<4||t>16)
                    {
                        Gtk::MessageDialog dlg("Please enter a integer value between 4 and 16", false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_OK, true);
                        dlg.set_title("Value not in limits");
                        dlg.run();
                        correctco=false;
                    }
                    if(correctco==true)
                    im->posterize(t);
                    im->addprocess(15,t);
                    break;
        }
    }
    if(correctco==true)
    {
        im->no_undo=0;
        im->is_save=false;
        im->createim();
        if(imagestatus)
        {
            m_image->set(".image_temp.bmp");
        }
        hide();
    }
}
示例#20
0
ParamComboBox::ParamComboBox(const gchar *name, const gchar *guitext, const gchar *desc,
                             const Parameter::_scope_t scope, bool gui_hidden, const gchar *gui_tip,
                             Inkscape::Extension::Extension *ext, Inkscape::XML::Node *xml)
    : Parameter(name, guitext, desc, scope, gui_hidden, gui_tip, ext)
    , _value(NULL)
    , _indent(0)
    , choices(NULL)
{
    const char *xmlval = NULL; // the value stored in XML

    if (xml != NULL) {
        // Read XML tree to add enumeration items:
        for (Inkscape::XML::Node *node = xml->firstChild(); node; node = node->next()) {
            char const * chname = node->name();
            if (!strcmp(chname, INKSCAPE_EXTENSION_NS "item") || !strcmp(chname, INKSCAPE_EXTENSION_NS "_item")) {
                Glib::ustring newguitext, newvalue;
                const char * contents = NULL;
                if (node->firstChild()) {
                    contents = node->firstChild()->content();
                }
                if (contents != NULL) {
                    // don't translate when 'item' but do translate when '_item'
                    // NOTE: internal extensions use build_from_mem and don't need _item but
                    //       still need to include if are to be localized
                    if (!strcmp(chname, INKSCAPE_EXTENSION_NS "_item")) {
                        if (node->attribute("msgctxt") != NULL) {
                            newguitext =  g_dpgettext2(NULL, node->attribute("msgctxt"), contents);
                        } else {
                            newguitext =  _(contents);
                        }
                    } else {
                        newguitext =  contents;
                    }
                } else
                    continue;

                const char * val = node->attribute("value");
                if (val != NULL) {
                    newvalue = val;
                } else {
                    newvalue = contents;
                }

                if ( (!newguitext.empty()) && (!newvalue.empty()) ) {   // logical error if this is not true here
                    choices = g_slist_append( choices, new enumentry(newvalue, newguitext) );
                }
            }
        }
    
        // Initialize _value with the default value from xml
        // for simplicity : default to the contents of the first xml-child
        if (xml->firstChild() && xml->firstChild()->firstChild()) {
            xmlval = xml->firstChild()->attribute("value");
        }

        const char *indent = xml->attribute("indent");
        if (indent != NULL) {
            _indent = atoi(indent) * 12;
        }
    }

    gchar * pref_name = this->pref_name();
    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
    Glib::ustring paramval = prefs ? prefs->getString(extension_pref_root + pref_name) : "";
    g_free(pref_name);

    if (!paramval.empty()) {
        _value = g_strdup(paramval.data());
    } else if (xmlval) {
        _value = g_strdup(xmlval);
    }
}
示例#21
0
/**
 * @brief Set a string attribute of a preference
 * @param pref_path Path of the preference to modify
 * @param value The new value of the pref attribute
 */
void Preferences::setString(Glib::ustring const &pref_path, Glib::ustring const &value)
{
    _setRawValue(pref_path, value.data());
}
示例#22
0
ParamRadioButton::ParamRadioButton (const gchar * name,
                                    const gchar * guitext,
                                    const gchar * desc,
                                    const Parameter::_scope_t scope,
                                    bool gui_hidden,
                                    const gchar * gui_tip,
                                    Inkscape::Extension::Extension * ext,
                                    Inkscape::XML::Node * xml,
                                    AppearanceMode mode) :
    Parameter(name, guitext, desc, scope, gui_hidden, gui_tip, ext),
    _value(0),
    _mode(mode),
    choices(0)
{
    // Read XML tree to add enumeration items:
    // printf("Extension Constructor: ");
    if (xml != NULL) {
        Inkscape::XML::Node *child_repr = sp_repr_children(xml);
        while (child_repr != NULL) {
            char const * chname = child_repr->name();
            if (!strcmp(chname, INKSCAPE_EXTENSION_NS "option") || !strcmp(chname, INKSCAPE_EXTENSION_NS "_option")) {
                Glib::ustring * newguitext = NULL;
                Glib::ustring * newvalue = NULL;
                const char * contents = sp_repr_children(child_repr)->content();

                if (contents != NULL)
                    // don't translate when 'option' but do translate when '_option'
                    newguitext = new Glib::ustring( !strcmp(chname, INKSCAPE_EXTENSION_NS "_option") ? _(contents) : contents );
                else
                    continue;

                const char * val = child_repr->attribute("value");
                if (val != NULL)
                    newvalue = new Glib::ustring(val);
                else
                    newvalue = new Glib::ustring(contents);

                if ( (newguitext) && (newvalue) ) {   // logical error if this is not true here
                    choices = g_slist_append( choices, new optionentry(newvalue, newguitext) );
                }
            }
            child_repr = sp_repr_next(child_repr);
        }
    }

    // Initialize _value with the default value from xml
    // for simplicity : default to the contents of the first xml-child
    const char * defaultval = NULL;
    if (choices)
        defaultval = ((optionentry*) choices->data)->value->c_str();

    gchar * pref_name = this->pref_name();
    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
    Glib::ustring paramval = prefs->getString(extension_pref_root + pref_name);
    g_free(pref_name);

    if (!paramval.empty())
        defaultval = paramval.data();
    if (defaultval != NULL)
        _value = g_strdup(defaultval);  // allocate space for _value

    return;
}
SPDocument *
sp_document_create(Inkscape::XML::Document *rdoc,
                   gchar const *uri,
                   gchar const *base,
                   gchar const *name,
                   unsigned int keepalive)
{
    SPDocument *document;
    Inkscape::XML::Node *rroot;
    Inkscape::Version sodipodi_version;
    Inkscape::Preferences *prefs = Inkscape::Preferences::get();

    rroot = rdoc->root();

    document = new SPDocument();

    document->keepalive = keepalive;

    document->rdoc = rdoc;
    document->rroot = rroot;

#ifndef WIN32
    prepend_current_dir_if_relative(&(document->uri), uri);
#else
    // FIXME: it may be that prepend_current_dir_if_relative works OK on windows too, test!
    document->uri = uri? g_strdup(uri) : NULL;
#endif

    // base is simply the part of the path before filename; e.g. when running "inkscape ../file.svg" the base is "../"
    // which is why we use g_get_current_dir() in calculating the abs path above
    //This is NULL for a new document
    if (base)
        document->base = g_strdup(base);
    else
        document->base = NULL;
    document->name = g_strdup(name);

    document->root = sp_object_repr_build_tree(document, rroot);

    sodipodi_version = SP_ROOT(document->root)->version.sodipodi;

    /* fixme: Not sure about this, but lets assume ::build updates */
    rroot->setAttribute("sodipodi:version", SODIPODI_VERSION);
    rroot->setAttribute("inkscape:version", Inkscape::version_string);
    /* fixme: Again, I moved these here to allow version determining in ::build (Lauris) */

    /* Quick hack 2 - get default image size into document */
    if (!rroot->attribute("width")) rroot->setAttribute("width", "100%");
    if (!rroot->attribute("height")) rroot->setAttribute("height", "100%");
    /* End of quick hack 2 */

    /* Quick hack 3 - Set uri attributes */
    if (uri) {
        rroot->setAttribute("sodipodi:docname", uri);
    }
    /* End of quick hack 3 */

    /* Eliminate obsolete sodipodi:docbase, for privacy reasons */
    rroot->setAttribute("sodipodi:docbase", NULL);
    
    /* Eliminate any claim to adhere to a profile, as we don't try to */
    rroot->setAttribute("baseProfile", NULL);

    // creating namedview
    if (!sp_item_group_get_child_by_name((SPGroup *) document->root, NULL, "sodipodi:namedview")) {
        // if there's none in the document already,
        Inkscape::XML::Node *rnew = NULL;
        
        rnew = rdoc->createElement("sodipodi:namedview");
        //rnew->setAttribute("id", "base");

        // Add namedview data from the preferences
        // we can't use getAllEntries because this could produce non-SVG doubles
        Glib::ustring pagecolor = prefs->getString("/template/base/pagecolor");
        if (!pagecolor.empty()) {
            rnew->setAttribute("pagecolor", pagecolor.data());
        }
        Glib::ustring bordercolor = prefs->getString("/template/base/bordercolor");
        if (!bordercolor.empty()) {
            rnew->setAttribute("bordercolor", bordercolor.data());
        }
        sp_repr_set_svg_double(rnew, "borderopacity",
            prefs->getDouble("/template/base/borderopacity", 1.0));
        sp_repr_set_svg_double(rnew, "objecttolerance",
            prefs->getDouble("/template/base/objecttolerance", 10.0));
        sp_repr_set_svg_double(rnew, "gridtolerance",
            prefs->getDouble("/template/base/gridtolerance", 10.0));
        sp_repr_set_svg_double(rnew, "guidetolerance",
            prefs->getDouble("/template/base/guidetolerance", 10.0));
        sp_repr_set_svg_double(rnew, "inkscape:pageopacity",
            prefs->getDouble("/template/base/inkscape:pageopacity", 0.0));
        sp_repr_set_int(rnew, "inkscape:pageshadow",
            prefs->getInt("/template/base/inkscape:pageshadow", 2));
        sp_repr_set_int(rnew, "inkscape:window-width",
            prefs->getInt("/template/base/inkscape:window-width", 640));
        sp_repr_set_int(rnew, "inkscape:window-height",
            prefs->getInt("/template/base/inkscape:window-height", 480));
        
        // insert into the document
        rroot->addChild(rnew, NULL);
        // clean up
        Inkscape::GC::release(rnew);
    }

    /* Defs */
    if (!SP_ROOT(document->root)->defs) {
        Inkscape::XML::Node *r;
        r = rdoc->createElement("svg:defs");
        rroot->addChild(r, NULL);
        Inkscape::GC::release(r);
        g_assert(SP_ROOT(document->root)->defs);
    }

    /* Default RDF */
    rdf_set_defaults( document );

    if (keepalive) {
        inkscape_ref();
    }

    // Remark: Here, we used to create a "currentpersp3d" element in the document defs.
    // But this is probably a bad idea since we need to adapt it for every change of selection, which will
    // completely clutter the undo history. Maybe rather save it to prefs on exit and re-read it on startup?

    document->current_persp3d = persp3d_document_first_persp(document);
    if (!document->current_persp3d) {
        document->current_persp3d = persp3d_create_xml_element (document);
    }

    sp_document_set_undo_sensitive(document, true);

    // reset undo key when selection changes, so that same-key actions on different objects are not coalesced
    if (!Inkscape::NSApplication::Application::getNewGui()) {
        g_signal_connect(G_OBJECT(INKSCAPE), "change_selection",
                         G_CALLBACK(sp_document_reset_key), document);
        g_signal_connect(G_OBJECT(INKSCAPE), "activate_desktop",
                         G_CALLBACK(sp_document_reset_key), document);
    } else {
        document->_selection_changed_connection = Inkscape::NSApplication::Editor::connectSelectionChanged (sigc::mem_fun (*document, &SPDocument::reset_key));
        document->_desktop_activated_connection = Inkscape::NSApplication::Editor::connectDesktopActivated (sigc::mem_fun (*document, &SPDocument::reset_key));
    }

    return document;
}