index 9e9686e77763d36ce92d10c1428563c7bd63bcec..8cdf0a07fcee4869fb4a1fe4cddb09f19670a4cc 100644 (file)
--- a/src/widgets/toolbox.cpp
+++ b/src/widgets/toolbox.cpp
# include "config.h"
#endif
+#include <cstring>
+#include <string>
+
#include <gtkmm.h>
#include <gtk/gtk.h>
#include <iostream>
#include "widgets/spw-utilities.h"
#include "widgets/spinbutton-events.h"
#include "dialogs/text-edit.h"
+#include "dialogs/dialog-events.h"
#include "ui/widget/style-swatch.h"
#include "document-private.h"
#include "desktop-style.h"
#include "../libnrtype/font-lister.h"
+#include "../libnrtype/font-instance.h"
#include "../connection-pool.h"
#include "../prefs-utils.h"
#include "../inkscape-stock.h"
#include "ege-select-one-action.h"
#include "helper/unit-tracker.h"
+#include "svg/css-ostringstream.h"
+
using Inkscape::UnitTracker;
typedef void (*SetupFunction)(GtkWidget *toolbox, SPDesktop *desktop);
" </toolbar>"
" <toolbar name='3DBoxToolbar'>"
- " <toolitem action='3DBoxPosAngleXAction' />"
- " <toolitem action='3DBoxVPXAction' />"
- " <separator />"
- " <toolitem action='3DBoxPosAngleYAction' />"
- " <toolitem action='3DBoxVPYAction' />"
+ " <toolitem action='3DBoxAngleXAction' />"
+ " <toolitem action='3DBoxVPXStateAction' />"
" <separator />"
- " <toolitem action='3DBoxPosAngleZAction' />"
- " <toolitem action='3DBoxVPZAction' />"
+ " <toolitem action='3DBoxAngleYAction' />"
+ " <toolitem action='3DBoxVPYStateAction' />"
" <separator />"
+ " <toolitem action='3DBoxAngleZAction' />"
+ " <toolitem action='3DBoxVPZStateAction' />"
" </toolbar>"
" <toolbar name='SpiralToolbar'>"
@@ -501,7 +507,7 @@ static GtkAction* create_action_for_verb( Inkscape::Verb* verb, Inkscape::UI::Vi
GtkAction* act = 0;
SPAction* targetAction = verb->get_action(view);
- InkAction* inky = ink_action_new( verb->get_id(), verb->get_name(), verb->get_tip(), verb->get_image(), size );
+ InkAction* inky = ink_action_new( verb->get_id(), _(verb->get_name()), verb->get_tip(), verb->get_image(), size );
act = GTK_ACTION(inky);
gtk_action_set_sensitive( act, targetAction->sensitive );
{
GtkWidget *tb = gtk_vbox_new(FALSE, 0);
- GtkWidget *tb_s = gtk_vbox_new(FALSE, 0);
- GtkWidget *tb_e = gtk_vbox_new(FALSE, 0);
gtk_box_set_spacing(GTK_BOX(tb), AUX_SPACING);
- gtk_box_pack_start(GTK_BOX(tb), GTK_WIDGET(tb_s), FALSE, FALSE, 0);
- gtk_box_pack_end(GTK_BOX(tb), GTK_WIDGET(tb_e), FALSE, FALSE, 0);
g_object_set_data(G_OBJECT(tb), "desktop", NULL);
- g_object_set_data(G_OBJECT(tb), "top_spacer", tb_s);
gtk_widget_set_sensitive(tb, FALSE);
{
GtkWidget *tb = gtk_vbox_new(FALSE, 0);
- GtkWidget *tb_s = gtk_vbox_new(FALSE, 0);
- GtkWidget *tb_e = gtk_vbox_new(FALSE, 0);
gtk_box_set_spacing(GTK_BOX(tb), AUX_SPACING);
- gtk_box_pack_start(GTK_BOX(tb), GTK_WIDGET(tb_s), FALSE, FALSE, 0);
- gtk_box_pack_end(GTK_BOX(tb), GTK_WIDGET(tb_e), FALSE, FALSE, 0);
g_object_set_data(G_OBJECT(tb), "desktop", NULL);
gtk_widget_set_sensitive(tb, FALSE);
}
gtk_widget_show(toolbox);
- // need to show the spacer, or the padding will be off
- GtkWidget *spacer = GTK_WIDGET(g_object_get_data(G_OBJECT(toolbox), "top_spacer"));
- gtk_widget_show(spacer);
-
gtk_widget_show_all(shown_toolbox);
}
@@ -1725,6 +1718,9 @@ static void star_tb_event_attr_changed(Inkscape::XML::Node *repr, gchar const *n
GtkAdjustment *adj = 0;
+ gchar const *flatsidedstr = prefs_get_string_attribute( "tools.shapes.star", "isflatsided" );
+ bool isFlatSided = flatsidedstr ? (strcmp(flatsidedstr, "false") != 0) : true;
+
if (!strcmp(name, "inkscape:randomized")) {
adj = GTK_ADJUSTMENT( gtk_object_get_data(GTK_OBJECT(tbl), "randomized") );
gtk_adjustment_set_value(adj, sp_repr_get_double_attribute(repr, "inkscape:randomized", 0.0));
@@ -1742,7 +1738,7 @@ static void star_tb_event_attr_changed(Inkscape::XML::Node *repr, gchar const *n
ege_select_one_action_set_active( flat_action, 0 );
gtk_action_set_sensitive( prop_action, FALSE );
}
- } else if (!strcmp(name, "sodipodi:r1") || !strcmp(name, "sodipodi:r2")) {
+ } else if ((!strcmp(name, "sodipodi:r1") || !strcmp(name, "sodipodi:r2")) && (!isFlatSided) ) {
adj = (GtkAdjustment*)gtk_object_get_data(GTK_OBJECT(tbl), "proportion");
gdouble r1 = sp_repr_get_double_attribute(repr, "sodipodi:r1", 1.0);
gdouble r2 = sp_repr_get_double_attribute(repr, "sodipodi:r2", 1.0);
@@ -1873,7 +1869,6 @@ static void sp_star_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions
}
{
- //EgeAdjustmentAction* calligraphy_angle = 0;
EgeAdjustmentAction* eact = 0;
gchar const *flatsidedstr = prefs_get_string_attribute( "tools.shapes.star", "isflatsided" );
bool isFlatSided = flatsidedstr ? (strcmp(flatsidedstr, "false") != 0) : true;
@@ -2343,228 +2338,224 @@ static void sp_rect_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions
//## 3D Box ##
//########################
-static void box3d_toggle_vp_changed (GtkToggleAction *act, GObject *dataKludge, Proj::Axis axis)
-{
- SPDesktop *desktop = (SPDesktop *) g_object_get_data (dataKludge, "desktop");
- SPDocument *document = sp_desktop_document (desktop);
- // FIXME: Make sure document->current_persp3d is set correctly!
- Persp3D *persp = document->current_persp3d;
+// normalize angle so that it lies in the interval [0,360]
+static double box3d_normalize_angle (double a) {
+ double angle = a + ((int) (a/360.0))*360;
+ if (angle < 0) {
+ angle += 360.0;
+ }
+ return angle;
+}
- g_return_if_fail (persp);
+static void
+box3d_set_button_and_adjustment(Persp3D *persp, Proj::Axis axis,
+ GtkAdjustment *adj, GtkAction *act, GtkToggleAction *tact) {
+ // TODO: Take all selected perspectives into account but don't touch the state button if not all of them
+ // have the same state (otherwise a call to box3d_vp_z_state_changed() is triggered and the states
+ // are reset).
+ bool is_infinite = !persp3d_VP_is_finite(persp, axis);
+
+ if (is_infinite) {
+ gtk_toggle_action_set_active(tact, TRUE);
+ gtk_action_set_sensitive(act, TRUE);
+
+ double angle = persp3d_get_infinite_angle(persp, axis);
+ if (angle != NR_HUGE) { // FIXME: We should catch this error earlier (don't show the spinbutton at all)
+ gtk_adjustment_set_value(adj, box3d_normalize_angle(angle));
+ }
+ } else {
+ gtk_toggle_action_set_active(tact, FALSE);
+ gtk_action_set_sensitive(act, FALSE);
+ }
+}
- // quit if run by the attr_changed listener
- if (g_object_get_data(dataKludge, "freeze")) {
+static void
+box3d_resync_toolbar(Inkscape::XML::Node *persp_repr, GObject *data) {
+ if (!persp_repr) {
+ g_print ("No perspective given to box3d_resync_toolbar().\n");
return;
}
- // in turn, prevent listener from responding
- g_object_set_data(dataKludge, "freeze", GINT_TO_POINTER(TRUE));
-
- persp3d_set_VP_state(persp, axis, gtk_toggle_action_get_active(act) ? Proj::INFINITE : Proj::FINITE);
+ GtkWidget *tbl = GTK_WIDGET(data);
+ GtkAdjustment *adj = 0;
+ GtkAction *act = 0;
+ GtkToggleAction *tact = 0;
+ Persp3D *persp = persp3d_get_from_repr(persp_repr);
+ {
+ adj = GTK_ADJUSTMENT(gtk_object_get_data(GTK_OBJECT(tbl), "box3d_angle_x"));
+ act = GTK_ACTION(g_object_get_data(G_OBJECT(tbl), "box3d_angle_x_action"));
+ tact = &INK_TOGGLE_ACTION(g_object_get_data(G_OBJECT(tbl), "box3d_vp_x_state_action"))->action;
- // FIXME: Can we merge this functionality with the one in box3d_persp_tb_event_attr_changed()?
- gchar *str;
- switch (axis) {
- case Proj::X:
- str = g_strdup ("box3d_angle_x_action");
- break;
- case Proj::Y:
- str = g_strdup ("box3d_angle_y_action");
- break;
- case Proj::Z:
- str = g_strdup ("box3d_angle_z_action");
- break;
- default:
- return;
- }
- GtkAction* angle_action = GTK_ACTION (g_object_get_data (dataKludge, str));
- if (angle_action) {
- gtk_action_set_sensitive (angle_action, !persp3d_VP_is_finite(persp, axis));
+ box3d_set_button_and_adjustment(persp, Proj::X, adj, act, tact);
}
+ {
+ adj = GTK_ADJUSTMENT(gtk_object_get_data(GTK_OBJECT(tbl), "box3d_angle_y"));
+ act = GTK_ACTION(g_object_get_data(G_OBJECT(tbl), "box3d_angle_y_action"));
+ tact = &INK_TOGGLE_ACTION(g_object_get_data(G_OBJECT(tbl), "box3d_vp_y_state_action"))->action;
- sp_document_maybe_done(sp_desktop_document(desktop), "toggle_vp", SP_VERB_CONTEXT_3DBOX,
- _("3D Box: Toggle VP"));
- //sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_3DBOX,_("3D Box: Toggle VP"));
+ box3d_set_button_and_adjustment(persp, Proj::Y, adj, act, tact);
+ }
+ {
+ adj = GTK_ADJUSTMENT(gtk_object_get_data(GTK_OBJECT(tbl), "box3d_angle_z"));
+ act = GTK_ACTION(g_object_get_data(G_OBJECT(tbl), "box3d_angle_z_action"));
+ tact = &INK_TOGGLE_ACTION(g_object_get_data(G_OBJECT(tbl), "box3d_vp_z_state_action"))->action;
- g_object_set_data(dataKludge, "freeze", GINT_TO_POINTER(FALSE));
+ box3d_set_button_and_adjustment(persp, Proj::Z, adj, act, tact);
+ }
}
-static void box3d_toggle_vp_x_changed(GtkToggleAction *act, GObject *dataKludge)
+static void box3d_persp_tb_event_attr_changed(Inkscape::XML::Node *repr, gchar const *name,
+ gchar const */*old_value*/, gchar const */*new_value*/,
+ bool /*is_interactive*/, gpointer data)
{
- box3d_toggle_vp_changed (act, dataKludge, Proj::X);
+ GtkWidget *tbl = GTK_WIDGET(data);
+
+ // quit if run by the attr_changed listener
+ // note: it used to work without the differently called freeze_ attributes (here and in
+ // box3d_angle_value_changed()) but I now it doesn't so I'm leaving them in for now
+ if (g_object_get_data(G_OBJECT(tbl), "freeze_angle")) {
+ return;
+ }
+
+ // set freeze so that it can be caught in box3d_angle_z_value_changed() (to avoid calling
+ // sp_document_maybe_done() when the document is undo insensitive)
+ g_object_set_data(G_OBJECT(tbl), "freeze_attr", GINT_TO_POINTER(TRUE));
+
+ // TODO: Only update the appropriate part of the toolbar
+// if (!strcmp(name, "inkscape:vp_z")) {
+ box3d_resync_toolbar(repr, G_OBJECT(tbl));
+// }
+
+ Persp3D *persp = persp3d_get_from_repr(repr);
+ persp3d_update_box_reprs(persp);
+
+ g_object_set_data(G_OBJECT(tbl), "freeze_attr", GINT_TO_POINTER(FALSE));
}
-static void box3d_toggle_vp_y_changed(GtkToggleAction *act, GObject *dataKludge)
+static Inkscape::XML::NodeEventVector box3d_persp_tb_repr_events =
{
- box3d_toggle_vp_changed (act, dataKludge, Proj::Y);
-}
+ NULL, /* child_added */
+ NULL, /* child_removed */
+ box3d_persp_tb_event_attr_changed,
+ NULL, /* content_changed */
+ NULL /* order_changed */
+};
-static void box3d_toggle_vp_z_changed(GtkToggleAction *act, GObject *dataKludge)
+/**
+ * \param selection Should not be NULL.
+ */
+// FIXME: This should rather be put into persp3d-reference.cpp or something similar so that it reacts upon each
+// Change of the perspective, and not of the current selection (but how to refer to the toolbar then?)
+static void
+box3d_toolbox_selection_changed(Inkscape::Selection *selection, GObject *tbl)
{
- box3d_toggle_vp_changed (act, dataKludge, Proj::Z);
+ // Here the following should be done: If all selected boxes have finite VPs in a certain direction,
+ // disable the angle entry fields for this direction (otherwise entering a value in them should only
+ // update the perspectives with infinite VPs and leave the other ones untouched).
+
+ Inkscape::XML::Node *persp_repr = NULL;
+ purge_repr_listener(tbl, tbl);
+
+ SPItem *item = selection->singleItem();
+ if (item && SP_IS_BOX3D(item)) {
+ // FIXME: Also deal with multiple selected boxes
+ SPBox3D *box = SP_BOX3D(item);
+ Persp3D *persp = box3d_get_perspective(box);
+ persp_repr = SP_OBJECT_REPR(persp);
+ if (persp_repr) {
+ g_object_set_data(tbl, "repr", persp_repr);
+ Inkscape::GC::anchor(persp_repr);
+ sp_repr_add_listener(persp_repr, &box3d_persp_tb_repr_events, tbl);
+ sp_repr_synthesize_events(persp_repr, &box3d_persp_tb_repr_events, tbl);
+ }
+
+ inkscape_active_document()->current_persp3d = persp3d_get_from_repr(persp_repr);
+ prefs_set_string_attribute("tools.shapes.3dbox", "persp", persp_repr->attribute("id"));
+
+ box3d_resync_toolbar(persp_repr, tbl);
+ }
}
-static void box3d_vp_angle_changed(GtkAdjustment *adj, GObject *dataKludge, Proj::Axis axis )
+static void
+box3d_angle_value_changed(GtkAdjustment *adj, GObject *dataKludge, Proj::Axis axis)
{
- SPDesktop *desktop = (SPDesktop *) g_object_get_data(dataKludge, "desktop");
- Persp3D *persp = sp_desktop_document (desktop)->current_persp3d;
+ SPDesktop *desktop = (SPDesktop *) g_object_get_data( dataKludge, "desktop" );
+ SPDocument *document = sp_desktop_document(desktop);
// quit if run by the attr_changed listener
- if (g_object_get_data(dataKludge, "freeze")) {
+ // note: it used to work without the differently called freeze_ attributes (here and in
+ // box3d_persp_tb_event_attr_changed()) but I now it doesn't so I'm leaving them in for now
+ if (g_object_get_data( dataKludge, "freeze_attr" )) {
return;
}
// in turn, prevent listener from responding
- g_object_set_data(dataKludge, "freeze", GINT_TO_POINTER(TRUE));
-
- if (persp) {
- double angle = adj->value;
- // FIXME: Shouldn't we set the angle via the SVG attributes of the perspective instead of directly?
- if (persp3d_VP_is_finite(persp, axis)) {
- return;
- }
- persp->tmat.set_infinite_direction (axis, angle);
- persp3d_update_box_reprs (persp);
+ g_object_set_data(dataKludge, "freeze_angle", GINT_TO_POINTER(TRUE));
- sp_document_maybe_done(sp_desktop_document(desktop), "perspectiveangle", SP_VERB_CONTEXT_3DBOX,
- _("3D Box: Change perspective"));
+ //Persp3D *persp = document->current_persp3d;
+ std::set<Persp3D *> sel_persps = persp3d_currently_selected_persps (inkscape_active_event_context());
+ if (sel_persps.empty()) {
+ // this can happen when the document is created; we silently ignore it
+ return;
}
+ Persp3D *persp = *(sel_persps.begin());
+
+ persp->tmat.set_infinite_direction (axis, adj->value);
+ SP_OBJECT(persp)->updateRepr();
- g_object_set_data(dataKludge, "freeze", GINT_TO_POINTER(FALSE));
+ // TODO: use the correct axis here, too
+ sp_document_maybe_done(document, "perspangle", SP_VERB_CONTEXT_3DBOX, _("3D Box: Change perspective (angle of infinite axis)"));
+
+ g_object_set_data( dataKludge, "freeze_angle", GINT_TO_POINTER(FALSE) );
}
-static void box3d_vpx_angle_changed(GtkAdjustment *adj, GObject *dataKludge )
+
+static void
+box3d_angle_x_value_changed(GtkAdjustment *adj, GObject *dataKludge)
{
- box3d_vp_angle_changed (adj, dataKludge, Proj::X);
+ box3d_angle_value_changed(adj, dataKludge, Proj::X);
}
-static void box3d_vpy_angle_changed(GtkAdjustment *adj, GObject *dataKludge )
+static void
+box3d_angle_y_value_changed(GtkAdjustment *adj, GObject *dataKludge)
{
- box3d_vp_angle_changed (adj, dataKludge, Proj::Y);
+ box3d_angle_value_changed(adj, dataKludge, Proj::Y);
}
-static void box3d_vpz_angle_changed(GtkAdjustment *adj, GObject *dataKludge )
+static void
+box3d_angle_z_value_changed(GtkAdjustment *adj, GObject *dataKludge)
{
- box3d_vp_angle_changed (adj, dataKludge, Proj::Z);
+ box3d_angle_value_changed(adj, dataKludge, Proj::Z);
}
-// normalize angle so that it lies in the interval [0,360]
-static double box3d_normalize_angle (double a) {
- double angle = a + ((int) (a/360.0))*360;
- if (angle < 0) {
- angle += 360.0;
- }
- return angle;
-}
-static void box3d_persp_tb_event_attr_changed(Inkscape::XML::Node *repr, gchar const *name,
- gchar const *old_value, gchar const *new_value,
- bool is_interactive, gpointer data)
+static void box3d_vp_state_changed( GtkToggleAction *act, GtkAction *box3d_angle, Proj::Axis axis )
{
- GtkWidget *tbl = GTK_WIDGET(data);
-
- // FIXME: if we check for "freeze" as in other tools, no action is performed at all ...
- // quit if run by the _changed callbacks
- if (g_object_get_data(G_OBJECT(tbl), "freeze")) {
- //return;
- }
-
- // in turn, prevent callbacks from responding
- //g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(TRUE));
-
- GtkAdjustment *adj = 0;
- double angle;
- SPDesktop *desktop = (SPDesktop *) g_object_get_data(G_OBJECT(tbl), "desktop");
- // FIXME: Get the persp from the box (should be the same, but ...)
- Persp3D *persp = sp_desktop_document (desktop)->current_persp3d;
- if (!strcmp(name, "inkscape:vp_x")) {
- GtkAction* act = GTK_ACTION (gtk_object_get_data (GTK_OBJECT(tbl), "box3d_angle_x_action"));
- GtkToggleAction* tact = GTK_TOGGLE_ACTION (gtk_object_get_data (GTK_OBJECT(tbl), "toggle_vp_x_action"));
- if (!persp3d_VP_is_finite(persp, Proj::X)) {
- gtk_action_set_sensitive(GTK_ACTION(act), TRUE);
- gtk_toggle_action_set_active(tact, TRUE);
- } else {
- gtk_action_set_sensitive(GTK_ACTION(act), FALSE);
- gtk_toggle_action_set_active(tact, FALSE);
- }
-
- adj = GTK_ADJUSTMENT(gtk_object_get_data(GTK_OBJECT(tbl), "dir_vp_x"));
- angle = persp3d_get_infinite_angle(persp, Proj::X);
- if (angle != NR_HUGE) { // FIXME: We should catch this error earlier (don't show the spinbutton at all)
- gtk_adjustment_set_value(adj, box3d_normalize_angle(angle));
- }
- }
-
- if (!strcmp(name, "inkscape:vp_y")) {
- GtkAction* act = GTK_ACTION (gtk_object_get_data (GTK_OBJECT(tbl), "box3d_angle_y_action"));
- GtkToggleAction* tact = GTK_TOGGLE_ACTION (gtk_object_get_data (GTK_OBJECT(tbl), "toggle_vp_y_action"));
- if (!persp3d_VP_is_finite(persp, Proj::Y)) {
- gtk_action_set_sensitive(GTK_ACTION(act), TRUE);
- gtk_toggle_action_set_active(tact, TRUE);
- } else {
- gtk_action_set_sensitive(GTK_ACTION(act), FALSE);
- gtk_toggle_action_set_active(tact, FALSE);
- }
-
- adj = GTK_ADJUSTMENT(gtk_object_get_data(GTK_OBJECT(tbl), "dir_vp_y"));
- angle = persp3d_get_infinite_angle(persp, Proj::Y);
- if (angle != NR_HUGE) { // FIXME: We should catch this error earlier (don't show the spinbutton at all)
- gtk_adjustment_set_value(adj, box3d_normalize_angle(angle));
- }
+ // TODO: Take all selected perspectives into account
+ std::set<Persp3D *> sel_persps = persp3d_currently_selected_persps (inkscape_active_event_context());
+ if (sel_persps.empty()) {
+ // this can happen when the document is created; we silently ignore it
+ return;
}
+ Persp3D *persp = *(sel_persps.begin());
- if (!strcmp(name, "inkscape:vp_z")) {
- GtkAction* act = GTK_ACTION (gtk_object_get_data (GTK_OBJECT(tbl), "box3d_angle_z_action"));
- GtkToggleAction* tact = GTK_TOGGLE_ACTION (gtk_object_get_data (GTK_OBJECT(tbl), "toggle_vp_z_action"));
- if (!persp3d_VP_is_finite(persp, Proj::Z)) {
- gtk_action_set_sensitive(GTK_ACTION(act), TRUE);
- gtk_toggle_action_set_active(tact, TRUE);
- } else {
- gtk_action_set_sensitive(GTK_ACTION(act), FALSE);
- gtk_toggle_action_set_active(tact, FALSE);
- }
-
- adj = GTK_ADJUSTMENT(gtk_object_get_data(GTK_OBJECT(tbl), "dir_vp_z"));
- angle = persp3d_get_infinite_angle(persp, Proj::Z);
- if (angle != NR_HUGE) { // FIXME: We should catch this error earlier (don't show the spinbutton at all)
- gtk_adjustment_set_value(adj, box3d_normalize_angle(angle));
- }
- }
-
- //g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(FALSE));
+ bool set_infinite = gtk_toggle_action_get_active(act);
+ persp3d_set_VP_state (persp, axis, set_infinite ? Proj::VP_INFINITE : Proj::VP_FINITE);
}
-static Inkscape::XML::NodeEventVector box3d_persp_tb_repr_events =
+static void box3d_vp_x_state_changed( GtkToggleAction *act, GtkAction *box3d_angle )
{
- NULL, /* child_added */
- NULL, /* child_removed */
- box3d_persp_tb_event_attr_changed,
- NULL, /* content_changed */
- NULL /* order_changed */
-};
+ box3d_vp_state_changed(act, box3d_angle, Proj::X);
+}
-/**
- * \param selection Should not be NULL.
- */
-// FIXME: This should rather be put into persp3d-reference.cpp or something similar so that it reacts upon each
-// Change of the perspective, and not of the current selection (but how to refer to the toolbar then?)
-static void
-box3d_toolbox_selection_changed(Inkscape::Selection *selection, GObject *tbl)
+static void box3d_vp_y_state_changed( GtkToggleAction *act, GtkAction *box3d_angle )
{
- Inkscape::XML::Node *repr = NULL;
- purge_repr_listener(tbl, tbl);
+ box3d_vp_state_changed(act, box3d_angle, Proj::Y);
+}
- SPItem *item = selection->singleItem();
- if (item && SP_IS_BOX3D(item)) {
- //repr = SP_OBJECT_REPR(item);
- repr = SP_OBJECT_REPR(SP_BOX3D(item)->persp_ref->getObject());
- if (repr) {
- g_object_set_data(tbl, "repr", repr);
- Inkscape::GC::anchor(repr);
- sp_repr_add_listener(repr, &box3d_persp_tb_repr_events, tbl);
- sp_repr_synthesize_events(repr, &box3d_persp_tb_repr_events, tbl);
- }
- }
+static void box3d_vp_z_state_changed( GtkToggleAction *act, GtkAction *box3d_angle )
+{
+ box3d_vp_state_changed(act, box3d_angle, Proj::Z);
}
static void box3d_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder)
@@ -2572,101 +2563,127 @@ static void box3d_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions,
EgeAdjustmentAction* eact = 0;
SPDocument *document = sp_desktop_document (desktop);
Persp3D *persp = document->current_persp3d;
- bool toggled = false;
-
- /* angle of VP in X direction */
- eact = create_adjustment_action("3DBoxPosAngleXAction",
- _("Angle X"), _("Angle X:"), _("Angle of infinite vanishing point in X direction"),
- "tools.shapes.3dbox", "dir_vp_x", persp3d_get_infinite_angle(persp, Proj::X),
- GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "altx-box3d",
- -360.0, 360.0, 1.0, 10.0,
- 0, 0, 0, // labels, values, G_N_ELEMENTS(labels),
- box3d_vpx_angle_changed,
- 0.1, 1);
- gtk_action_group_add_action(mainActions, GTK_ACTION(eact));
- g_object_set_data(holder, "box3d_angle_x_action", eact);
+
+ EgeAdjustmentAction* box3d_angle_x = 0;
+ EgeAdjustmentAction* box3d_angle_y = 0;
+ EgeAdjustmentAction* box3d_angle_z = 0;
+
+ /* Angle X */
+ {
+ gchar const* labels[] = { 0, 0, 0, 0, 0, 0, 0 };
+ gdouble values[] = {-90, -60, -30, 0, 30, 60, 90};
+ eact = create_adjustment_action( "3DBoxAngleXAction",
+ _("Angle in X direction"), _("Angle X:"),
+ // Translators: PL is short for 'perspective line'
+ _("Angle of PLs in X direction"),
+ "tools.shapes.3dbox", "box3d_angle_x", 30,
+ GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "altx-box3d",
+ -360.0, 360.0, 1.0, 10.0,
+ labels, values, G_N_ELEMENTS(labels),
+ box3d_angle_x_value_changed );
+ gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
+ g_object_set_data( holder, "box3d_angle_x_action", eact );
+ box3d_angle_x = eact;
+ }
+
if (!persp3d_VP_is_finite(persp, Proj::X)) {
- gtk_action_set_sensitive(GTK_ACTION(eact), TRUE);
+ gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
} else {
- gtk_action_set_sensitive(GTK_ACTION(eact), FALSE);
+ gtk_action_set_sensitive( GTK_ACTION(eact), FALSE );
}
- /* toggle VP in X direction */
+
+ /* VP X state */
{
- InkToggleAction* act = ink_toggle_action_new("3DBoxVPXAction",
- _("Toggle VP in X direction"),
- _("Toggle VP in X direction between 'finite' and 'infinite' (= parallel)"),
- "toggle_vp_x",
- Inkscape::ICON_SIZE_DECORATION);
- gtk_action_group_add_action(mainActions, GTK_ACTION(act));
- g_object_set_data(holder, "toggle_vp_x_action", act);
- gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act), !persp3d_VP_is_finite(persp, Proj::X));
- /* we connect the signal after setting the state to avoid switching the state again */
- g_signal_connect_after(G_OBJECT(act), "toggled", G_CALLBACK(box3d_toggle_vp_x_changed), holder);
- }
-
- /* angle of VP in Y direction */
- eact = create_adjustment_action("3DBoxPosAngleYAction",
- _("Angle Y"), _("Angle Y:"), _("Angle of infinite vanishing point in Y direction"),
- "tools.shapes.3dbox", "dir_vp_y", persp3d_get_infinite_angle(persp, Proj::Y),
- GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL,
- -360.0, 360.0, 1.0, 10.0,
- 0, 0, 0, // labels, values, G_N_ELEMENTS(labels),
- box3d_vpy_angle_changed,
- 0.1, 1);
- gtk_action_group_add_action(mainActions, GTK_ACTION(eact));
- g_object_set_data(holder, "box3d_angle_y_action", eact);
+ InkToggleAction* act = ink_toggle_action_new( "3DBoxVPXStateAction",
+ // Translators: VP is short for 'vanishing point'
+ _("State of VP in X direction"),
+ _("Toggle VP in X direction between 'finite' and 'infinite' (=parallel)"),
+ "toggle_vp_x",
+ Inkscape::ICON_SIZE_DECORATION );
+ gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
+ g_object_set_data( holder, "box3d_vp_x_state_action", act );
+ g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(box3d_vp_x_state_changed), box3d_angle_x );
+ gtk_action_set_sensitive( GTK_ACTION(box3d_angle_x), !prefs_get_int_attribute( "tools.shapes.3dbox", "vp_x_state", 1 ) );
+ gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs_get_int_attribute( "tools.shapes.3dbox", "vp_x_state", 1 ) );
+ }
+
+ /* Angle Y */
+ {
+ gchar const* labels[] = { 0, 0, 0, 0, 0, 0, 0 };
+ gdouble values[] = {-90, -60, -30, 0, 30, 60, 90};
+ eact = create_adjustment_action( "3DBoxAngleYAction",
+ _("Angle in Y direction"), _("Angle Y:"),
+ // Translators: PL is short for 'perspective line'
+ _("Angle of PLs in Y direction"),
+ "tools.shapes.3dbox", "box3d_angle_y", 30,
+ GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL,
+ -360.0, 360.0, 1.0, 10.0,
+ labels, values, G_N_ELEMENTS(labels),
+ box3d_angle_y_value_changed );
+ gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
+ g_object_set_data( holder, "box3d_angle_y_action", eact );
+ box3d_angle_y = eact;
+ }
+
if (!persp3d_VP_is_finite(persp, Proj::Y)) {
- gtk_action_set_sensitive(GTK_ACTION(eact), TRUE);
+ gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
} else {
- gtk_action_set_sensitive(GTK_ACTION(eact), FALSE);
+ gtk_action_set_sensitive( GTK_ACTION(eact), FALSE );
+ }
+
+ /* VP Y state */
+ {
+ InkToggleAction* act = ink_toggle_action_new( "3DBoxVPYStateAction",
+ // Translators: VP is short for 'vanishing point'
+ _("State of VP in Y direction"),
+ _("Toggle VP in Y direction between 'finite' and 'infinite' (=parallel)"),
+ "toggle_vp_y",
+ Inkscape::ICON_SIZE_DECORATION );
+ gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
+ g_object_set_data( holder, "box3d_vp_y_state_action", act );
+ g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(box3d_vp_y_state_changed), box3d_angle_y );
+ gtk_action_set_sensitive( GTK_ACTION(box3d_angle_y), !prefs_get_int_attribute( "tools.shapes.3dbox", "vp_y_state", 1 ) );
+ gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs_get_int_attribute( "tools.shapes.3dbox", "vp_y_state", 1 ) );
}
- /* toggle VP in Y direction */
+ /* Angle Z */
{
- InkToggleAction* act = ink_toggle_action_new("3DBoxVPYAction",
- _("Toggle VP in Y direction"),
- _("Toggle VP in Y direction between 'finite' and 'infinite' (= parallel)"),
- "toggle_vp_y",
- Inkscape::ICON_SIZE_DECORATION);
- gtk_action_group_add_action(mainActions, GTK_ACTION(act));
- gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act), !persp3d_VP_is_finite(persp, Proj::Y));
- g_object_set_data(holder, "toggle_vp_y_action", act);
- /* we connect the signal after setting the state to avoid switching the state again */
- g_signal_connect_after(G_OBJECT(act), "toggled", G_CALLBACK(box3d_toggle_vp_y_changed), holder);
- }
-
- /* angle of VP in Z direction */
- eact = create_adjustment_action("3DBoxPosAngleZAction",
- _("Angle Z"), _("Angle Z:"), _("Angle of infinite vanishing point in Z direction"),
- "tools.shapes.3dbox", "dir_vp_z", persp3d_get_infinite_angle(persp, Proj::Z),
- GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL,
- -360.0, 360.0, 1.0, 10.0,
- 0, 0, 0, // labels, values, G_N_ELEMENTS(labels),
- box3d_vpz_angle_changed,
- 0.1, 1);
-
- gtk_action_group_add_action(mainActions, GTK_ACTION(eact));
- g_object_set_data(holder, "box3d_angle_z_action", eact);
+ gchar const* labels[] = { 0, 0, 0, 0, 0, 0, 0 };
+ gdouble values[] = {-90, -60, -30, 0, 30, 60, 90};
+ eact = create_adjustment_action( "3DBoxAngleZAction",
+ _("Angle in Z direction"), _("Angle Z:"),
+ // Translators: PL is short for 'perspective line'
+ _("Angle of PLs in Z direction"),
+ "tools.shapes.3dbox", "box3d_angle_z", 30,
+ GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL,
+ -360.0, 360.0, 1.0, 10.0,
+ labels, values, G_N_ELEMENTS(labels),
+ box3d_angle_z_value_changed );
+ gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
+ g_object_set_data( holder, "box3d_angle_z_action", eact );
+ box3d_angle_z = eact;
+ }
+
if (!persp3d_VP_is_finite(persp, Proj::Z)) {
- gtk_action_set_sensitive(GTK_ACTION(eact), TRUE);
+ gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
} else {
- gtk_action_set_sensitive(GTK_ACTION(eact), FALSE);
+ gtk_action_set_sensitive( GTK_ACTION(eact), FALSE );
}
- /* toggle VP in Z direction */
+ /* VP Z state */
{
- InkToggleAction* act = ink_toggle_action_new("3DBoxVPZAction",
- _("Toggle VP in Z direction"),
- _("Toggle VP in Z direction between 'finite' and 'infinite' (= parallel)"),
- "toggle_vp_z",
- Inkscape::ICON_SIZE_DECORATION);
- gtk_action_group_add_action(mainActions, GTK_ACTION(act));
-
- gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act), !persp3d_VP_is_finite(persp, Proj::Z));
- g_object_set_data(holder, "toggle_vp_z_action", act);
- /* we connect the signal after setting the state to avoid switching the state again */
- g_signal_connect_after(G_OBJECT(act), "toggled", G_CALLBACK(box3d_toggle_vp_z_changed), holder);
+ InkToggleAction* act = ink_toggle_action_new( "3DBoxVPZStateAction",
+ // Translators: VP is short for 'vanishing point'
+ _("State of VP in Z direction"),
+ _("Toggle VP in Z direction between 'finite' and 'infinite' (=parallel)"),
+ "toggle_vp_z",
+ Inkscape::ICON_SIZE_DECORATION );
+ gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
+ g_object_set_data( holder, "box3d_vp_z_state_action", act );
+ g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(box3d_vp_z_state_changed), box3d_angle_z );
+ gtk_action_set_sensitive( GTK_ACTION(box3d_angle_z), !prefs_get_int_attribute( "tools.shapes.3dbox", "vp_z_state", 1 ) );
+ gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs_get_int_attribute( "tools.shapes.3dbox", "vp_z_state", 1 ) );
}
sigc::connection *connection = new sigc::connection(
namespace {
-bool visible = false;
+bool popdown_visible = false;
+bool popdown_hasfocus = false;
void
sp_text_toolbox_selection_changed (Inkscape::Selection */*selection*/, GObject *tbl)
{
SPStyle *query =
sp_style_new (SP_ACTIVE_DOCUMENT);
+
+ int result_fontspec =
+ sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONT_SPECIFICATION);
int result_family =
sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTFAMILY);
@@ -3981,15 +4002,27 @@ sp_text_toolbox_selection_changed (Inkscape::Selection */*selection*/, GObject *
GtkWidget *entry = GTK_WIDGET (g_object_get_data (G_OBJECT (tbl), "family-entry"));
gtk_entry_set_text (GTK_ENTRY (entry), "");
- } else if (query->text->font_family.value) {
+ } else if (query->text->font_specification.value || query->text->font_family.value) {
GtkWidget *entry = GTK_WIDGET (g_object_get_data (G_OBJECT (tbl), "family-entry"));
- gtk_entry_set_text (GTK_ENTRY (entry), query->text->font_family.value);
+
+ // Get the font that corresponds
+ Glib::ustring familyName;
+
+ font_instance * font = font_factory::Default()->FaceFromStyle(query);
+ if (font) {
+ familyName = font_factory::Default()->GetUIFamilyString(font->descr);
+ font->Unref();
+ font = NULL;
+ }
+
+ gtk_entry_set_text (GTK_ENTRY (entry), familyName.c_str());
Gtk::TreePath path;
try {
- path = Inkscape::FontLister::get_instance()->get_row_for_font (query->text->font_family.value);
+ path = Inkscape::FontLister::get_instance()->get_row_for_font (familyName);
} catch (...) {
+ g_warning("Family name %s does not have an entry in the font lister.", familyName.c_str());
return;
}
{
SPDesktop *desktop = SP_ACTIVE_DESKTOP;
GtkTreeModel *model = 0;
- GtkWidget *popdown = GTK_WIDGET (g_object_get_data (tbl, "family-popdown-window"));
GtkWidget *entry = GTK_WIDGET (g_object_get_data (tbl, "family-entry"));
GtkTreeIter iter;
char *family = 0;
- (void)popdown;
-
gdk_pointer_ungrab (GDK_CURRENT_TIME);
gdk_keyboard_ungrab (GDK_CURRENT_TIME);
SPStyle *query =
sp_style_new (SP_ACTIVE_DOCUMENT);
- int result_numbers =
- sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS);
+ int result_fontspec =
+ sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONT_SPECIFICATION);
+ font_instance * fontFromStyle = font_factory::Default()->FaceFromStyle(query);
+
SPCSSAttr *css = sp_repr_css_attr_new ();
- sp_repr_css_set_property (css, "font-family", family);
+
+
+ // First try to get the font spec from the stored value
+ Glib::ustring fontSpec = query->text->font_specification.set ? query->text->font_specification.value : "";
- // If querying returned nothing, read the style from the text tool prefs (default style for new texts)
- if (result_numbers == QUERY_STYLE_NOTHING)
+ if (fontSpec.empty()) {
+ // Construct a new font specification if it does not yet exist
+ font_instance * fontFromStyle = font_factory::Default()->FaceFromStyle(query);
+ fontSpec = font_factory::Default()->ConstructFontSpecification(fontFromStyle);
+ fontFromStyle->Unref();
+ }
+
+ if (!fontSpec.empty()) {
+ Glib::ustring newFontSpec = font_factory::Default()->ReplaceFontSpecificationFamily(fontSpec, family);
+ if (!newFontSpec.empty() && fontSpec != newFontSpec) {
+ font_instance *font = font_factory::Default()->FaceFromFontSpecification(newFontSpec.c_str());
+ if (font) {
+ sp_repr_css_set_property (css, "-inkscape-font-specification", newFontSpec.c_str());
+
+ // Set all the these just in case they were altered when finding the best
+ // match for the new family and old style...
+
+ gchar c[256];
+
+ font->Family(c, 256);
+ sp_repr_css_set_property (css, "font-family", c);
+
+ font->Attribute( "weight", c, 256);
+ sp_repr_css_set_property (css, "font-weight", c);
+
+ font->Attribute("style", c, 256);
+ sp_repr_css_set_property (css, "font-style", c);
+
+ font->Attribute("stretch", c, 256);
+ sp_repr_css_set_property (css, "font-stretch", c);
+
+ font->Attribute("variant", c, 256);
+ sp_repr_css_set_property (css, "font-variant", c);
+
+ font->Unref();
+ }
+ }
+ }
+
+ // If querying returned nothing, set the default style of the tool (for new texts)
+ if (result_fontspec == QUERY_STYLE_NOTHING)
{
sp_repr_css_change (inkscape_get_repr (INKSCAPE, "tools.text"), css, "style");
sp_text_edit_dialog_default_set_insensitive (); //FIXME: Replace trough a verb
int prop = GPOINTER_TO_INT(data);
bool active = gtk_toggle_button_get_active (button);
+ SPStyle *query =
+ sp_style_new (SP_ACTIVE_DOCUMENT);
+
+ int result_fontspec =
+ sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONT_SPECIFICATION);
+
+ int result_family =
+ sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTFAMILY);
+ int result_style =
+ sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTSTYLE);
+
+ int result_numbers =
+ sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS);
+
+ Glib::ustring fontSpec = query->text->font_specification.set ? query->text->font_specification.value : "";
+ Glib::ustring newFontSpec = "";
+
+ if (fontSpec.empty()) {
+ // Construct a new font specification if it does not yet exist
+ font_instance * fontFromStyle = font_factory::Default()->FaceFromStyle(query);
+ fontSpec = font_factory::Default()->ConstructFontSpecification(fontFromStyle);
+ fontFromStyle->Unref();
+ }
+
switch (prop)
{
case 0:
{
- sp_repr_css_set_property (css, "font-weight", active ? "bold" : "normal" );
+ if (!fontSpec.empty()) {
+ newFontSpec = font_factory::Default()->FontSpecificationSetBold(fontSpec, active);
+ }
+ if (fontSpec != newFontSpec) {
+ // Don't even set the bold if the font didn't exist on the system
+ sp_repr_css_set_property (css, "font-weight", active ? "bold" : "normal" );
+ }
break;
}
case 1:
{
- sp_repr_css_set_property (css, "font-style", active ? "italic" : "normal");
+ if (!fontSpec.empty()) {
+ newFontSpec = font_factory::Default()->FontSpecificationSetItalic(fontSpec, active);
+ }
+ if (fontSpec != newFontSpec) {
+ // Don't even set the italic if the font didn't exist on the system
+ sp_repr_css_set_property (css, "font-style", active ? "italic" : "normal");
+ }
break;
}
}
- SPStyle *query =
- sp_style_new (SP_ACTIVE_DOCUMENT);
- int result_numbers =
- sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS);
+ if (!newFontSpec.empty()) {
+ sp_repr_css_set_property (css, "-inkscape-font-specification", newFontSpec.c_str());
+ }
// If querying returned nothing, read the style from the text tool prefs (default style for new texts)
- if (result_numbers == QUERY_STYLE_NOTHING)
+ if (result_fontspec == QUERY_STYLE_NOTHING)
{
sp_repr_css_change (inkscape_get_repr (INKSCAPE, "tools.text"), css, "style");
}
gtk_widget_grab_focus (GTK_WIDGET(desktop->canvas));
}
-gboolean
-sp_text_toolbox_size_keypress (GtkWidget */*w*/, GdkEventKey *event, gpointer /*data*/)
-{
- SPDesktop *desktop = SP_ACTIVE_DESKTOP;
- if (!desktop) return FALSE;
-
- switch (get_group0_keyval (event)) {
- case GDK_Escape: // defocus
- gtk_widget_grab_focus (GTK_WIDGET(desktop->canvas));
- return TRUE; // I consumed the event
- break;
- case GDK_Return: // defocus
- case GDK_KP_Enter:
- gtk_widget_grab_focus (GTK_WIDGET(desktop->canvas));
- return TRUE; // I consumed the event
- break;
- }
- return FALSE;
-}
-
gboolean
sp_text_toolbox_family_keypress (GtkWidget */*w*/, GdkEventKey *event, GObject *tbl)
{
@@ -4395,10 +4484,19 @@ sp_text_toolbox_family_list_keypress (GtkWidget *w, GdkEventKey *event, GObject
case GDK_Return:
case GDK_Escape: // defocus
gtk_widget_hide (w);
- visible = false;
+ popdown_visible = false;
gtk_widget_grab_focus (GTK_WIDGET(desktop->canvas));
return TRUE; // I consumed the event
break;
+ case GDK_w:
+ case GDK_W:
+ if (event->state & GDK_CONTROL_MASK) {
+ gtk_widget_hide (w);
+ popdown_visible = false;
+ gtk_widget_grab_focus (GTK_WIDGET(desktop->canvas));
+ return TRUE; // I consumed the event
+ }
+ break;
}
return FALSE;
}
if (g_object_get_data (tbl, "size-block")) return;
+ // If this is not from selecting a size in the list (in which case get_active will give the
+ // index of the selected item, otherwise -1) and not from user pressing Enter/Return, do not
+ // process this event. This fixes GTK's stupid insistence on sending an activate change every
+ // time any character gets typed or deleted, which made this control nearly unusable in 0.45.
+ if (gtk_combo_box_get_active (cbox) < 0 && !g_object_get_data (tbl, "enter-pressed"))
+ return;
+
+ gchar *endptr;
+ gdouble value = -1;
char *text = gtk_combo_box_get_active_text (cbox);
+ if (text) {
+ value = g_strtod (text, &endptr);
+ if (endptr == text) // conversion failed, non-numeric input
+ value = -1;
+ free (text);
+ }
+ if (value <= 0) {
+ return; // could not parse value
+ }
SPCSSAttr *css = sp_repr_css_attr_new ();
- sp_repr_css_set_property (css, "font-size", text);
- free (text);
+ Inkscape::CSSOStringStream osfs;
+ osfs << value;
+ sp_repr_css_set_property (css, "font-size", osfs.str().c_str());
SPStyle *query =
sp_style_new (SP_ACTIVE_DOCUMENT);
_("Text: Change font size"));
sp_repr_css_attr_unref (css);
+ gtk_widget_grab_focus (GTK_WIDGET(desktop->canvas));
+}
- if (gtk_combo_box_get_active (cbox) > 0) // if this was from drop-down (as opposed to type-in), defocus
- gtk_widget_grab_focus (GTK_WIDGET(desktop->canvas));
+gboolean
+sp_text_toolbox_size_focusout (GtkWidget */*w*/, GdkEventFocus *event, GObject *tbl)
+{
+ SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+ if (!desktop) return FALSE;
+
+ if (!g_object_get_data (tbl, "esc-pressed")) {
+ g_object_set_data (tbl, "enter-pressed", gpointer(1));
+ GtkComboBox *cbox = GTK_COMBO_BOX(g_object_get_data (G_OBJECT (tbl), "combo-box-size"));
+ sp_text_toolbox_size_changed (cbox, tbl);
+ g_object_set_data (tbl, "enter-pressed", gpointer(0));
+ }
+ return FALSE; // I consumed the event
+}
+
+
+gboolean
+sp_text_toolbox_size_keypress (GtkWidget */*w*/, GdkEventKey *event, GObject *tbl)
+{
+ SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+ if (!desktop) return FALSE;
+
+ switch (get_group0_keyval (event)) {
+ case GDK_Escape: // defocus
+ g_object_set_data (tbl, "esc-pressed", gpointer(1));
+ gtk_widget_grab_focus (GTK_WIDGET(desktop->canvas));
+ g_object_set_data (tbl, "esc-pressed", gpointer(0));
+ return TRUE; // I consumed the event
+ break;
+ case GDK_Return: // defocus
+ case GDK_KP_Enter:
+ g_object_set_data (tbl, "enter-pressed", gpointer(1));
+ GtkComboBox *cbox = GTK_COMBO_BOX(g_object_get_data (G_OBJECT (tbl), "combo-box-size"));
+ sp_text_toolbox_size_changed (cbox, tbl);
+ gtk_widget_grab_focus (GTK_WIDGET(desktop->canvas));
+ g_object_set_data (tbl, "enter-pressed", gpointer(0));
+ return TRUE; // I consumed the event
+ break;
+ }
+ return FALSE;
}
void
GtkWidget *widget = GTK_WIDGET (g_object_get_data (tbl, "family-entry"));
int x, y;
- if (!visible)
+ if (!popdown_visible)
{
gdk_window_get_origin (widget->window, &x, &y);
gtk_window_move (GTK_WINDOW (popdown), x, y + widget->allocation.height + 2); //2px of grace space
gtk_widget_show_all (popdown);
+ //sp_transientize (popdown);
gdk_pointer_grab (widget->window, TRUE,
GdkEventMask (GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
gdk_keyboard_grab (widget->window, TRUE, GDK_CURRENT_TIME);
- visible = true;
+ popdown_visible = true;
}
else
{
+ SPDesktop *desktop = SP_ACTIVE_DESKTOP;
gdk_pointer_ungrab (GDK_CURRENT_TIME);
gdk_keyboard_ungrab (GDK_CURRENT_TIME);
+ gtk_widget_grab_focus (GTK_WIDGET(desktop->canvas));
gtk_widget_hide (popdown);
- visible = false;
+ popdown_visible = false;
}
}
{
SPDesktop *desktop = SP_ACTIVE_DESKTOP;
- gtk_widget_hide (popdown);
- visible = false;
- gtk_widget_grab_focus (GTK_WIDGET(desktop->canvas));
+ if (popdown_hasfocus) {
+ gtk_widget_hide (popdown);
+ popdown_hasfocus = false;
+ popdown_visible = false;
+ gtk_widget_grab_focus (GTK_WIDGET(desktop->canvas));
+ return TRUE;
+ }
+ return FALSE;
+}
+
+gboolean
+sp_text_toolbox_popdown_focus_in (GtkWidget *popdown,
+ GdkEventFocus */*event*/,
+ GObject */*tbl*/)
+{
+ popdown_hasfocus = true;
return TRUE;
}
+
void
cell_data_func (GtkTreeViewColumn */*column*/,
GtkCellRenderer *cell,
g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (sp_text_toolbox_text_popdown_clicked), tbl);
g_signal_connect (G_OBJECT (window), "focus-out-event", G_CALLBACK (sp_text_toolbox_popdown_focus_out), tbl);
+ g_signal_connect (G_OBJECT (window), "focus-in-event", G_CALLBACK (sp_text_toolbox_popdown_focus_in), tbl);
g_signal_connect (G_OBJECT (window), "key-press-event", G_CALLBACK(sp_text_toolbox_family_list_keypress), tbl);
GtkTreeSelection *tselection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
gtk_box_pack_start (GTK_BOX (tbl), cbox, FALSE, FALSE, 0);
g_object_set_data (G_OBJECT (tbl), "combo-box-size", cbox);
g_signal_connect (G_OBJECT (cbox), "changed", G_CALLBACK (sp_text_toolbox_size_changed), tbl);
- gtk_signal_connect(GTK_OBJECT(cbox), "key-press-event", GTK_SIGNAL_FUNC(sp_text_toolbox_size_keypress), NULL);
+ gtk_signal_connect(GTK_OBJECT(gtk_bin_get_child(GTK_BIN(cbox))), "key-press-event", GTK_SIGNAL_FUNC(sp_text_toolbox_size_keypress), tbl);
+ gtk_signal_connect(GTK_OBJECT(gtk_bin_get_child(GTK_BIN(cbox))), "focus-out-event", GTK_SIGNAL_FUNC(sp_text_toolbox_size_focusout), tbl);
//spacer
aux_toolbox_space (tbl, 4);
@@ -5130,7 +5306,9 @@ static void sp_paintbucket_toolbox_prep(SPDesktop *desktop, GtkActionGroup* main
// Create the units menu.
UnitTracker* tracker = new UnitTracker( SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE );
- tracker->setActiveUnit(sp_unit_get_by_abbreviation(prefs_get_string_attribute("tools.paintbucket", "offsetunits")));
+ const gchar *stored_unit = prefs_get_string_attribute("tools.paintbucket", "offsetunits");
+ if (stored_unit)
+ tracker->setActiveUnit(sp_unit_get_by_abbreviation(stored_unit));
g_object_set_data( holder, "tracker", tracker );
{
GtkAction* act = tracker->createAction( "PaintbucketUnitsAction", _("Units"), ("") );
@@ -5200,3 +5378,6 @@ static void sp_paintbucket_toolbox_prep(SPDesktop *desktop, GtkActionGroup* main
*/
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+
+
+