// // 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; }
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()); } }
/** * 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; }
/** * 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; }
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); }
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 }
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); }
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; }
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")); }
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()); }
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); } }
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; }
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(); }
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; }
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; }
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) ); }
/** * \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); } }
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(); } }
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); } }
/** * @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()); }
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; }