index 052a8f061a18f7f5a806861ad5002370334714e8..07b388d140127087fdd2283e75babdc92a200168 100644 (file)
--- a/src/widgets/toolbox.cpp
+++ b/src/widgets/toolbox.cpp
#include "connector-context.h"
#include "node-context.h"
-#include "draw-context.h"
+#include "pen-context.h"
#include "shape-editor.h"
#include "tweak-context.h"
#include "sp-rect.h"
#include "sp-clippath.h"
#include "sp-mask.h"
#include "style.h"
+#include "tools-switch.h"
#include "selection.h"
#include "selection-chemistry.h"
#include "document-private.h"
} else {
gtk_action_set_sensitive(xact, TRUE);
gtk_action_set_sensitive(yact, TRUE);
- NR::Coord oldx = sp_units_get_pixels(gtk_adjustment_get_value(xadj), *unit);
- NR::Coord oldy = sp_units_get_pixels(gtk_adjustment_get_value(xadj), *unit);
+ Geom::Coord oldx = sp_units_get_pixels(gtk_adjustment_get_value(xadj), *unit);
+ Geom::Coord oldy = sp_units_get_pixels(gtk_adjustment_get_value(xadj), *unit);
if (n_selected == 1) {
- NR::Point sel_node = nodepath->singleSelectedCoords();
- if (oldx != sel_node[NR::X] || oldy != sel_node[NR::Y]) {
- gtk_adjustment_set_value(xadj, sp_pixels_get_units(sel_node[NR::X], *unit));
- gtk_adjustment_set_value(yadj, sp_pixels_get_units(sel_node[NR::Y], *unit));
+ Geom::Point sel_node = nodepath->singleSelectedCoords();
+ if (oldx != sel_node[Geom::X] || oldy != sel_node[Geom::Y]) {
+ gtk_adjustment_set_value(xadj, sp_pixels_get_units(sel_node[Geom::X], *unit));
+ gtk_adjustment_set_value(yadj, sp_pixels_get_units(sel_node[Geom::Y], *unit));
}
} else {
- NR::Maybe<NR::Coord> x = sp_node_selected_common_coord(nodepath, NR::X);
- NR::Maybe<NR::Coord> y = sp_node_selected_common_coord(nodepath, NR::Y);
+ boost::optional<Geom::Coord> x = sp_node_selected_common_coord(nodepath, Geom::X);
+ boost::optional<Geom::Coord> y = sp_node_selected_common_coord(nodepath, Geom::Y);
if ((x && ((*x) != oldx)) || (y && ((*y) != oldy))) {
/* Note: Currently x and y will always have a value, even if the coordinates of the
selected nodes don't coincide (in this case we use the coordinates of the center
@@ -1152,10 +1153,10 @@ sp_node_path_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const *value_
if (shape_editor && shape_editor->has_nodepath()) {
double val = sp_units_get_pixels(gtk_adjustment_get_value(adj), *unit);
if (!strcmp(value_name, "x")) {
- sp_node_selected_move_absolute(shape_editor->get_nodepath(), val, NR::X);
+ sp_node_selected_move_absolute(shape_editor->get_nodepath(), val, Geom::X);
}
if (!strcmp(value_name, "y")) {
- sp_node_selected_move_absolute(shape_editor->get_nodepath(), val, NR::Y);
+ sp_node_selected_move_absolute(shape_editor->get_nodepath(), val, Geom::Y);
}
}
@@ -3264,21 +3265,40 @@ static void sp_spiral_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActio
}
//########################
-//## Pen/Pencil ##
+//## Pen/Pencil ##
//########################
-static void sp_pc_spiro_spline_mode_changed(EgeSelectOneAction* act, GObject* /*tbl*/)
+/* This is used in generic functions below to share large portions of code between pen and pencil tool */
+static char const *
+freehand_tool_name(GObject *dataKludge)
{
- prefs_set_int_attribute("tools.freehand", "spiro-spline-mode", ege_select_one_action_get_active(act));
+ SPDesktop *desktop = (SPDesktop *) g_object_get_data(dataKludge, "desktop");
+ return ( tools_isactive(desktop, TOOLS_FREEHAND_PEN)
+ ? "tools.freehand.pen"
+ : "tools.freehand.pencil" );
}
-static void sp_add_spiro_toggle(GtkActionGroup* mainActions, GObject* holder, bool tool_is_pencil)
+static void freehand_mode_changed(EgeSelectOneAction* act, GObject* tbl)
+{
+ gint mode = ege_select_one_action_get_active(act);
+
+ prefs_set_int_attribute(freehand_tool_name(tbl), "freehand-mode", mode);
+
+ SPDesktop *desktop = (SPDesktop *) g_object_get_data(tbl, "desktop");
+
+ // in pen tool we have more options than in pencil tool; if one of them was chosen, we do any
+ // preparatory work here
+ if (SP_IS_PEN_CONTEXT(desktop->event_context)) {
+ SPPenContext *pc = SP_PEN_CONTEXT(desktop->event_context);
+ pc->polylines_only = (mode == 2);
+ }
+}
+
+static void sp_add_freehand_mode_toggle(GtkActionGroup* mainActions, GObject* holder, bool tool_is_pencil)
{
/* Freehand mode toggle buttons */
{
- //gchar const *flatsidedstr = prefs_get_string_attribute( "tools.shapes.star", "isflatsided" );
- //bool isSpiroMode = flatsidedstr ? (strcmp(flatsidedstr, "false") != 0) : true;
- guint spiroMode = prefs_get_int_attribute("tools.freehand", "spiro-spline-mode", 0);
+ guint freehandMode = prefs_get_int_attribute(tool_is_pencil ? "tools.freehand.pencil" : "tools.freehand.pen", "freehand-mode", 0);
Inkscape::IconSize secondarySize = prefToSize("toolbox", "secondary", 1);
{
@@ -3287,22 +3307,31 @@ static void sp_add_spiro_toggle(GtkActionGroup* mainActions, GObject* holder, bo
GtkTreeIter iter;
gtk_list_store_append( model, &iter );
gtk_list_store_set( model, &iter,
- 0, _("Bézier"),
- 1, _("Regular Bézier mode"),
+ 0, _("Bezier"),
+ 1, _("Create regular Bezier path"),
2, "bezier_mode",
-1 );
gtk_list_store_append( model, &iter );
gtk_list_store_set( model, &iter,
0, _("Spiro"),
- 1, _("Spiro splines mode"),
+ 1, _("Create Spiro path"),
2, "spiro_splines_mode",
-1 );
+ if (!tool_is_pencil) {
+ gtk_list_store_append( model, &iter );
+ gtk_list_store_set( model, &iter,
+ 0, _("Zigzag"),
+ 1, _("Create a sequence of straight line segments"),
+ 2, "polylines_mode",
+ -1 );
+ }
+
EgeSelectOneAction* act = ege_select_one_action_new(tool_is_pencil ?
"FreehandModeActionPencil" :
"FreehandModeActionPen",
- ("Mode:"), ("Mode"), NULL, GTK_TREE_MODEL(model) );
+ (_("Mode:")), ("Mode"), NULL, GTK_TREE_MODEL(model) );
gtk_action_group_add_action( mainActions, GTK_ACTION(act) );
ege_select_one_action_set_appearance( act, "full" );
@@ -3312,15 +3341,15 @@ static void sp_add_spiro_toggle(GtkActionGroup* mainActions, GObject* holder, bo
ege_select_one_action_set_icon_size( act, secondarySize );
ege_select_one_action_set_tooltip_column( act, 1 );
- ege_select_one_action_set_active( act, spiroMode);
- g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(sp_pc_spiro_spline_mode_changed), holder);
+ ege_select_one_action_set_active( act, freehandMode);
+ g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(freehand_mode_changed), holder);
}
}
}
-static void sp_freehand_change_shape(EgeSelectOneAction* act, GObject */*dataKludge*/) {
+static void freehand_change_shape(EgeSelectOneAction* act, GObject *dataKludge) {
gint shape = ege_select_one_action_get_active( act );
- prefs_set_int_attribute("tools.freehand", "shape", shape);
+ prefs_set_int_attribute(freehand_tool_name(dataKludge), "shape", shape);
}
/**
GList *glist = NULL;
glist = g_list_append (glist, _("None"));
- glist = g_list_append (glist, _("Clipboard"));
- glist = g_list_append (glist, _("Crescendo"));
- glist = g_list_append (glist, _("Decrescendo"));
+ glist = g_list_append (glist, _("Triangle in"));
+ glist = g_list_append (glist, _("Triangle out"));
+ glist = g_list_append (glist, _("Ellipse"));
+ glist = g_list_append (glist, _("From clipboard"));
return glist;
}
static void
-sp_freehand_add_advanced_shape_options(GtkActionGroup* mainActions, GObject* holder, bool tool_is_pencil) {
+freehand_add_advanced_shape_options(GtkActionGroup* mainActions, GObject* holder, bool tool_is_pencil) {
/*advanced shape options */
{
GtkListStore* model = gtk_list_store_new( 2, G_TYPE_STRING, G_TYPE_INT );
@@ -3356,11 +3386,11 @@ sp_freehand_add_advanced_shape_options(GtkActionGroup* mainActions, GObject* hol
items = 0;
EgeSelectOneAction* act1 = ege_select_one_action_new(
tool_is_pencil ? "SetPencilShapeAction" : "SetPenShapeAction",
- _("Shape:"), (""), NULL, GTK_TREE_MODEL(model));
+ _("Shape:"), ("Shape"), NULL, GTK_TREE_MODEL(model));
g_object_set( act1, "short_label", _("Shape:"), NULL );
ege_select_one_action_set_appearance( act1, "compact" );
- ege_select_one_action_set_active( act1, prefs_get_int_attribute("tools.freehand", "shape", 0) );
- g_signal_connect( G_OBJECT(act1), "changed", G_CALLBACK(sp_freehand_change_shape), holder );
+ ege_select_one_action_set_active( act1, prefs_get_int_attribute(tool_is_pencil ? "tools.freehand.pencil" : "tools.freehand.pen", "shape", 0) );
+ g_signal_connect( G_OBJECT(act1), "changed", G_CALLBACK(freehand_change_shape), holder );
gtk_action_group_add_action( mainActions, GTK_ACTION(act1) );
g_object_set_data( holder, "shape_action", act1 );
}
@@ -3368,8 +3398,8 @@ sp_freehand_add_advanced_shape_options(GtkActionGroup* mainActions, GObject* hol
static void sp_pen_toolbox_prep(SPDesktop */*desktop*/, GtkActionGroup* mainActions, GObject* holder)
{
- sp_add_spiro_toggle(mainActions, holder, false);
- sp_freehand_add_advanced_shape_options(mainActions, holder, false);
+ sp_add_freehand_mode_toggle(mainActions, holder, false);
+ freehand_add_advanced_shape_options(mainActions, holder, false);
}
static void sp_pencil_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder)
{
- sp_add_spiro_toggle(mainActions, holder, true);
+ sp_add_freehand_mode_toggle(mainActions, holder, true);
EgeAdjustmentAction* eact = 0;
@@ -3454,7 +3484,7 @@ static void sp_pencil_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActio
gchar const* labels[] = {_("(many nodes, rough)"), ("(default)"), 0, 0, 0, 0, ("(few nodes, smooth)")};
gdouble values[] = {1, 10, 20, 30, 50, 75, 100};
eact = create_adjustment_action( "PencilToleranceAction",
- _("Smoothing:"), _("Smoothing"),
+ _("Smoothing:"), _("Smoothing: "),
_("How much smoothing (simplifying) is applied to the line"),
"tools.freehand.pencil", "tolerance",
3.0,
@@ -3475,7 +3505,7 @@ static void sp_pencil_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActio
}
/* advanced shape options */
- sp_freehand_add_advanced_shape_options(mainActions, holder, true);
+ freehand_add_advanced_shape_options(mainActions, holder, true);
/* Reset */
{
@@ -3788,15 +3818,64 @@ static void sp_tweak_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainAction
//########################
//## Calligraphy ##
//########################
-static void update_presets_list (GObject *tbl){
-
- if (g_object_get_data(tbl, "presets_blocked"))
+static void update_presets_list (GObject *tbl)
+{
+ if (g_object_get_data(tbl, "presets_blocked"))
return;
EgeSelectOneAction *sel = static_cast<EgeSelectOneAction *>(g_object_get_data(tbl, "profile_selector"));
- if (sel) {
+ if (!sel) {
ege_select_one_action_set_active(sel, 0);
+ return;
}
+
+ int total_prefs = pref_path_number_of_children("tools.calligraphic.preset");
+
+ for (int i = 1; i <= total_prefs; i++) {
+ gchar *preset_path = get_pref_nth_child("tools.calligraphic.preset", i);
+ Inkscape::XML::Node *preset_repr = inkscape_get_repr(INKSCAPE, preset_path);
+
+ bool match = true;
+
+ for ( Inkscape::Util::List<Inkscape::XML::AttributeRecord const> iter = preset_repr->attributeList();
+ iter;
+ ++iter ) {
+ const gchar *attr_name = g_quark_to_string(iter->key);
+ if (!strcmp(attr_name, "id") || !strcmp(attr_name, "name"))
+ continue;
+ void *widget = g_object_get_data(tbl, attr_name);
+ if (widget) {
+ if (GTK_IS_ADJUSTMENT(widget)) {
+ double v = prefs_get_double_attribute(preset_path, attr_name, 0); // fixme: no min/max checks here, add?
+ GtkAdjustment* adj = static_cast<GtkAdjustment *>(widget);
+ //std::cout << "compared adj " << attr_name << gtk_adjustment_get_value(adj) << " to " << v << "\n";
+ if (fabs(gtk_adjustment_get_value(adj) - v) > 1e-6) {
+ match = false;
+ break;
+ }
+ } else if (GTK_IS_TOGGLE_ACTION(widget)) {
+ int v = prefs_get_int_attribute(preset_path, attr_name, 0); // fixme: no min/max checks here, add?
+ GtkToggleAction* toggle = static_cast<GtkToggleAction *>(widget);
+ //std::cout << "compared toggle " << attr_name << gtk_toggle_action_get_active(toggle) << " to " << v << "\n";
+ if (gtk_toggle_action_get_active(toggle) != v) {
+ match = false;
+ break;
+ }
+ }
+ }
+ }
+
+ if (match) {
+ // newly added item is at the same index as the
+ // save command, so we need to change twice for it to take effect
+ ege_select_one_action_set_active(sel, 0);
+ ege_select_one_action_set_active(sel, i);
+ return;
+ }
+ }
+
+ // no match found
+ ege_select_one_action_set_active(sel, 0);
}
static void sp_ddc_mass_value_changed( GtkAdjustment *adj, GObject* tbl )
}
-#define NUMBER_OF_PRESET_PARAMS 11
-static gchar * widget_names[NUMBER_OF_PRESET_PARAMS] = {
+static gchar const *const widget_names[] = {
"width",
"mass",
"wiggle",
static void sp_dcc_build_presets_list(GObject *tbl)
{
+ g_object_set_data(tbl, "presets_blocked", GINT_TO_POINTER(TRUE));
+
EgeSelectOneAction* selector = static_cast<EgeSelectOneAction *>(g_object_get_data(tbl, "profile_selector"));
GtkListStore* model = GTK_LIST_STORE(ege_select_one_action_get_model(selector));
gtk_list_store_clear (model);
g_object_set_data(tbl, "save_presets_index", GINT_TO_POINTER(ii));
}
+ g_object_set_data(tbl, "presets_blocked", GINT_TO_POINTER(FALSE));
+
update_presets_list (tbl);
}
return;
}
+ g_object_set_data(tbl, "presets_blocked", GINT_TO_POINTER(TRUE));
+
int new_index = -1;
gchar *pref_path = NULL;
int total_prefs = pref_path_number_of_children("tools.calligraphic.preset");
new_index = total_prefs + 1;
gchar *profile_id = g_strdup_printf("dcc%d", new_index);
pref_path = create_pref("tools.calligraphic.preset", profile_id);
- free(profile_id);
+ g_free(profile_id);
}
- for (unsigned i = 0; i < NUMBER_OF_PRESET_PARAMS; ++i) {
- gchar *widget_name = widget_names[i];
+ for (unsigned i = 0; i < G_N_ELEMENTS(widget_names); ++i) {
+ gchar const *const widget_name = widget_names[i];
void *widget = g_object_get_data(tbl, widget_name);
if (widget) {
if (GTK_IS_ADJUSTMENT(widget)) {
}
prefs_set_string_attribute(pref_path, "name", profile_name.c_str());
+ g_object_set_data(tbl, "presets_blocked", GINT_TO_POINTER(FALSE));
+
sp_dcc_build_presets_list (tbl);
- free (pref_path);
+ g_free(pref_path);
}
return;
}
- gchar *preset_path = get_pref_nth_child("tools.calligraphic.preset", preset_index);
+ if (g_object_get_data(tbl, "presets_blocked"))
+ return;
+
+ gchar *const preset_path = get_pref_nth_child("tools.calligraphic.preset", preset_index);
if (preset_path) {
g_object_set_data(tbl, "presets_blocked", GINT_TO_POINTER(TRUE)); //temporarily block the selector so no one will updadte it while we're reading it
g_warning("Bad key found in a preset record: %s\n", attr_name);
}
}
- free(preset_path);
+ g_free(preset_path);
g_object_set_data(tbl, "presets_blocked", GINT_TO_POINTER(FALSE));
}
static void sp_calligraphy_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder)
{
{
+ g_object_set_data(holder, "presets_blocked", GINT_TO_POINTER(TRUE));
+
EgeAdjustmentAction* calligraphy_angle = 0;
{
@@ -4228,10 +4319,12 @@ static void sp_calligraphy_toolbox_prep(SPDesktop *desktop, GtkActionGroup* main
/*calligraphic profile */
{
GtkListStore* model = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT);
- EgeSelectOneAction* act1 = ege_select_one_action_new ("SetProfileAction", "" , (_("Change calligraphic profile")), NULL, GTK_TREE_MODEL(model));
+ EgeSelectOneAction* act1 = ege_select_one_action_new ("SetProfileAction", "" , (_("Choose a preset")), NULL, GTK_TREE_MODEL(model));
ege_select_one_action_set_appearance (act1, "compact");
g_object_set_data (holder, "profile_selector", act1 );
+ g_object_set_data(holder, "presets_blocked", GINT_TO_POINTER(FALSE));
+
sp_dcc_build_presets_list (holder);
g_signal_connect(G_OBJECT(act1), "changed", G_CALLBACK(sp_ddc_change_profile), holder);
@@ -4867,12 +4960,14 @@ sp_text_toolbox_selection_changed (Inkscape::Selection */*selection*/, GObject *
}
//Size
- GtkWidget *cbox = GTK_WIDGET (g_object_get_data (G_OBJECT (tbl), "combo-box-size"));
- char *str = g_strdup_printf ("%.5g", query->font_size.computed);
- g_object_set_data (tbl, "size-block", gpointer(1));
- gtk_entry_set_text (GTK_ENTRY(GTK_BIN (cbox)->child), str);
- g_object_set_data (tbl, "size-block", gpointer(0));
- free (str);
+ {
+ GtkWidget *cbox = GTK_WIDGET(g_object_get_data(G_OBJECT(tbl), "combo-box-size"));
+ gchar *const str = g_strdup_printf("%.5g", query->font_size.computed);
+ g_object_set_data(tbl, "size-block", gpointer(1));
+ gtk_entry_set_text(GTK_ENTRY(GTK_BIN(cbox)->child), str);
+ g_object_set_data(tbl, "size-block", gpointer(0));
+ g_free(str);
+ }
//Anchor
if (query->text_align.computed == SP_CSS_TEXT_ALIGN_JUSTIFY)
sp_document_done (sp_desktop_document (SP_ACTIVE_DESKTOP), SP_VERB_CONTEXT_TEXT,
_("Text: Change font family"));
sp_repr_css_attr_unref (css);
- free (family);
+ g_free(family);
gtk_widget_hide (GTK_WIDGET (g_object_get_data (G_OBJECT(tbl), "warning-image")));
gtk_widget_grab_focus (GTK_WIDGET(desktop->canvas));
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);
+ {
+ gchar *endptr;
+ gchar *const 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;
+ }
+ g_free(text);
+ }
}
if (value <= 0) {
return; // could not parse value
GtkTreeIter *iter,
gpointer /*data*/)
{
- char *family,
- *family_escaped,
- *sample_escaped;
+ gchar *family;
+ gtk_tree_model_get(tree_model, iter, 0, &family, -1);
+ gchar *const family_escaped = g_markup_escape_text(family, -1);
- static const char *sample = _("AaBbCcIiPpQq12369$\342\202\254\302\242?.;/()");
-
- gtk_tree_model_get (tree_model, iter, 0, &family, -1);
-
- family_escaped = g_markup_escape_text (family, -1);
- sample_escaped = g_markup_escape_text (sample, -1);
+ static char const *const sample = _("AaBbCcIiPpQq12369$\342\202\254\302\242?.;/()");
+ gchar *const sample_escaped = g_markup_escape_text(sample, -1);
std::stringstream markup;
- markup << family_escaped << " <span foreground='darkgray' font_family='" << family_escaped << "'>" << sample_escaped << "</span>";
+ markup << family_escaped << " <span foreground='darkgray' font_family='"
+ << family_escaped << "'>" << sample_escaped << "</span>";
g_object_set (G_OBJECT (cell), "markup", markup.str().c_str(), NULL);
- free (family);
- free (family_escaped);
- free (sample_escaped);
+ g_free(family);
+ g_free(family_escaped);
+ g_free(sample_escaped);
}
static void delete_completion(GObject */*obj*/, GtkWidget *entry) {
g_signal_connect_swapped (G_OBJECT (tbl), "show", G_CALLBACK (gtk_widget_hide), box);
////////////Size
- const char *sizes[] = {
+ gchar const *const sizes[] = {
"4", "6", "8", "9", "10", "11", "12", "13", "14",
"16", "18", "20", "22", "24", "28",
"32", "36", "40", "48", "56", "64", "72", "144"
};
GtkWidget *cbox = gtk_combo_box_entry_new_text ();
- for (unsigned int n = 0; n < G_N_ELEMENTS (sizes); gtk_combo_box_append_text (GTK_COMBO_BOX(cbox), sizes[n++]));
+ for (unsigned int i = 0; i < G_N_ELEMENTS(sizes); ++i) {
+ gtk_combo_box_append_text(GTK_COMBO_BOX(cbox), sizes[i]);
+ }
gtk_widget_set_size_request (cbox, 80, -1);
gtk_toolbar_append_widget( tbl, cbox, "", "");
g_object_set_data (G_OBJECT (tbl), "combo-box-size", cbox);