diff --git a/src/interface.cpp b/src/interface.cpp
index ea08f170c65b0cf4c14a69e53a6f3231faf0f927..96c8c10ba41a700fa75c1e5577971466233d0aab 100644 (file)
--- a/src/interface.cpp
+++ b/src/interface.cpp
#define __SP_INTERFACE_C__
-/**
- * Main UI stuff
- *
- * Authors:
+/** @file
+ * @brief Main UI stuff
+ */
+/* Authors:
* Lauris Kaplinski <lauris@kaplinski.com>
* Frank Felfe <innerspace@iname.com>
* bulia byak <buliabyak@users.sf.net>
#endif
#include <gtk/gtk.h>
+#include <glib.h>
#include "inkscape-private.h"
#include "extension/effect.h"
#include "widgets/icon.h"
-#include "prefs-utils.h"
+#include "preferences.h"
#include "path-prefix.h"
#include "shortcuts.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"
#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);
-static void sp_ui_state_event(GtkWidget *widget, GdkEventWindowState *event, SPDesktop*desktop);
-
-
/* Drag and Drop */
typedef enum {
URI_LIST,
} 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},
+ {(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
- {"application/x-inkscape-color", 0, APP_X_INKY_COLOR},
+ {(gchar *)"application/x-inkscape-color", 0, APP_X_INKY_COLOR},
#endif // ENABLE_MAGIC_COLORS
- {"application/x-color", 0, APP_X_COLOR}
+ {(gchar *)"application/x-color", 0, APP_X_COLOR }
};
static GtkTargetEntry *completeDropTargets = 0;
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,
+static void sp_ui_menu_item_set_name(SPAction *action,
Glib::ustring name,
void *data);
+static void sp_recent_open(GtkRecentChooser *, gpointer);
SPActionEventVector menu_item_event_vector = {
{NULL},
g_return_if_fail(vw != NULL);
g_return_if_fail(SP_IS_VIEW_WIDGET(vw));
- GtkWidget *win = sp_window_new("", TRUE);
+ Gtk::Window *win = Inkscape::UI::window_new("", TRUE);
- if (editable) {
- g_object_set_data(G_OBJECT(vw), "window", win);
- reinterpret_cast<SPDesktopWidget*>(vw)->window =
- static_cast<GtkWindow*>((void*)win);
- }
+ gtk_container_add(GTK_CONTAINER(win->gobj()), GTK_WIDGET(vw));
+ gtk_widget_show(GTK_WIDGET(vw));
if (editable) {
- SPDesktop* desktop = SP_DESKTOP_WIDGET(vw)->desktop;
+ g_object_set_data(G_OBJECT(vw), "window", win);
- /* fixme: doesn't allow making window any smaller than this */
- gtk_window_set_default_size((GtkWindow *) win, 640, 480);
- g_object_set_data(G_OBJECT(win), "desktop", desktop);
- g_object_set_data(G_OBJECT(win), "desktopwidget", vw);
- g_signal_connect(G_OBJECT(win), "delete_event", G_CALLBACK(sp_ui_delete), vw->view);
+ SPDesktopWidget *desktop_widget = reinterpret_cast<SPDesktopWidget*>(vw);
+ SPDesktop* desktop = desktop_widget->desktop;
- g_signal_connect(G_OBJECT(win), "window_state_event", G_CALLBACK(sp_ui_state_event), static_cast<SPDesktop*>(vw->view));
- g_signal_connect(G_OBJECT(win), "focus_in_event", G_CALLBACK(sp_desktop_widget_set_focus), vw);
+ desktop_widget->window = win;
- gint prefs_geometry =
- (2==prefs_get_int_attribute("options.savewindowgeometry", "value", 0));
+ 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));
+
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ gint prefs_geometry =
+ (2==prefs->getInt("/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);
+ gint pw = prefs->getInt("/desktop/geometry/width", -1);
+ gint ph = prefs->getInt("/desktop/geometry/height", -1);
+ gint px = prefs->getInt("/desktop/geometry/x", -1);
+ gint py = prefs->getInt("/desktop/geometry/y", -1);
+ gint full = prefs->getBool("/desktop/geometry/fullscreen");
+ gint maxed = prefs->getBool("/desktop/geometry/maximized");
if (pw>0 && ph>0) {
gint w = MIN(gdk_screen_width(), pw);
gint h = MIN(gdk_screen_height(), ph);
if (x>0 && y>0) {
SPDesktop *active_desktop = SP_ACTIVE_DESKTOP;
if (active_desktop == desktop || active_desktop==NULL) {
- desktop->setWindowPosition(NR::Point(x, y));
+ desktop->setWindowPosition(Geom::Point(x, y));
}
}
}
if (maxed) {
- gtk_window_maximize(GTK_WINDOW(win));
+ win->maximize();
}
if (full) {
- gtk_window_fullscreen(GTK_WINDOW(win));
+ win->fullscreen();
}
}
} else {
- gtk_window_set_policy(GTK_WINDOW(win), TRUE, TRUE, TRUE);
+ gtk_window_set_policy(GTK_WINDOW(win->gobj()), TRUE, TRUE, TRUE);
}
- gtk_container_add(GTK_CONTAINER(win), GTK_WIDGET(vw));
- gtk_widget_show(GTK_WIDGET(vw));
-
if ( completeDropTargets == 0 || completeDropTargetsCount == 0 )
{
std::vector<gchar*> types;
}
}
- gtk_drag_dest_set(win,
+ 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(win),
+
+
+ g_signal_connect(G_OBJECT(win->gobj()),
"drag_data_received",
G_CALLBACK(sp_ui_drag_data_received),
NULL);
- gtk_widget_show(win);
+ 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);
* \param widget unused
*/
void
-sp_ui_close_view(GtkWidget *widget)
+sp_ui_close_view(GtkWidget */*widget*/)
{
if (SP_ACTIVE_DESKTOP == NULL) {
return;
return TRUE;
}
-static gint
-sp_ui_delete(GtkWidget *widget, GdkEvent *event, Inkscape::UI::View::View *view)
-{
- return view->shutdown();
-}
-
-/**
- * sp_ui_state_event
- *
- * Called when the window changes its maximize/fullscreen/iconify/pinned state.
- * Since GTK doesn't have a way to query this state information directly, we
- * record it for the desktop here, and also possibly trigger a layout.
- */
-static void
-sp_ui_state_event(GtkWidget *widget, GdkEventWindowState *event, SPDesktop* desktop)
-{
- // Record the desktop window's state
- desktop->window_state = event->new_window_state;
-
- // Layout may differ depending on full-screen mode or not
- GdkWindowState changed = event->changed_mask;
- if (changed & (GDK_WINDOW_STATE_FULLSCREEN|GDK_WINDOW_STATE_MAXIMIZED)) {
- desktop->layoutWidget();
- }
-/*
- // debug info
- g_message("State event desktop=0x%p", desktop);
- GdkWindowState state = event->new_window_state;
- GdkWindowState changed = event->changed_mask;
- if (changed & GDK_WINDOW_STATE_WITHDRAWN) {
- g_message("-- WIDTHDRAWN = %d", 0!=(state&GDK_WINDOW_STATE_WITHDRAWN));
- }
- if (changed & GDK_WINDOW_STATE_ICONIFIED) {
- g_message("-- ICONIFIED = %d", 0!=(state&GDK_WINDOW_STATE_ICONIFIED));
- }
- if (changed & GDK_WINDOW_STATE_MAXIMIZED) {
- g_message("-- MAXIMIZED = %d", 0!=(state&GDK_WINDOW_STATE_MAXIMIZED));
- }
- if (changed & GDK_WINDOW_STATE_STICKY) {
- g_message("-- STICKY = %d", 0!=(state&GDK_WINDOW_STATE_STICKY));
- }
- if (changed & GDK_WINDOW_STATE_FULLSCREEN) {
- g_message("-- FULLSCREEN = %d", 0!=(state&GDK_WINDOW_STATE_FULLSCREEN));
- }
- if (changed & GDK_WINDOW_STATE_ABOVE) {
- g_message("-- ABOVE = %d", 0!=(state&GDK_WINDOW_STATE_ABOVE));
- }
- if (changed & GDK_WINDOW_STATE_BELOW) {
- g_message("-- BELOW = %d", 0!=(state&GDK_WINDOW_STATE_BELOW));
- }
-*/
-}
-
/*
* Some day when the right-click menus are ready to start working
* smarter with the verbs, we'll need to change this NULL being
@@ -390,19 +362,19 @@ sp_ui_state_event(GtkWidget *widget, GdkEventWindowState *event, SPDesktop* desk
* 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();
}
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;
}
gchar const *pref = (gchar const *) 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<SPDesktop*>(view)->is_fullscreen())
- pref_path = g_strconcat("fullscreen.", pref, NULL);
- else
- pref_path = g_strconcat("window.", pref, NULL);
+ Glib::ustring pref_path;
+ if (reinterpret_cast<SPDesktop*>(view)->is_focusMode()) {
+ pref_path = "/focus/";
+ } else if (reinterpret_cast<SPDesktop*>(view)->is_fullscreen()) {
+ pref_path = "/fullscreen/";
+ } else {
+ pref_path = "/window/";
+ }
+ pref_path += pref;
+ pref_path += "/state";
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
gboolean checked = gtk_check_menu_item_get_active(menuitem);
- prefs_set_int_attribute(pref_path, "state", checked);
+ prefs->setBool(pref_path, checked);
reinterpret_cast<SPDesktop*>(view)->layoutWidget();
}
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);
gchar const *pref = (gchar const *) 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<SPDesktop*>(view))->is_fullscreen())
- pref_path = g_strconcat("fullscreen.", pref, NULL);
- else
- pref_path = g_strconcat("window.", pref, NULL);
+ Glib::ustring pref_path;
+ if ((static_cast<SPDesktop*>(view))->is_fullscreen()) {
+ pref_path = "/fullscreen/";
+ } else {
+ pref_path = "/window/";
+ }
+ pref_path += pref;
- gint ison = prefs_get_int_attribute_limited(pref_path, "state", 1, 0, 1);
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ bool ison = prefs->getBool(pref_path + "/state", true);
g_signal_handlers_block_by_func(G_OBJECT(menuitem), (gpointer)(GCallback)checkitem_toggled, user_data);
gtk_check_menu_item_set_active(menuitem, ison);
@@ -763,13 +745,20 @@ 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(GtkRecentChooser *recent_menu, gpointer /*user_data*/)
{
- sp_file_open(uri, NULL);
+ // dealing with the bizarre filename convention in Inkscape for now
+ gchar *uri = gtk_recent_chooser_get_current_uri(GTK_RECENT_CHOOSER(recent_menu));
+ gchar *local_fn = g_filename_from_uri(uri, NULL, NULL);
+ gchar *utf8_fn = g_filename_to_utf8(local_fn, -1, NULL, NULL, NULL);
+ sp_file_open(utf8_fn, NULL);
+ g_free(utf8_fn);
+ g_free(local_fn);
+ g_free(uri);
}
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);
}
}
}
-void
-sp_menu_append_recent_documents(GtkWidget *menu, Inkscape::UI::View::View* /* view */)
-{
- gchar const **recent = prefs_get_recent_files();
- if (recent) {
- int i;
-
- for (i = 0; recent[i] != NULL; i += 2) {
- gchar const *uri = recent[i];
- gchar const *name = recent[i + 1];
-
- GtkWidget *item = gtk_menu_item_new_with_label(name);
- gtk_widget_show(item);
- g_signal_connect(G_OBJECT(item),
- "activate",
- G_CALLBACK(sp_recent_open),
- (gpointer)uri);
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
- }
-
- g_free(recent);
- } else {
- GtkWidget *item = gtk_menu_item_new_with_label(_("None"));
- gtk_widget_show(item);
- gtk_widget_set_sensitive(item, FALSE);
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
- }
-}
-
void
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, _("Snap controls Bar"), _("Show or hide the snapping controls"), "snaptoolbox",
+ checkitem_toggled, checkitem_update, 0);
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);
}
+/** @brief Observer that updates the recent list's max document count */
+class MaxRecentObserver : public Inkscape::Preferences::Observer {
+public:
+ MaxRecentObserver(GtkWidget *recent_menu) :
+ Observer("/options/maxrecentdocuments/value"),
+ _rm(recent_menu)
+ {
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ prefs->addObserver(*this);
+ }
+ virtual void notify(Inkscape::Preferences::Entry const &e) {
+ gtk_recent_chooser_set_limit(GTK_RECENT_CHOOSER(_rm), e.getInt());
+ // hack: the recent menu doesn't repopulate after changing the limit, so we force it
+ g_signal_emit_by_name((gpointer) gtk_recent_manager_get_default(), "changed");
+ }
+private:
+ GtkWidget *_rm;
+};
+
/** \brief This function turns XML into a menu
\param menus This is the XML that defines the menu
\param menu Menu to be added to
@@ -955,7 +936,27 @@ sp_ui_build_dyn_menus(Inkscape::XML::Node *menus, GtkWidget *menu, Inkscape::UI:
continue;
}
if (!strcmp(menu_pntr->name(), "recent-file-list")) {
- sp_menu_append_recent_documents(menu, view);
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+
+ // create recent files menu
+ int max_recent = prefs->getInt("/options/maxrecentdocuments/value");
+ GtkWidget *recent_menu = gtk_recent_chooser_menu_new_for_manager(gtk_recent_manager_get_default());
+ gtk_recent_chooser_set_limit(GTK_RECENT_CHOOSER(recent_menu), max_recent);
+ // sort most recently used documents first to preserve previous behavior
+ gtk_recent_chooser_set_sort_type(GTK_RECENT_CHOOSER(recent_menu), GTK_RECENT_SORT_MRU);
+ g_signal_connect(G_OBJECT(recent_menu), "item-activated", G_CALLBACK(sp_recent_open), (gpointer) NULL);
+
+ // add filter to only open files added by Inkscape
+ GtkRecentFilter *inkscape_only_filter = gtk_recent_filter_new();
+ gtk_recent_filter_add_application(inkscape_only_filter, g_get_prgname());
+ gtk_recent_chooser_add_filter(GTK_RECENT_CHOOSER(recent_menu), inkscape_only_filter);
+
+ GtkWidget *recent_item = gtk_menu_item_new_with_mnemonic(_("Open _Recent"));
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(recent_item), recent_menu);
+
+ gtk_menu_append(GTK_MENU(menu), GTK_WIDGET(recent_item));
+ // this will just sit and update the list's item count
+ static MaxRecentObserver *mro = new MaxRecentObserver(recent_menu);
continue;
}
if (!strcmp(menu_pntr->name(), "objects-checkboxes")) {
{
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) {
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;
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 ) ) );
+ Geom::Point where( sp_canvas_window_to_world( desktop->canvas, Geom::Point( destX, destY ) ) );
SPItem *item = desktop->item_at_point( where, true );
if ( item )
{
+ 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),
str = 0;
sp_object_setAttribute( SP_OBJECT(item),
- (drag_context->action != GDK_ACTION_MOVE) ? "inkscape:x-fill-tag":"inkscape:x-stroke-tag",
+ fillnotstroke ? "inkscape:x-fill-tag":"inkscape:x-stroke-tag",
palName.c_str(),
false );
item->updateRepr();
- sp_repr_css_set_property( css, (drag_context->action != GDK_ACTION_MOVE) ? "fill":"stroke", c );
+ sp_repr_css_set_property( css, fillnotstroke ? "fill":"stroke", c );
updatePerformed = true;
}
}
if ( !updatePerformed ) {
- sp_repr_css_set_property( css, (drag_context->action != GDK_ACTION_MOVE) ? "fill":"stroke", c );
+ 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,
+ sp_document_done( doc , SP_VERB_NONE,
_("Drop color"));
if ( srgbProf ) {
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 ) ) );
+ Geom::Point where( sp_canvas_window_to_world( desktop->canvas, Geom::Point( destX, destY ) ) );
+ Geom::Point const button_dt(desktop->w2d(where));
+ Geom::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<Path::cut_position> position = get_nearest_position_on_Path(livarot_path, button_doc);
+ if (position) {
+ Geom::Point nearest = get_point_on_Path(livarot_path, position->piece, position->t);
+ Geom::Point delta = nearest - button_doc;
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ delta = desktop->d2w(delta);
+ double stroke_tolerance =
+ ( !SP_OBJECT_STYLE(item)->stroke.isNone() ?
+ desktop->current_zoom() *
+ SP_OBJECT_STYLE (item)->stroke_width.computed *
+ to_2geom(sp_item_i2d_affine(item)).descrim() * 0.5
+ : 0.0)
+ + prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100);
+
+ if (Geom::L2 (delta) < stroke_tolerance) {
+ fillnotstroke = false;
+ }
+ }
+ delete livarot_path;
+ }
- SPItem *item = desktop->item_at_point( where, true );
- if ( item )
- {
- 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),
- ));
SPCSSAttr *css = sp_repr_css_attr_new();
- sp_repr_css_set_property( css, (drag_context->action != GDK_ACTION_MOVE) ? "fill":"stroke", c );
+ 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,
+ sp_document_done( doc , SP_VERB_NONE,
_("Drop color"));
}
}
// 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);
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ bool const saved_pref = prefs->getBool("/options/transform/pattern", true);
+ prefs->setBool("/options/transform/pattern", true);
sp_document_ensure_up_to_date(sp_desktop_document(desktop));
- NR::Maybe<NR::Rect> sel_bbox = selection->bounds();
+ Geom::OptRect sel_bbox = selection->bounds();
if (sel_bbox) {
- NR::Point m( desktop->point() - sel_bbox->midpoint() );
+ Geom::Point m( desktop->point() - sel_bbox->midpoint() );
sp_selection_move_relative(selection, m);
}
- prefs_set_int_attribute("options.transform", "pattern", saved_pref);
+ prefs->setBool("/options/transform/pattern", saved_pref);
}
Inkscape::GC::release(newgroup);
- sp_document_done(doc, SP_VERB_NONE,
+ sp_document_done(doc, SP_VERB_NONE,
_("Drop SVG"));
break;
}
desktop->currentLayer()->appendChildRepr(newImage);
Inkscape::GC::release(newImage);
- sp_document_done( doc , SP_VERB_NONE,
+ 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)
{
}
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)
bool return_value = FALSE;
if (Inkscape::IO::file_test(filename, G_FILE_TEST_EXISTS)) {
- GtkWidget* ancestor = 0;
- SPDesktop *desktop = SP_ACTIVE_DESKTOP;
- if ( desktop ) {
- desktop->getToplevel( ancestor );
- }
- GtkWindow *window = GTK_WIDGET_TOPLEVEL(ancestor) ? GTK_WINDOW( ancestor ) : 0;
+ 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,
+ 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,
}
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)
+sp_ui_menu_item_set_name(SPAction */*action*/, Glib::ustring name, void *data)
{
- gtk_label_set_markup_with_mnemonic(
- GTK_LABEL (gtk_container_get_children(GTK_CONTAINER (GTK_BIN (data)->child))->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...
}