diff --git a/src/interface.cpp b/src/interface.cpp
index 8379cd0e23c9e48aa9ea1fe7091f87a902e5355c..cf70720649c1ff5b8bdc8e983b56f722e0cc2927 100644 (file)
--- a/src/interface.cpp
+++ b/src/interface.cpp
#include "widgets/desktop-widget.h"
#include "sp-item-group.h"
#include "sp-text.h"
+#include "sp-gradient-fns.h"
+#include "sp-gradient.h"
#include "sp-flowtext.h"
#include "sp-namedview.h"
#include "ui/view/view.h"
#include "style.h"
#include "event-context.h"
#include "gradient-drag.h"
-#include "widgets/eek-color-def.h"
+#include "widgets/ege-paint-def.h"
// Include Mac OS X menu synchronization on native OSX build
#ifdef GDK_WINDOWING_QUARTZ
static GtkTargetEntry *completeDropTargets = 0;
static int completeDropTargetsCount = 0;
+static bool temporarily_block_actions = false;
#define ENTRIES_SIZE(n) sizeof(n)/sizeof(n[0])
static guint nui_drop_target_entries = ENTRIES_SIZE(ui_drop_target_entries);
gtk_widget_show(GTK_WIDGET(vw));
if (editable) {
- g_object_set_data(G_OBJECT(vw), "window", win);
+ g_object_set_data(G_OBJECT(vw), "window", win);
- SPDesktopWidget *desktop_widget = reinterpret_cast<SPDesktopWidget*>(vw);
- SPDesktop* desktop = desktop_widget->desktop;
+ SPDesktopWidget *desktop_widget = reinterpret_cast<SPDesktopWidget*>(vw);
+ SPDesktop* desktop = desktop_widget->desktop;
- desktop_widget->window = win;
+ 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));
+ 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();
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
gint prefs_geometry =
(2==prefs->getInt("/options/savewindowgeometry/value", 0));
if (prefs_geometry) {
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) {
+ if (w>0 && h>0) {
x = MIN(gdk_screen_width() - w, x);
y = MIN(gdk_screen_height() - h, y);
- }
- if (w>0 && h>0) {
desktop->setWindowSize(w, h);
}
// 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(Geom::Point(x, y));
- }
+ SPDesktop *active_desktop = SP_ACTIVE_DESKTOP;
+ if (active_desktop == desktop || active_desktop==NULL) {
+ desktop->setWindowPosition(Geom::Point(x, y));
}
}
if (maxed) {
void
sp_ui_close_view(GtkWidget */*widget*/)
{
- if (SP_ACTIVE_DESKTOP == NULL) {
+ SPDesktop *dt = SP_ACTIVE_DESKTOP;
+
+ if (dt == NULL) {
return;
}
- if ((SP_ACTIVE_DESKTOP)->shutdown()) {
- return;
+
+ if (dt->shutdown()) {
+ return; // Shutdown operation has been canceled, so do nothing
}
- SP_ACTIVE_DESKTOP->destroyWidget();
+
+ // Shutdown can proceed; use the stored reference to the desktop here instead of the current SP_ACTIVE_DESKTOP,
+ // because the user might have changed the focus in the meantime (see bug #381357 on Launchpad)
+ dt->destroyWidget();
}
/* Iterate through all the windows, destroying each in the order they
become active */
while (SP_ACTIVE_DESKTOP) {
- if ((SP_ACTIVE_DESKTOP)->shutdown()) {
- /* The user cancelled the operation, so end doing the close */
+ SPDesktop *dt = SP_ACTIVE_DESKTOP;
+ if (dt->shutdown()) {
+ /* The user canceled the operation, so end doing the close */
return FALSE;
}
- SP_ACTIVE_DESKTOP->destroyWidget();
+ // Shutdown can proceed; use the stored reference to the desktop here instead of the current SP_ACTIVE_DESKTOP,
+ // because the user might have changed the focus in the meantime (see bug #381357 on Launchpad)
+ dt->destroyWidget();
}
return TRUE;
static void
sp_ui_menu_activate(void */*object*/, SPAction *action)
{
- sp_action_perform(action, NULL);
+ if (!temporarily_block_actions) {
+ sp_action_perform(action, NULL);
+ }
}
static void
@@ -608,9 +618,8 @@ sp_ui_menu_append_item_from_verb(GtkMenu *menu, Inkscape::Verb *verb, Inkscape::
sp_ui_menuitem_add_icon(item, action->image);
}
gtk_widget_set_events(item, GDK_KEY_PRESS_MASK);
- g_signal_connect( G_OBJECT(item), "activate",
- G_CALLBACK(sp_ui_menu_activate), action );
-
+ g_object_set_data(G_OBJECT(item), "view", (gpointer) view);
+ g_signal_connect( G_OBJECT(item), "activate", G_CALLBACK(sp_ui_menu_activate), action );
g_signal_connect( G_OBJECT(item), "select", G_CALLBACK(sp_ui_menu_select_action), action );
g_signal_connect( G_OBJECT(item), "deselect", G_CALLBACK(sp_ui_menu_deselect_action), action );
}
@@ -673,6 +682,44 @@ checkitem_update(GtkWidget *widget, GdkEventExpose */*event*/, gpointer user_dat
return FALSE;
}
+/**
+ * \brief Callback function to update the status of the radio buttons in the View -> Display mode menu (Normal, No Filters, Outline)
+ */
+
+static gboolean
+update_view_menu(GtkWidget *widget, GdkEventExpose */*event*/, gpointer user_data)
+{
+ SPAction *action = (SPAction *) user_data;
+ g_assert(action->id != NULL);
+
+ Inkscape::UI::View::View *view = (Inkscape::UI::View::View *) g_object_get_data(G_OBJECT(widget), "view");
+ SPDesktop *dt = static_cast<SPDesktop*>(view);
+ Inkscape::RenderMode mode = dt->getMode();
+
+ bool new_state = false;
+ if (!strcmp(action->id, "ViewModeNormal")) {
+ new_state = mode == Inkscape::RENDERMODE_NORMAL;
+ } else if (!strcmp(action->id, "ViewModeNoFilters")) {
+ new_state = mode == Inkscape::RENDERMODE_NO_FILTERS;
+ } else if (!strcmp(action->id, "ViewModeOutline")) {
+ new_state = mode == Inkscape::RENDERMODE_OUTLINE;
+ } else {
+ g_warning("update_view_menu does not handle this verb");
+ }
+
+ if (new_state) { //only one of the radio buttons has to be activated; the others will automatically be deactivated
+ if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (widget))) {
+ // When the GtkMenuItem version of the "activate" signal has been emitted by a GtkRadioMenuItem, there is a second
+ // emission as the most recently active item is toggled to inactive. This is dealt with before the original signal is handled.
+ // This emission however should not invoke any actions, hence we block it here:
+ temporarily_block_actions = true;
+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (widget), TRUE);
+ temporarily_block_actions = false;
+ }
+ }
+
+ return FALSE;
+}
void
sp_ui_menu_append_check_item_from_verb(GtkMenu *menu, Inkscape::UI::View::View *view, gchar const *label, gchar const *tip, gchar const *pref,
// 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, _("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",
a couple of submenus, it is unlikely this will go more than two or
three times.
- In the case of an unreconginzed verb, a menu item is made to identify
+ In the case of an unrecognized verb, a menu item is made to identify
the verb that is missing, and display that. The menu item is also made
insensitive.
*/
@@ -896,6 +943,10 @@ sp_ui_build_dyn_menus(Inkscape::XML::Node *menus, GtkWidget *menu, Inkscape::UI:
if (menu_pntr->attribute("default") != NULL) {
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE);
}
+ if (verb->get_code() != SP_VERB_NONE) {
+ SPAction *action = verb->get_action(view);
+ g_signal_connect( G_OBJECT(item), "expose_event", (GCallback) update_view_menu, (void *) action);
+ }
} else {
sp_ui_menu_append_item_from_verb(GTK_MENU(menu), verb, view);
group = NULL;
GtkWidget *mbar = gtk_menu_bar_new();
#ifdef GDK_WINDOWING_QUARTZ
- ige_mac_menu_set_menu_bar(GTK_MENU_SHELL(mbar));
+ 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;
+ return NULL;
#else
return mbar;
#endif
bool worked = false;
Glib::ustring colorspec;
if ( data->format == 8 ) {
- eek::ColorDef color;
+ ege::PaintDef color;
worked = color.fromMIMEData("application/x-oswb-color",
reinterpret_cast<char*>(data->data),
data->length,
data->format);
if ( worked ) {
- if ( color.getType() == eek::ColorDef::CLEAR ) {
+ if ( color.getType() == ege::PaintDef::CLEAR ) {
colorspec = ""; // TODO check if this is sufficient
- } else if ( color.getType() == eek::ColorDef::NONE ) {
+ } else if ( color.getType() == ege::PaintDef::NONE ) {
colorspec = "none";
- } else {
- gchar* tmp = g_strdup_printf("#%02x%02x%02x", color.getR(), color.getG(), color.getB());
- colorspec = tmp;
- g_free(tmp);
+ } else {
+ unsigned int r = color.getR();
+ unsigned int g = color.getG();
+ unsigned int b = color.getB();
+
+ SPGradient* matches = 0;
+ const GSList *gradients = sp_document_get_resource_list(doc, "gradient");
+ for (const GSList *item = gradients; item; item = item->next) {
+ SPGradient* grad = SP_GRADIENT(item->data);
+ if ( color.descr == grad->id ) {
+ if ( grad->has_stops ) {
+ matches = grad;
+ break;
+ }
+ }
+ }
+ if (matches) {
+ colorspec = "url(#";
+ colorspec += matches->id;
+ colorspec += ")";
+ } else {
+ gchar* tmp = g_strdup_printf("#%02x%02x%02x", r, g, b);
+ colorspec = tmp;
+ g_free(tmp);
+ }
}
}
}
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.
+
+ // move to mouse pointer
{
- 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));
Geom::OptRect sel_bbox = selection->bounds();
if (sel_bbox) {
Geom::Point m( desktop->point() - sel_bbox->midpoint() );
- sp_selection_move_relative(selection, m);
+ sp_selection_move_relative(selection, m, false);
}
- prefs->setBool("/options/transform/pattern", saved_pref);
}
Inkscape::GC::release(newgroup);
Inkscape::XML::Document *xml_doc = sp_document_repr_doc(doc);
Inkscape::XML::Node *newImage = xml_doc->createElement("svg:image");
gchar *atom_name = gdk_atom_name(data->type);
-
+
// this formula taken from Glib docs
guint needed_size = data->length * 4 / 3 + data->length * 4 / (3 * 72) + 7;
needed_size += 5 + 8 + strlen(atom_name); // 5 bytes for data:, 8 for ;base64,
-
+
gchar *buffer = (gchar *) g_malloc(needed_size), *buf_work = buffer;
buf_work += g_sprintf(buffer, "data:%s;base64,", atom_name);
-
+
gint state = 0, save = 0;
g_base64_encode_step(data->data, data->length, TRUE, buf_work, &state, &save);
g_base64_encode_close(TRUE, buf_work, &state, &save);