X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Finterface.cpp;h=0259ecb6602dd52d7f62c0f53e5a7cded9f1d31e;hb=0f51f94e09af3ab07d55c057a09b44f0790599b9;hp=26552d510133fd1faf82da13568d26e21cb60416;hpb=91ff754f4da47efc8f558ea87cfcf92f86934944;p=inkscape.git diff --git a/src/interface.cpp b/src/interface.cpp index 26552d510..0259ecb66 100644 --- a/src/interface.cpp +++ b/src/interface.cpp @@ -33,13 +33,16 @@ #include "file.h" #include "interface.h" #include "desktop.h" -#include "object-ui.h" +#include "ui/context-menu.h" #include "selection.h" #include "selection-chemistry.h" #include "svg-view-widget.h" #include "widgets/desktop-widget.h" #include "sp-item-group.h" +#include "sp-text.h" +#include "sp-flowtext.h" #include "sp-namedview.h" +#include "ui/view/view.h" #include "helper/action.h" #include "helper/gnome-utils.h" @@ -54,19 +57,25 @@ #include "message-context.h" // Added for color drag-n-drop +#if ENABLE_LCMS +#include "lcms.h" +#endif // ENABLE_LCMS #include "display/sp-canvas.h" #include "color.h" #include "svg/svg-color.h" #include "desktop-style.h" #include "style.h" +#include "event-context.h" +#include "gradient-drag.h" +// Include Mac OS X menu synchronization on native OSX build +#ifdef GDK_WINDOWING_QUARTZ +#include "ige-mac-menu.h" +#endif using Inkscape::IO::StringOutputStream; using Inkscape::IO::Base64OutputStream; -/* forward declaration */ -static gint sp_ui_delete(GtkWidget *widget, GdkEvent *event, Inkscape::UI::View::View *view); - /* Drag and Drop */ typedef enum { URI_LIST, @@ -75,16 +84,20 @@ typedef enum { PNG_DATA, JPEG_DATA, IMAGE_DATA, + APP_X_INKY_COLOR, APP_X_COLOR } ui_drop_target_info; static GtkTargetEntry ui_drop_target_entries [] = { - {"text/uri-list", 0, URI_LIST}, - {"image/svg+xml", 0, SVG_XML_DATA}, - {"image/svg", 0, SVG_DATA}, - {"image/png", 0, PNG_DATA}, - {"image/jpeg", 0, JPEG_DATA}, - {"application/x-color", 0, APP_X_COLOR} + {(gchar *)"text/uri-list", 0, URI_LIST }, + {(gchar *)"image/svg+xml", 0, SVG_XML_DATA }, + {(gchar *)"image/svg", 0, SVG_DATA }, + {(gchar *)"image/png", 0, PNG_DATA }, + {(gchar *)"image/jpeg", 0, JPEG_DATA }, +#if ENABLE_MAGIC_COLORS + {(gchar *)"application/x-inkscape-color", 0, APP_X_INKY_COLOR}, +#endif // ENABLE_MAGIC_COLORS + {(gchar *)"application/x-color", 0, APP_X_COLOR } }; static GtkTargetEntry *completeDropTargets = 0; @@ -102,54 +115,108 @@ static void sp_ui_drag_data_received(GtkWidget *widget, guint info, guint event_time, gpointer user_data); +static void sp_ui_drag_motion( GtkWidget *widget, + GdkDragContext *drag_context, + gint x, gint y, + GtkSelectionData *data, + guint info, + guint event_time, + gpointer user_data ); +static void sp_ui_drag_leave( GtkWidget *widget, + GdkDragContext *drag_context, + guint event_time, + gpointer user_data ); static void sp_ui_menu_item_set_sensitive(SPAction *action, unsigned int sensitive, void *data); +static void sp_ui_menu_item_set_name(SPAction *action, + Glib::ustring name, + void *data); SPActionEventVector menu_item_event_vector = { {NULL}, NULL, NULL, /* set_active */ sp_ui_menu_item_set_sensitive, /* set_sensitive */ - NULL /* set_shortcut */ + NULL, /* set_shortcut */ + sp_ui_menu_item_set_name /* set_name */ }; +static const int MIN_ONSCREEN_DISTANCE = 50; + void sp_create_window(SPViewWidget *vw, gboolean editable) { - GtkWidget *w, *hb; - g_return_if_fail(vw != NULL); g_return_if_fail(SP_IS_VIEW_WIDGET(vw)); - w = sp_window_new("", TRUE); + Gtk::Window *win = Inkscape::UI::window_new("", TRUE); + + gtk_container_add(GTK_CONTAINER(win->gobj()), GTK_WIDGET(vw)); + gtk_widget_show(GTK_WIDGET(vw)); if (editable) { - g_object_set_data(G_OBJECT(vw), "window", w); - reinterpret_cast(vw)->window = - static_cast((void*)w); - } + g_object_set_data(G_OBJECT(vw), "window", win); + + SPDesktopWidget *desktop_widget = reinterpret_cast(vw); + SPDesktop* desktop = desktop_widget->desktop; + + desktop_widget->window = win; + + win->set_data("desktop", desktop); + win->set_data("desktopwidget", desktop_widget); + + win->signal_delete_event().connect(sigc::mem_fun(*(SPDesktop*)vw->view, &SPDesktop::onDeleteUI)); + win->signal_window_state_event().connect(sigc::mem_fun(*desktop, &SPDesktop::onWindowStateEvent)); + win->signal_focus_in_event().connect(sigc::mem_fun(*desktop_widget, &SPDesktopWidget::onFocusInEvent)); + + gint prefs_geometry = + (2==prefs_get_int_attribute("options.savewindowgeometry", "value", 0)); + if (prefs_geometry) { + gint pw = prefs_get_int_attribute("desktop.geometry", "width", -1); + gint ph = prefs_get_int_attribute("desktop.geometry", "height", -1); + gint px = prefs_get_int_attribute("desktop.geometry", "x", -1); + gint py = prefs_get_int_attribute("desktop.geometry", "y", -1); + gint full = prefs_get_int_attribute("desktop.geometry", "fullscreen", 0); + gint maxed = prefs_get_int_attribute("desktop.geometry", "maximized", 0); + if (pw>0 && ph>0) { + gint w = MIN(gdk_screen_width(), pw); + gint h = MIN(gdk_screen_height(), ph); + gint x = MIN(gdk_screen_width() - MIN_ONSCREEN_DISTANCE, px); + gint y = MIN(gdk_screen_height() - MIN_ONSCREEN_DISTANCE, py); + if (w>0 && h>0 && x>0 && y>0) { + x = MIN(gdk_screen_width() - w, x); + y = MIN(gdk_screen_height() - h, y); + } + if (w>0 && h>0) { + desktop->setWindowSize(w, h); + } - hb = gtk_hbox_new(FALSE, 0); - gtk_widget_show(hb); - gtk_container_add(GTK_CONTAINER(w), hb); - g_object_set_data(G_OBJECT(w), "hbox", hb); + // Only restore xy for the first window so subsequent windows don't overlap exactly + // with first. (Maybe rule should be only restore xy if it's different from xy of + // other desktops?) + + // Empirically it seems that active_desktop==this desktop only the first time a + // desktop is created. + if (x>0 && y>0) { + SPDesktop *active_desktop = SP_ACTIVE_DESKTOP; + if (active_desktop == desktop || active_desktop==NULL) { + desktop->setWindowPosition(NR::Point(x, y)); + } + } + } + if (maxed) { + win->maximize(); + } + if (full) { + win->fullscreen(); + } + } - /* fixme: */ - if (editable) { - gtk_window_set_default_size((GtkWindow *) w, 640, 480); - g_object_set_data(G_OBJECT(w), "desktop", SP_DESKTOP_WIDGET(vw)->desktop); - g_object_set_data(G_OBJECT(w), "desktopwidget", vw); - g_signal_connect(G_OBJECT(w), "delete_event", G_CALLBACK(sp_ui_delete), vw->view); - g_signal_connect(G_OBJECT(w), "focus_in_event", G_CALLBACK(sp_desktop_widget_set_focus), vw); } else { - gtk_window_set_policy(GTK_WINDOW(w), TRUE, TRUE, TRUE); + gtk_window_set_policy(GTK_WINDOW(win->gobj()), TRUE, TRUE, TRUE); } - gtk_box_pack_end(GTK_BOX(hb), GTK_WIDGET(vw), TRUE, TRUE, 0); - gtk_widget_show(GTK_WIDGET(vw)); - - if ( completeDropTargets == 0 || completeDropTargetsCount == 0 ) { std::vector types; @@ -181,16 +248,26 @@ sp_create_window(SPViewWidget *vw, gboolean editable) } } - gtk_drag_dest_set(w, + gtk_drag_dest_set((GtkWidget*)win->gobj(), GTK_DEST_DEFAULT_ALL, completeDropTargets, completeDropTargetsCount, GdkDragAction(GDK_ACTION_COPY | GDK_ACTION_MOVE)); - g_signal_connect(G_OBJECT(w), + + + g_signal_connect(G_OBJECT(win->gobj()), "drag_data_received", G_CALLBACK(sp_ui_drag_data_received), NULL); - gtk_widget_show(w); + g_signal_connect(G_OBJECT(win->gobj()), + "drag_motion", + G_CALLBACK(sp_ui_drag_motion), + NULL); + g_signal_connect(G_OBJECT(win->gobj()), + "drag_leave", + G_CALLBACK(sp_ui_drag_leave), + NULL); + win->show(); // needed because the first ACTIVATE_DESKTOP was sent when there was no window yet inkscape_reactivate_desktop(SP_DESKTOP_WIDGET(vw)->desktop); @@ -210,6 +287,7 @@ sp_ui_new_view() sp_create_window(dtw, TRUE); sp_namedview_window_from_document(static_cast(dtw->view)); + sp_namedview_update_layers_from_document(static_cast(dtw->view)); } /* TODO: not yet working */ @@ -234,7 +312,7 @@ sp_ui_new_view_preview() * \param widget unused */ void -sp_ui_close_view(GtkWidget *widget) +sp_ui_close_view(GtkWidget */*widget*/) { if (SP_ACTIVE_DESKTOP == NULL) { return; @@ -273,12 +351,6 @@ sp_ui_close_all(void) return TRUE; } -static gint -sp_ui_delete(GtkWidget *widget, GdkEvent *event, Inkscape::UI::View::View *view) -{ - return view->shutdown(); -} - /* * Some day when the right-click menus are ready to start working * smarter with the verbs, we'll need to change this NULL being @@ -287,19 +359,19 @@ sp_ui_delete(GtkWidget *widget, GdkEvent *event, Inkscape::UI::View::View *view) * investigate when they're called. */ static void -sp_ui_menu_activate(void *object, SPAction *action) +sp_ui_menu_activate(void */*object*/, SPAction *action) { sp_action_perform(action, NULL); } static void -sp_ui_menu_select_action(void *object, SPAction *action) +sp_ui_menu_select_action(void */*object*/, SPAction *action) { action->view->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, action->tip); } static void -sp_ui_menu_deselect_action(void *object, SPAction *action) +sp_ui_menu_deselect_action(void */*object*/, SPAction *action) { action->view->tipsMessageContext()->clear(); } @@ -329,7 +401,7 @@ sp_ui_menuitem_add_icon( GtkWidget *item, gchar *icon_name ) { GtkWidget *icon; - icon = sp_icon_new( GTK_ICON_SIZE_MENU, icon_name ); + icon = sp_icon_new( Inkscape::ICON_SIZE_MENU, icon_name ); gtk_widget_show(icon); gtk_image_menu_item_set_image((GtkImageMenuItem *) item, icon); } // end of sp_ui_menu_add_icon @@ -397,9 +469,10 @@ sp_key_name(guint keyval) else if (!strcmp(n, "Page_Down" )) return "PgDn"; else if (!strcmp(n, "grave" )) return "`"; else if (!strcmp(n, "numbersign" )) return "#"; - else if (!strcmp(n, "bar" )) return "|"; - else if (!strcmp(n, "slash" )) return "/"; - else if (!strcmp(n, "exclam" )) return "!"; + else if (!strcmp(n, "bar" )) return "|"; + else if (!strcmp(n, "slash" )) return "/"; + else if (!strcmp(n, "exclam" )) return "!"; + else if (!strcmp(n, "percent" )) return "%"; else return n; } @@ -561,7 +634,7 @@ checkitem_toggled(GtkCheckMenuItem *menuitem, gpointer user_data) Inkscape::UI::View::View *view = (Inkscape::UI::View::View *) g_object_get_data(G_OBJECT(menuitem), "view"); gchar const *pref_path; - if (reinterpret_cast(view)->is_fullscreen) + if (reinterpret_cast(view)->is_fullscreen()) pref_path = g_strconcat("fullscreen.", pref, NULL); else pref_path = g_strconcat("window.", pref, NULL); @@ -573,7 +646,7 @@ checkitem_toggled(GtkCheckMenuItem *menuitem, gpointer user_data) } static gboolean -checkitem_update(GtkWidget *widget, GdkEventExpose *event, gpointer user_data) +checkitem_update(GtkWidget *widget, GdkEventExpose */*event*/, gpointer user_data) { GtkCheckMenuItem *menuitem=GTK_CHECK_MENU_ITEM(widget); @@ -581,7 +654,7 @@ checkitem_update(GtkWidget *widget, GdkEventExpose *event, gpointer user_data) Inkscape::UI::View::View *view = (Inkscape::UI::View::View *) g_object_get_data(G_OBJECT(menuitem), "view"); gchar const *pref_path; - if (static_cast(view)->is_fullscreen) + if ((static_cast(view))->is_fullscreen()) pref_path = g_strconcat("fullscreen.", pref, NULL); else pref_path = g_strconcat("window.", pref, NULL); @@ -660,13 +733,13 @@ sp_ui_menu_append_check_item_from_verb(GtkMenu *menu, Inkscape::UI::View::View * } static void -sp_recent_open(GtkWidget *widget, gchar const *uri) +sp_recent_open(GtkWidget */*widget*/, gchar const *uri) { sp_file_open(uri, NULL); } static void -sp_file_new_from_template(GtkWidget *widget, gchar const *uri) +sp_file_new_from_template(GtkWidget */*widget*/, gchar const *uri) { sp_file_new(uri); } @@ -688,7 +761,7 @@ sp_menu_append_new_templates(GtkWidget *menu, Inkscape::UI::View::View *view) if (dir) { for (gchar const *file = g_dir_read_name(dir); file != NULL; file = g_dir_read_name(dir)) { - if (!g_str_has_suffix(file, ".svg")) + if (!g_str_has_suffix(file, ".svg") && !g_str_has_suffix(file, ".svgz")) continue; // skip non-svg files gchar *basename = g_path_get_basename(file); @@ -764,7 +837,7 @@ sp_ui_checkboxes_menus(GtkMenu *m, Inkscape::UI::View::View *view) // checkitem_toggled, checkitem_update, 0); sp_ui_menu_append_check_item_from_verb(m, view, _("Commands Bar"), _("Show or hide the Commands bar (under the menu)"), "commands", checkitem_toggled, checkitem_update, 0); - sp_ui_menu_append_check_item_from_verb(m, view, _("Tool Controls"), _("Show or hide the Tool Controls panel"), "toppanel", + sp_ui_menu_append_check_item_from_verb(m, view, _("Tool Controls Bar"), _("Show or hide the Tool Controls bar"), "toppanel", checkitem_toggled, checkitem_update, 0); sp_ui_menu_append_check_item_from_verb(m, view, _("_Toolbox"), _("Show or hide the main toolbox (on the left)"), "toolbox", checkitem_toggled, checkitem_update, 0); @@ -772,9 +845,9 @@ sp_ui_checkboxes_menus(GtkMenu *m, Inkscape::UI::View::View *view) checkitem_toggled, checkitem_update, Inkscape::Verb::get(SP_VERB_TOGGLE_RULERS)); sp_ui_menu_append_check_item_from_verb(m, view, NULL, NULL, "scrollbars", checkitem_toggled, checkitem_update, Inkscape::Verb::get(SP_VERB_TOGGLE_SCROLLBARS)); - sp_ui_menu_append_check_item_from_verb(m, view, _("_Statusbar"), _("Show or hide the statusbar (at the bottom of the window)"), "statusbar", + sp_ui_menu_append_check_item_from_verb(m, view, _("_Palette"), _("Show or hide the color palette"), "panels", checkitem_toggled, checkitem_update, 0); - sp_ui_menu_append_check_item_from_verb(m, view, _("_Panels"), _("Show or hide the panels"), "panels", + sp_ui_menu_append_check_item_from_verb(m, view, _("_Statusbar"), _("Show or hide the statusbar (at the bottom of the window)"), "statusbar", checkitem_toggled, checkitem_update, 0); } @@ -804,9 +877,6 @@ sp_ui_build_dyn_menus(Inkscape::XML::Node *menus, GtkWidget *menu, Inkscape::UI: menu_pntr != NULL; menu_pntr = menu_pntr->next()) { if (!strcmp(menu_pntr->name(), "submenu")) { - if (!strcmp(menu_pntr->attribute("name"), "Effects") && !prefs_get_int_attribute("extensions", "show-effects-menu", 0)) { - continue; - } GtkWidget *mitem = gtk_menu_item_new_with_mnemonic(_(menu_pntr->attribute("name"))); GtkWidget *submenu = gtk_menu_new(); sp_ui_build_dyn_menus(menu_pntr->firstChild(), submenu, view); @@ -877,9 +947,17 @@ sp_ui_main_menubar(Inkscape::UI::View::View *view) { GtkWidget *mbar = gtk_menu_bar_new(); +#ifdef GDK_WINDOWING_QUARTZ + ige_mac_menu_set_menu_bar(GTK_MENU_SHELL(mbar)); +#endif + sp_ui_build_dyn_menus(inkscape_get_menus(INKSCAPE), mbar, view); +#ifdef GDK_WINDOWING_QUARTZ + return NULL; +#else return mbar; +#endif } static void leave_group(GtkMenuItem *, SPDesktop *desktop) { @@ -888,7 +966,7 @@ static void leave_group(GtkMenuItem *, SPDesktop *desktop) { static void enter_group(GtkMenuItem *mi, SPDesktop *desktop) { desktop->setCurrentLayer(reinterpret_cast(g_object_get_data(G_OBJECT(mi), "group"))); - SP_DT_SELECTION(desktop)->clear(); + sp_desktop_selection(desktop)->clear(); } GtkWidget * @@ -935,7 +1013,8 @@ sp_ui_context_menu(Inkscape::UI::View::View *view, SPItem *item) } if (( group && group != dt->currentLayer() ) || - ( dt->currentLayer() != dt->currentRoot() ) ) { + ( dt->currentLayer() != dt->currentRoot() && SP_OBJECT_PARENT(dt->currentLayer()) != dt->currentRoot() ) ) { + /* Separator */ sp_ui_menu_append_item(GTK_MENU(m), NULL, NULL, NULL, NULL, NULL, NULL); } @@ -970,13 +1049,16 @@ sp_ui_drag_data_received(GtkWidget *widget, gint x, gint y, GtkSelectionData *data, guint info, - guint event_time, - gpointer user_data) + guint /*event_time*/, + gpointer /*user_data*/) { + SPDocument *doc = SP_ACTIVE_DOCUMENT; + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + switch (info) { - case APP_X_COLOR: +#if ENABLE_MAGIC_COLORS + case APP_X_INKY_COLOR: { - SPDesktop *desktop = SP_ACTIVE_DESKTOP; int destX = 0; int destY = 0; gtk_widget_translate_coordinates( widget, &(desktop->canvas->widget), x, y, &destX, &destY ); @@ -985,11 +1067,15 @@ sp_ui_drag_data_received(GtkWidget *widget, SPItem *item = desktop->item_at_point( where, true ); if ( item ) { - if ( data->length == 8 ) { + bool fillnotstroke = (drag_context->action != GDK_ACTION_MOVE); + + if ( data->length >= 8 ) { + cmsHPROFILE srgbProf = cmsCreate_sRGBProfile(); + gchar c[64] = {0}; // Careful about endian issues. guint16* dataVals = (guint16*)data->data; - sp_svg_write_color( c, 64, + sp_svg_write_color( c, sizeof(c), SP_RGBA32_U_COMPOSE( 0x0ff & (dataVals[0] >> 8), 0x0ff & (dataVals[1] >> 8), @@ -998,13 +1084,130 @@ sp_ui_drag_data_received(GtkWidget *widget, //0x0ff & (data->data[3] >> 8), )); SPCSSAttr *css = sp_repr_css_attr_new(); - sp_repr_css_set_property( css, (drag_context->action != GDK_ACTION_MOVE) ? "fill":"stroke", c ); + bool updatePerformed = false; + + if ( data->length > 14 ) { + int flags = dataVals[4]; + + // piggie-backed palette entry info + int index = dataVals[5]; + Glib::ustring palName; + for ( int i = 0; i < dataVals[6]; i++ ) { + palName += (gunichar)dataVals[7+i]; + } + + // Now hook in a magic tag of some sort. + if ( !palName.empty() && (flags & 1) ) { + gchar* str = g_strdup_printf("%d|", index); + palName.insert( 0, str ); + g_free(str); + str = 0; + + sp_object_setAttribute( SP_OBJECT(item), + fillnotstroke ? "inkscape:x-fill-tag":"inkscape:x-stroke-tag", + palName.c_str(), + false ); + item->updateRepr(); + + sp_repr_css_set_property( css, fillnotstroke ? "fill":"stroke", c ); + updatePerformed = true; + } + } + + if ( !updatePerformed ) { + sp_repr_css_set_property( css, fillnotstroke ? "fill":"stroke", c ); + } sp_desktop_apply_css_recursive( item, css, true ); item->updateRepr(); - SPDocument *doc = SP_ACTIVE_DOCUMENT; - sp_document_done( doc ); + sp_document_done( doc , SP_VERB_NONE, + _("Drop color")); + + if ( srgbProf ) { + cmsCloseProfile( srgbProf ); + } + } + } + } + break; +#endif // ENABLE_MAGIC_COLORS + + case APP_X_COLOR: + { + int destX = 0; + int destY = 0; + gtk_widget_translate_coordinates( widget, &(desktop->canvas->widget), x, y, &destX, &destY ); + NR::Point where( sp_canvas_window_to_world( desktop->canvas, NR::Point( destX, destY ) ) ); + NR::Point const button_dt(desktop->w2d(where)); + NR::Point const button_doc(desktop->dt2doc(button_dt)); + + if ( data->length == 8 ) { + gchar c[64] = {0}; + // Careful about endian issues. + guint16* dataVals = (guint16*)data->data; + sp_svg_write_color( c, 64, + SP_RGBA32_U_COMPOSE( + 0x0ff & (dataVals[0] >> 8), + 0x0ff & (dataVals[1] >> 8), + 0x0ff & (dataVals[2] >> 8), + 0xff // can't have transparency in the color itself + //0x0ff & (data->data[3] >> 8), + )); + + SPItem *item = desktop->item_at_point( where, true ); + + bool consumed = false; + if (desktop->event_context && desktop->event_context->get_drag()) { + consumed = desktop->event_context->get_drag()->dropColor(item, c, button_dt); + if (consumed) { + sp_document_done( doc , SP_VERB_NONE, _("Drop color on gradient")); + desktop->event_context->get_drag()->updateDraggers(); + } + } + + //if (!consumed && tools_active(desktop, TOOLS_TEXT)) { + // consumed = sp_text_context_drop_color(c, button_doc); + // if (consumed) { + // sp_document_done( doc , SP_VERB_NONE, _("Drop color on gradient stop")); + // } + //} + + if (!consumed && item) { + bool fillnotstroke = (drag_context->action != GDK_ACTION_MOVE); + if (fillnotstroke && + (SP_IS_SHAPE(item) || SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item))) { + Path *livarot_path = Path_for_item(item, true, true); + livarot_path->ConvertWithBackData(0.04); + + boost::optional position = get_nearest_position_on_Path(livarot_path, button_doc); + if (position) { + NR::Point nearest = get_point_on_Path(livarot_path, position->piece, position->t); + NR::Point delta = nearest - button_doc; + delta = desktop->d2w(delta); + double stroke_tolerance = + ( !SP_OBJECT_STYLE(item)->stroke.isNone() ? + desktop->current_zoom() * + SP_OBJECT_STYLE (item)->stroke_width.computed * + NR::expansion(sp_item_i2d_affine(item)) * 0.5 + : 0.0) + + prefs_get_int_attribute_limited("options.dragtolerance", "value", 0, 0, 100); + + if (NR::L2 (delta) < stroke_tolerance) { + fillnotstroke = false; + } + } + delete livarot_path; + } + + SPCSSAttr *css = sp_repr_css_attr_new(); + sp_repr_css_set_property( css, fillnotstroke ? "fill":"stroke", c ); + + sp_desktop_apply_css_recursive( item, css, true ); + item->updateRepr(); + + sp_document_done( doc , SP_VERB_NONE, + _("Drop color")); } } } @@ -1014,8 +1217,6 @@ sp_ui_drag_data_received(GtkWidget *widget, case SVG_XML_DATA: { gchar *svgdata = (gchar *)data->data; - SPDocument *doc = SP_ACTIVE_DOCUMENT; - Inkscape::XML::Document *rnewdoc = sp_repr_read_mem(svgdata, data->length, SP_SVG_NS_URI); if (rnewdoc == NULL) { @@ -1023,41 +1224,45 @@ sp_ui_drag_data_received(GtkWidget *widget, return; } - Inkscape::XML::Node *repr = sp_repr_document_root(rnewdoc); + Inkscape::XML::Node *repr = rnewdoc->root(); gchar const *style = repr->attribute("style"); - Inkscape::XML::Node *newgroup = sp_repr_new("svg:g"); + Inkscape::XML::Node *newgroup = rnewdoc->createElement("svg:g"); newgroup->setAttribute("style", style); + Inkscape::XML::Document * xml_doc = sp_document_repr_doc(doc); for (Inkscape::XML::Node *child = repr->firstChild(); child != NULL; child = child->next()) { - Inkscape::XML::Node *newchild = child->duplicate(); + Inkscape::XML::Node *newchild = child->duplicate(xml_doc); newgroup->appendChild(newchild); } Inkscape::GC::release(rnewdoc); - SPDesktop *desktop = SP_ACTIVE_DESKTOP; // Add it to the current layer // Greg's edits to add intelligent positioning of svg drops SPObject *new_obj = NULL; new_obj = desktop->currentLayer()->appendChildRepr(newgroup); - Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + Inkscape::Selection *selection = sp_desktop_selection(desktop); selection->set(SP_ITEM(new_obj)); // To move the imported object, we must temporarily set the "transform pattern with // object" option. { int const saved_pref = prefs_get_int_attribute("options.transform", "pattern", 1); prefs_set_int_attribute("options.transform", "pattern", 1); - sp_document_ensure_up_to_date(SP_DT_DOCUMENT(desktop)); - NR::Point m( desktop->point() - selection->bounds().midpoint() ); - sp_selection_move_relative(selection, m); + sp_document_ensure_up_to_date(sp_desktop_document(desktop)); + boost::optional sel_bbox = selection->bounds(); + if (sel_bbox) { + NR::Point m( desktop->point() - sel_bbox->midpoint() ); + sp_selection_move_relative(selection, m); + } prefs_set_int_attribute("options.transform", "pattern", saved_pref); } Inkscape::GC::release(newgroup); - sp_document_done(doc); + sp_document_done(doc, SP_VERB_NONE, + _("Drop SVG")); break; } @@ -1076,9 +1281,9 @@ sp_ui_drag_data_received(GtkWidget *widget, Base64OutputStream b64out(outs); b64out.setColumnWidth(0); - SPDocument *doc = SP_ACTIVE_DOCUMENT; + Inkscape::XML::Document *xml_doc = sp_document_repr_doc(doc); - Inkscape::XML::Node *newImage = sp_repr_new("svg:image"); + Inkscape::XML::Node *newImage = xml_doc->createElement("svg:image"); for ( int i = 0; i < data->length; i++ ) { b64out.put( data->data[i] ); @@ -1110,18 +1315,42 @@ sp_ui_drag_data_received(GtkWidget *widget, } } - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - // Add it to the current layer desktop->currentLayer()->appendChildRepr(newImage); Inkscape::GC::release(newImage); - sp_document_done( doc ); + sp_document_done( doc , SP_VERB_NONE, + _("Drop bitmap image")); break; } } } +#include "gradient-context.h" + +void sp_ui_drag_motion( GtkWidget */*widget*/, + GdkDragContext */*drag_context*/, + gint /*x*/, gint /*y*/, + GtkSelectionData */*data*/, + guint /*info*/, + guint /*event_time*/, + gpointer /*user_data*/) +{ +// SPDocument *doc = SP_ACTIVE_DOCUMENT; +// SPDesktop *desktop = SP_ACTIVE_DESKTOP; + + +// g_message("drag-n-drop motion (%4d, %4d) at %d", x, y, event_time); +} + +static void sp_ui_drag_leave( GtkWidget */*widget*/, + GdkDragContext */*drag_context*/, + guint /*event_time*/, + gpointer /*user_data*/ ) +{ +// g_message("drag-n-drop leave at %d", event_time); +} + static void sp_ui_import_files(gchar *buffer) { @@ -1134,7 +1363,7 @@ sp_ui_import_files(gchar *buffer) } static void -sp_ui_import_one_file_with_check(gpointer filename, gpointer unused) +sp_ui_import_one_file_with_check(gpointer filename, gpointer /*unused*/) { if (filename) { if (strlen((char const *)filename) > 2) @@ -1162,7 +1391,7 @@ sp_ui_error_dialog(gchar const *message) gchar *safeMsg = Inkscape::IO::sanitizeString(message); dlg = gtk_message_dialog_new(NULL, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, - GTK_BUTTONS_CLOSE, safeMsg); + GTK_BUTTONS_CLOSE, "%s", safeMsg); sp_transientize(dlg); gtk_window_set_resizable(GTK_WINDOW(dlg), FALSE); gtk_dialog_run(GTK_DIALOG(dlg)); @@ -1174,49 +1403,34 @@ bool sp_ui_overwrite_file(gchar const *filename) { bool return_value = FALSE; - GtkWidget *dialog; - GtkWidget *hbox; - GtkWidget *boxdata; - gchar *title; - gchar *text; if (Inkscape::IO::file_test(filename, G_FILE_TEST_EXISTS)) { - - title = g_strdup_printf(_("Overwrite %s"), filename); - dialog = gtk_dialog_new_with_buttons(title, - NULL, - (GtkDialogFlags)(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT), - GTK_STOCK_NO, - GTK_RESPONSE_NO, - GTK_STOCK_YES, - GTK_RESPONSE_YES, - NULL); - gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_YES); - - sp_transientize(dialog); - gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE); - - hbox = gtk_hbox_new(FALSE, 5); - boxdata = gtk_image_new_from_stock(GTK_STOCK_DIALOG_QUESTION, GTK_ICON_SIZE_DIALOG); - gtk_widget_show(boxdata); - gtk_box_pack_start(GTK_BOX(hbox), boxdata, TRUE, TRUE, 5); - text = g_strdup_printf(_("The file %s already exists. Do you want to overwrite that file with the current document?"), filename); - boxdata = gtk_label_new(text); - gtk_label_set_line_wrap(GTK_LABEL(boxdata), TRUE); - gtk_widget_show(boxdata); - gtk_box_pack_start(GTK_BOX(hbox), boxdata, FALSE, FALSE, 5); - gtk_widget_show(hbox); - gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, TRUE, TRUE, 5); - - if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_YES) { + Gtk::Window *window = SP_ACTIVE_DESKTOP->getToplevel(); + gchar* baseName = g_path_get_basename( filename ); + gchar* dirName = g_path_get_dirname( filename ); + GtkWidget* dialog = gtk_message_dialog_new_with_markup( window->gobj(), + (GtkDialogFlags)(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT), + GTK_MESSAGE_QUESTION, + GTK_BUTTONS_NONE, + _( "A file named \"%s\" already exists. Do you want to replace it?\n\n" + "The file already exists in \"%s\". Replacing it will overwrite its contents." ), + baseName, + dirName + ); + gtk_dialog_add_buttons( GTK_DIALOG(dialog), + GTK_STOCK_CANCEL, GTK_RESPONSE_NO, + _("Replace"), GTK_RESPONSE_YES, + NULL ); + gtk_dialog_set_default_response( GTK_DIALOG(dialog), GTK_RESPONSE_YES ); + + if ( gtk_dialog_run( GTK_DIALOG(dialog) ) == GTK_RESPONSE_YES ) { return_value = TRUE; } else { return_value = FALSE; } - gtk_widget_destroy(dialog); - g_free(title); - g_free(text); + g_free( baseName ); + g_free( dirName ); } else { return_value = TRUE; } @@ -1225,11 +1439,30 @@ sp_ui_overwrite_file(gchar const *filename) } static void -sp_ui_menu_item_set_sensitive(SPAction *action, unsigned int sensitive, void *data) +sp_ui_menu_item_set_sensitive(SPAction */*action*/, unsigned int sensitive, void *data) { return gtk_widget_set_sensitive(GTK_WIDGET(data), sensitive); } +static void +sp_ui_menu_item_set_name(SPAction */*action*/, Glib::ustring name, void *data) +{ + void *child = GTK_BIN (data)->child; + //child is either + //- a GtkHBox, whose first child is a label displaying name if the menu + //item has an accel key + //- a GtkLabel if the menu has no accel key + if (GTK_IS_LABEL(child)) { + gtk_label_set_markup_with_mnemonic(GTK_LABEL (child), name.c_str()); + } else if (GTK_IS_HBOX(child)) { + gtk_label_set_markup_with_mnemonic( + GTK_LABEL (gtk_container_get_children(GTK_CONTAINER (child))->data), + name.c_str()); + }//else sp_ui_menu_append_item_from_verb has been modified and can set + //a menu item in yet another way... +} + + /* Local Variables: mode:c++