diff options
| author | su_v <suv-sf@users.sourceforge.net> | 2012-12-13 04:17:37 +0000 |
|---|---|---|
| committer | ~suv <suv-sf@users.sourceforge.net> | 2012-12-13 04:17:37 +0000 |
| commit | 991279702f188995eaf339994394ba0ea4d9e7a6 (patch) | |
| tree | 4cda11330822097aae2cb256602343fe2a918f12 /src | |
| parent | preliminary release of the EMF import text reassembly feature. (diff) | |
| parent | Migrate document metadata from NotbookPage to Gtk::Grid and drop dead code (diff) | |
| download | inkscape-991279702f188995eaf339994394ba0ea4d9e7a6.tar.gz inkscape-991279702f188995eaf339994394ba0ea4d9e7a6.zip | |
merge from trunk (r11952)
(bzr r11668.1.46)
Diffstat (limited to 'src')
34 files changed, 1070 insertions, 507 deletions
diff --git a/src/display/drawing-item.cpp b/src/display/drawing-item.cpp index b443ad22a..1e6e44d6f 100644 --- a/src/display/drawing-item.cpp +++ b/src/display/drawing-item.cpp @@ -20,7 +20,6 @@ #include "nr-filter.h" #include "preferences.h" #include "style.h" -#include "2geom/rect.h" namespace Inkscape { @@ -541,17 +540,8 @@ DrawingItem::render(DrawingContext &ct, Geom::IntRect const &area, unsigned flag iarea.intersectWith(_drawbox); } - // Must use same scale factor between "logical space" (coordinates in the - // rendering) and "physical space" (surface pixels). See drawing-surface.cpp. - // See bug 955141. - // There must be a better lib2geom way of finding sarea. - DrawingSurface* ds = ct.surface(); - Geom::Scale scale = ds->scale(); - Geom::Rect rarea( *iarea ); - Geom::Point sarea( rarea.dimensions() * scale ); - DrawingSurface intermediate( *iarea, sarea.ceil() ); + DrawingSurface intermediate(*iarea); DrawingContext ict(intermediate); - unsigned render_result = RENDER_OK; // 1. Render clipping path with alpha = opacity. @@ -624,24 +614,9 @@ DrawingItem::render(DrawingContext &ct, Geom::IntRect const &area, unsigned flag cachect.fill(); _cache->markClean(*carea); } - - ct.rectangle(*carea); // Area to be filled - - // Account for difference between logical and physical spaces. - ct.scale( intermediate.scale().inverse() ); - - // Must shift origin to compensate for scaling. - Geom::Point factor( Geom::Point(1,1) - intermediate.scale().vector() ); - Geom::Point origin( intermediate.origin() ); - Geom::Point shift( origin[Geom::X] * factor[Geom::X], origin[Geom::Y] * factor[Geom::Y] ); - ct.translate( -shift ); - + ct.rectangle(*carea); ct.setSource(&intermediate); ct.fill(); - - ct.translate( shift ); - ct.scale( intermediate.scale() ); - ct.setSource(0,0,0,0); // the call above is to clear a ref on the intermediate surface held by ct @@ -692,29 +667,24 @@ DrawingItem::clip(Inkscape::DrawingContext &ct, Geom::IntRect const &area) if (!_visible) return; if (!area.intersects(_bbox)) return; - // The item used as the clipping path itself has a clipping path. - // Render this item's clipping path onto a temporary surface, then composite it - // with the item using the IN operator - if (_clip) { - ct.pushAlphaGroup(); - { Inkscape::DrawingContext::Save save(ct); - ct.setSource(0,0,0,1); - _clip->clip(ct, area); - } - ct.pushAlphaGroup(); - } - + ct.setSource(0,0,0,1); + ct.pushGroup(); // rasterize the clipping path _clipItem(ct, area); - if (_clip) { + // The item used as the clipping path itself has a clipping path. + // Render this item's clipping path onto a temporary surface, then composite it + // with the item using the IN operator + ct.pushGroup(); + _clip->clip(ct, area); ct.popGroupToSource(); ct.setOperator(CAIRO_OPERATOR_IN); ct.paint(); - ct.popGroupToSource(); - ct.setOperator(CAIRO_OPERATOR_SOURCE); - ct.paint(); } + ct.popGroupToSource(); + ct.setOperator(CAIRO_OPERATOR_OVER); + ct.paint(); + ct.setSource(0,0,0,0); } /** diff --git a/src/display/nr-filter-gaussian.cpp b/src/display/nr-filter-gaussian.cpp index 390021712..6ef321992 100644 --- a/src/display/nr-filter-gaussian.cpp +++ b/src/display/nr-filter-gaussian.cpp @@ -102,15 +102,16 @@ static inline Tt clip_round_cast(Ts const v) { Ts const minval = std::numeric_limits<Tt>::min(); Ts const maxval = std::numeric_limits<Tt>::max(); Tt const minval_rounded = std::numeric_limits<Tt>::min(); - Ts const maxval_rounded = std::numeric_limits<Tt>::max(); + Tt const maxval_rounded = std::numeric_limits<Tt>::max(); if ( v < minval ) return minval_rounded; if ( v > maxval ) return maxval_rounded; return round_cast<Tt>(v); } template<typename Tt, typename Ts> -static inline Tt clip_round_cast_varmax(Ts const v, Ts const maxval, Tt const maxval_rounded) { +static inline Tt clip_round_cast_varmax(Ts const v, Tt const maxval_rounded) { Ts const minval = std::numeric_limits<Tt>::min(); + Tt const maxval = maxval_rounded; Tt const minval_rounded = std::numeric_limits<Tt>::min(); if ( v < minval ) return minval_rounded; if ( v > maxval ) return maxval_rounded; @@ -339,7 +340,7 @@ filter2D_IIR(PT *const dest, int const dstr1, int const dstr2, dstimg -= dstr1; if ( PREMULTIPLIED_ALPHA ) { dstimg[alpha_PC] = clip_round_cast<PT>(v[0][alpha_PC]); - PREMUL_ALPHA_LOOP dstimg[c] = clip_round_cast_varmax<PT>(v[0][c], v[0][alpha_PC], dstimg[alpha_PC]); + PREMUL_ALPHA_LOOP dstimg[c] = clip_round_cast_varmax<PT>(v[0][c], dstimg[alpha_PC]); } else { for(unsigned int c=0; c<PC; c++) dstimg[c] = clip_round_cast<PT>(v[0][c]); } @@ -354,7 +355,7 @@ filter2D_IIR(PT *const dest, int const dstr1, int const dstr2, dstimg -= dstr1; if ( PREMULTIPLIED_ALPHA ) { dstimg[alpha_PC] = clip_round_cast<PT>(v[0][alpha_PC]); - PREMUL_ALPHA_LOOP dstimg[c] = clip_round_cast_varmax<PT>(v[0][c], v[0][alpha_PC], dstimg[alpha_PC]); + PREMUL_ALPHA_LOOP dstimg[c] = clip_round_cast_varmax<PT>(v[0][c], dstimg[alpha_PC]); } else { for(unsigned int c=0; c<PC; c++) dstimg[c] = clip_round_cast<PT>(v[0][c]); } diff --git a/src/flood-context.cpp b/src/flood-context.cpp index a6c7fa0dc..3c656527e 100644 --- a/src/flood-context.cpp +++ b/src/flood-context.cpp @@ -205,6 +205,10 @@ static void sp_flood_context_setup(SPEventContext *ec) } } +// Changes from 0.48 -> 0.49 (Cairo) +// 0.49: Ignores alpha in background +// 0.48: RGBA, 0.49 ARGB +// 0.49: premultiplied alpha inline static guint32 compose_onto(guint32 px, guint32 bg) { guint ap = 0, rp = 0, gp = 0, bp = 0; @@ -212,10 +216,12 @@ inline static guint32 compose_onto(guint32 px, guint32 bg) ExtractARGB32(px, ap, rp, gp, bp); ExtractRGB32(bg, rb, gb, bb); - guint ao = 255*255 - (255-ap)*(255-bp); ao = (ao + 127) / 255; - guint ro = (255-ap)*rb + rp; ro = (ro + 127) / 255; - guint go = (255-ap)*gb + gp; go = (go + 127) / 255; - guint bo = (255-ap)*bb + bp; bo = (bo + 127) / 255; + // guint ao = 255*255 - (255-ap)*(255-bp); ao = (ao + 127) / 255; + // guint ao = (255-ap)*ab + 255*ap; ao = (ao + 127) / 255; + guint ao = 255; // Cairo version doesn't allow background to have alpha != 1. + guint ro = (255-ap)*rb + 255*rp; ro = (ro + 127) / 255; + guint go = (255-ap)*gb + 255*gp; go = (go + 127) / 255; + guint bo = (255-ap)*bb + 255*bp; bo = (bo + 127) / 255; guint pxout = AssembleARGB32(ao, ro, go, bo); return pxout; @@ -314,10 +320,12 @@ static bool compare_pixels(guint32 check, guint32 orig, guint32 merged_orig_pixe return abs(static_cast<int>(ac ? unpremul_alpha(bc, ac) : 0) - (ao ? unpremul_alpha(bo, ao) : 0)) <= threshold; case FLOOD_CHANNELS_RGB: guint32 amc, rmc, bmc, gmc; - amc = 255*255 - (255-ac)*(255-ad); amc = (amc + 127) / 255; - rmc = (255-ac)*rd + rc; rmc = (rmc + 127) / 255; - gmc = (255-ac)*gd + gc; gmc = (gmc + 127) / 255; - bmc = (255-ac)*bd + bc; bmc = (bmc + 127) / 255; + //amc = 255*255 - (255-ac)*(255-ad); amc = (amc + 127) / 255; + //amc = (255-ac)*ad + 255*ac; amc = (amc + 127) / 255; + amc = 255; // Why are we looking at desktop? Cairo version ignores destop alpha + rmc = (255-ac)*rd + 255*rc; rmc = (rmc + 127) / 255; + gmc = (255-ac)*gd + 255*gc; gmc = (gmc + 127) / 255; + bmc = (255-ac)*bd + 255*bc; bmc = (bmc + 127) / 255; diff += abs(static_cast<int>(amc ? unpremul_alpha(rmc, amc) : 0) - (amop ? unpremul_alpha(rmop, amop) : 0)); diff += abs(static_cast<int>(amc ? unpremul_alpha(gmc, amc) : 0) - (amop ? unpremul_alpha(gmop, amop) : 0)); @@ -826,6 +834,7 @@ static void sp_flood_do_flood_fill(SPEventContext *event_context, GdkEvent *even guchar *px = g_new(guchar, stride * height); guint32 bgcolor, dtc; + // Draw image into data block px { // this block limits the lifetime of Drawing and DrawingContext /* Create DrawingItems and set transform */ unsigned dkey = SPItem::display_key_new(1); @@ -854,6 +863,8 @@ static void sp_flood_do_flood_fill(SPEventContext *event_context, GdkEvent *even drawing.render(ct, final_bbox); + //cairo_surface_write_to_png( s, "cairo.png" ); + cairo_surface_flush(s); cairo_surface_destroy(s); @@ -861,6 +872,14 @@ static void sp_flood_do_flood_fill(SPEventContext *event_context, GdkEvent *even document->getRoot()->invoke_hide(dkey); } + // { + // // Dump data to png + // cairo_surface_t *s = cairo_image_surface_create_for_data( + // px, CAIRO_FORMAT_ARGB32, width, height, stride); + // cairo_surface_write_to_png( s, "cairo2.png" ); + // std::cout << " Wrote cairo2.png" << std::endl; + // } + guchar *trace_px = g_new(guchar, width * height); memset(trace_px, 0x00, width * height); diff --git a/src/gradient-drag.cpp b/src/gradient-drag.cpp index 69b9db92d..904c3b349 100644 --- a/src/gradient-drag.cpp +++ b/src/gradient-drag.cpp @@ -2080,28 +2080,33 @@ void GrDrag::updateDraggers() if (style && (style->fill.isPaintserver())) { SPPaintServer *server = style->getFillPaintServer(); - if ( server && (server->isSolid() || SP_GRADIENT(server)->getVector()->isSolid()) ) { - // Suppress "gradientness" of solid paint - } else if ( SP_IS_LINEARGRADIENT(server) ) { - addDraggersLinear( SP_LINEARGRADIENT(server), item, Inkscape::FOR_FILL ); - } else if ( SP_IS_RADIALGRADIENT(server) ) { - addDraggersRadial( SP_RADIALGRADIENT(server), item, Inkscape::FOR_FILL ); - } else if ( SP_IS_MESHGRADIENT(server) ) { - addDraggersMesh( SP_MESHGRADIENT(server), item, Inkscape::FOR_FILL ); + if ( server && SP_IS_GRADIENT( server ) ) { + if ( server->isSolid() + || (SP_GRADIENT(server)->getVector() && SP_GRADIENT(server)->getVector()->isSolid())) { + // Suppress "gradientness" of solid paint + } else if ( SP_IS_LINEARGRADIENT(server) ) { + addDraggersLinear( SP_LINEARGRADIENT(server), item, Inkscape::FOR_FILL ); + } else if ( SP_IS_RADIALGRADIENT(server) ) { + addDraggersRadial( SP_RADIALGRADIENT(server), item, Inkscape::FOR_FILL ); + } else if ( SP_IS_MESHGRADIENT(server) ) { + addDraggersMesh( SP_MESHGRADIENT(server), item, Inkscape::FOR_FILL ); + } } - } if (style && (style->stroke.isPaintserver())) { SPPaintServer *server = style->getStrokePaintServer(); - if ( server && (server->isSolid() || SP_GRADIENT(server)->getVector()->isSolid()) ) { - // Suppress "gradientness" of solid paint - } else if ( SP_IS_LINEARGRADIENT(server) ) { - addDraggersLinear( SP_LINEARGRADIENT(server), item, Inkscape::FOR_STROKE ); - } else if ( SP_IS_RADIALGRADIENT(server) ) { - addDraggersRadial( SP_RADIALGRADIENT(server), item, Inkscape::FOR_STROKE ); - } else if ( SP_IS_MESHGRADIENT(server) ) { - addDraggersMesh( SP_MESHGRADIENT(server), item, Inkscape::FOR_STROKE ); + if ( server && SP_IS_GRADIENT( server ) ) { + if ( server->isSolid() + || (SP_GRADIENT(server)->getVector() && SP_GRADIENT(server)->getVector()->isSolid())) { + // Suppress "gradientness" of solid paint + } else if ( SP_IS_LINEARGRADIENT(server) ) { + addDraggersLinear( SP_LINEARGRADIENT(server), item, Inkscape::FOR_STROKE ); + } else if ( SP_IS_RADIALGRADIENT(server) ) { + addDraggersRadial( SP_RADIALGRADIENT(server), item, Inkscape::FOR_STROKE ); + } else if ( SP_IS_MESHGRADIENT(server) ) { + addDraggersMesh( SP_MESHGRADIENT(server), item, Inkscape::FOR_STROKE ); + } } } } @@ -2145,58 +2150,61 @@ void GrDrag::updateLines() if (style && (style->fill.isPaintserver())) { SPPaintServer *server = item->style->getFillPaintServer(); - if ( server && (server->isSolid() || SP_GRADIENT(server)->getVector()->isSolid()) ) { - // Suppress "gradientness" of solid paint - } else if ( SP_IS_LINEARGRADIENT(server) ) { - addLine(item, getGradientCoords(item, POINT_LG_BEGIN, 0, Inkscape::FOR_FILL), getGradientCoords(item, POINT_LG_END, 0, Inkscape::FOR_FILL), Inkscape::FOR_FILL); - } else if ( SP_IS_RADIALGRADIENT(server) ) { - Geom::Point center = getGradientCoords(item, POINT_RG_CENTER, 0, Inkscape::FOR_FILL); - addLine(item, center, getGradientCoords(item, POINT_RG_R1, 0, Inkscape::FOR_FILL), Inkscape::FOR_FILL); - addLine(item, center, getGradientCoords(item, POINT_RG_R2, 0, Inkscape::FOR_FILL), Inkscape::FOR_FILL); - } else if ( SP_IS_MESHGRADIENT(server) ) { - - SPMeshGradient *mg = SP_MESHGRADIENT(server); - - guint rows = mg->array.patch_rows(); - guint columns = mg->array.patch_columns(); - for ( guint i = 0; i < rows; ++i ) { - for ( guint j = 0; j < columns; ++j ) { - - std::vector<Geom::Point> h; - - SPMeshPatchI patch( &(mg->array.nodes), i, j ); - - // Top line - h = patch.getPointsForSide( 0 ); - for( guint p = 0; p < 4; ++p ) { - h[p] *= Geom::Affine(mg->gradientTransform) * (Geom::Affine)item->i2dt_affine(); - } - addCurve (item, h[0], h[1], h[2], h[3], Inkscape::FOR_FILL ); - - // Right line - if( j == columns - 1 ) { - h = patch.getPointsForSide( 1 ); + if ( server && SP_IS_GRADIENT( server ) ) { + if ( server->isSolid() + || (SP_GRADIENT(server)->getVector() && SP_GRADIENT(server)->getVector()->isSolid())) { + // Suppress "gradientness" of solid paint + } else if ( SP_IS_LINEARGRADIENT(server) ) { + addLine(item, getGradientCoords(item, POINT_LG_BEGIN, 0, Inkscape::FOR_FILL), getGradientCoords(item, POINT_LG_END, 0, Inkscape::FOR_FILL), Inkscape::FOR_FILL); + } else if ( SP_IS_RADIALGRADIENT(server) ) { + Geom::Point center = getGradientCoords(item, POINT_RG_CENTER, 0, Inkscape::FOR_FILL); + addLine(item, center, getGradientCoords(item, POINT_RG_R1, 0, Inkscape::FOR_FILL), Inkscape::FOR_FILL); + addLine(item, center, getGradientCoords(item, POINT_RG_R2, 0, Inkscape::FOR_FILL), Inkscape::FOR_FILL); + } else if ( SP_IS_MESHGRADIENT(server) ) { + + SPMeshGradient *mg = SP_MESHGRADIENT(server); + + guint rows = mg->array.patch_rows(); + guint columns = mg->array.patch_columns(); + for ( guint i = 0; i < rows; ++i ) { + for ( guint j = 0; j < columns; ++j ) { + + std::vector<Geom::Point> h; + + SPMeshPatchI patch( &(mg->array.nodes), i, j ); + + // Top line + h = patch.getPointsForSide( 0 ); for( guint p = 0; p < 4; ++p ) { h[p] *= Geom::Affine(mg->gradientTransform) * (Geom::Affine)item->i2dt_affine(); } addCurve (item, h[0], h[1], h[2], h[3], Inkscape::FOR_FILL ); - } - // Bottom line - if( i == rows - 1 ) { - h = patch.getPointsForSide( 2 ); + // Right line + if( j == columns - 1 ) { + h = patch.getPointsForSide( 1 ); + for( guint p = 0; p < 4; ++p ) { + h[p] *= Geom::Affine(mg->gradientTransform) * (Geom::Affine)item->i2dt_affine(); + } + addCurve (item, h[0], h[1], h[2], h[3], Inkscape::FOR_FILL ); + } + + // Bottom line + if( i == rows - 1 ) { + h = patch.getPointsForSide( 2 ); + for( guint p = 0; p < 4; ++p ) { + h[p] *= Geom::Affine(mg->gradientTransform) * (Geom::Affine)item->i2dt_affine(); + } + addCurve (item, h[0], h[1], h[2], h[3], Inkscape::FOR_FILL ); + } + + // Left line + h = patch.getPointsForSide( 3 ); for( guint p = 0; p < 4; ++p ) { h[p] *= Geom::Affine(mg->gradientTransform) * (Geom::Affine)item->i2dt_affine(); } addCurve (item, h[0], h[1], h[2], h[3], Inkscape::FOR_FILL ); } - - // Left line - h = patch.getPointsForSide( 3 ); - for( guint p = 0; p < 4; ++p ) { - h[p] *= Geom::Affine(mg->gradientTransform) * (Geom::Affine)item->i2dt_affine(); - } - addCurve (item, h[0], h[1], h[2], h[3], Inkscape::FOR_FILL ); } } } @@ -2204,61 +2212,64 @@ void GrDrag::updateLines() if (style && (style->stroke.isPaintserver())) { SPPaintServer *server = item->style->getStrokePaintServer(); - if ( server && (server->isSolid() || SP_GRADIENT(server)->getVector()->isSolid()) ) { - // Suppress "gradientness" of solid paint - } else if ( SP_IS_LINEARGRADIENT(server) ) { - addLine(item, getGradientCoords(item, POINT_LG_BEGIN, 0, Inkscape::FOR_STROKE), getGradientCoords(item, POINT_LG_END, 0, Inkscape::FOR_STROKE), Inkscape::FOR_STROKE); - } else if ( SP_IS_RADIALGRADIENT(server) ) { - Geom::Point center = getGradientCoords(item, POINT_RG_CENTER, 0, Inkscape::FOR_STROKE); - addLine(item, center, getGradientCoords(item, POINT_RG_R1, 0, Inkscape::FOR_STROKE), Inkscape::FOR_STROKE); - addLine(item, center, getGradientCoords(item, POINT_RG_R2, 0, Inkscape::FOR_STROKE), Inkscape::FOR_STROKE); - } else if ( SP_IS_MESHGRADIENT(server) ) { - - // MESH FIXME: TURN ROUTINE INTO FUNCTION AND CALL FOR BOTH FILL AND STROKE. - SPMeshGradient *mg = SP_MESHGRADIENT(server); - - guint rows = mg->array.patch_rows(); - guint columns = mg->array.patch_columns(); - for ( guint i = 0; i < rows; ++i ) { - for ( guint j = 0; j < columns; ++j ) { - - std::vector<Geom::Point> h; - - SPMeshPatchI patch( &(mg->array.nodes), i, j ); - - // Top line - h = patch.getPointsForSide( 0 ); - for( guint p = 0; p < 4; ++p ) { - h[p] *= Geom::Affine(mg->gradientTransform) * (Geom::Affine)item->i2dt_affine(); - } - addCurve (item, h[0], h[1], h[2], h[3], Inkscape::FOR_STROKE ); - - // Right line - if( j == columns - 1 ) { - h = patch.getPointsForSide( 1 ); + if ( server && SP_IS_GRADIENT( server ) ) { + if ( server->isSolid() + || (SP_GRADIENT(server)->getVector() && SP_GRADIENT(server)->getVector()->isSolid())) { + // Suppress "gradientness" of solid paint + } else if ( SP_IS_LINEARGRADIENT(server) ) { + addLine(item, getGradientCoords(item, POINT_LG_BEGIN, 0, Inkscape::FOR_STROKE), getGradientCoords(item, POINT_LG_END, 0, Inkscape::FOR_STROKE), Inkscape::FOR_STROKE); + } else if ( SP_IS_RADIALGRADIENT(server) ) { + Geom::Point center = getGradientCoords(item, POINT_RG_CENTER, 0, Inkscape::FOR_STROKE); + addLine(item, center, getGradientCoords(item, POINT_RG_R1, 0, Inkscape::FOR_STROKE), Inkscape::FOR_STROKE); + addLine(item, center, getGradientCoords(item, POINT_RG_R2, 0, Inkscape::FOR_STROKE), Inkscape::FOR_STROKE); + } else if ( SP_IS_MESHGRADIENT(server) ) { + + // MESH FIXME: TURN ROUTINE INTO FUNCTION AND CALL FOR BOTH FILL AND STROKE. + SPMeshGradient *mg = SP_MESHGRADIENT(server); + + guint rows = mg->array.patch_rows(); + guint columns = mg->array.patch_columns(); + for ( guint i = 0; i < rows; ++i ) { + for ( guint j = 0; j < columns; ++j ) { + + std::vector<Geom::Point> h; + + SPMeshPatchI patch( &(mg->array.nodes), i, j ); + + // Top line + h = patch.getPointsForSide( 0 ); for( guint p = 0; p < 4; ++p ) { h[p] *= Geom::Affine(mg->gradientTransform) * (Geom::Affine)item->i2dt_affine(); } addCurve (item, h[0], h[1], h[2], h[3], Inkscape::FOR_STROKE ); - } - // Bottom line - if( i == rows - 1 ) { - h = patch.getPointsForSide( 2 ); + // Right line + if( j == columns - 1 ) { + h = patch.getPointsForSide( 1 ); + for( guint p = 0; p < 4; ++p ) { + h[p] *= Geom::Affine(mg->gradientTransform) * (Geom::Affine)item->i2dt_affine(); + } + addCurve (item, h[0], h[1], h[2], h[3], Inkscape::FOR_STROKE ); + } + + // Bottom line + if( i == rows - 1 ) { + h = patch.getPointsForSide( 2 ); + for( guint p = 0; p < 4; ++p ) { + h[p] *= Geom::Affine(mg->gradientTransform) * (Geom::Affine)item->i2dt_affine(); + } + addCurve (item, h[0], h[1], h[2], h[3], Inkscape::FOR_STROKE ); + } + + // Left line + h = patch.getPointsForSide( 3 ); for( guint p = 0; p < 4; ++p ) { h[p] *= Geom::Affine(mg->gradientTransform) * (Geom::Affine)item->i2dt_affine(); } addCurve (item, h[0], h[1], h[2], h[3], Inkscape::FOR_STROKE ); } - - // Left line - h = patch.getPointsForSide( 3 ); - for( guint p = 0; p < 4; ++p ) { - h[p] *= Geom::Affine(mg->gradientTransform) * (Geom::Affine)item->i2dt_affine(); - } - addCurve (item, h[0], h[1], h[2], h[3], Inkscape::FOR_STROKE ); - } - } + } + } } } } diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp index 76a3df0e8..ed1e1dc5c 100644 --- a/src/libnrtype/FontFactory.cpp +++ b/src/libnrtype/FontFactory.cpp @@ -22,13 +22,6 @@ #include "libnrtype/font-instance.h" #include "util/unordered-containers.h" -#if !PANGO_VERSION_CHECK(1,24,0) -#define PANGO_WEIGHT_THIN static_cast<PangoWeight>(100) -#define PANGO_WEIGHT_BOOK static_cast<PangoWeight>(380) -#define PANGO_WEIGHT_MEDIUM static_cast<PangoWeight>(500) -#define PANGO_WEIGHT_ULTRAHEAVY static_cast<PangoWeight>(1000) -#endif - typedef INK_UNORDERED_MAP<PangoFontDescription*, font_instance*, font_descr_hash, font_descr_equal> FaceMapType; // need to avoid using the size field diff --git a/src/libnrtype/FontInstance.cpp b/src/libnrtype/FontInstance.cpp index f8b2c3b9d..4ca8bf2a0 100644 --- a/src/libnrtype/FontInstance.cpp +++ b/src/libnrtype/FontInstance.cpp @@ -27,13 +27,6 @@ #include "livarot/Path.h" #include "util/unordered-containers.h" -#if !PANGO_VERSION_CHECK(1,24,0) -#define PANGO_WEIGHT_THIN static_cast<PangoWeight>(100) -#define PANGO_WEIGHT_BOOK static_cast<PangoWeight>(380) -#define PANGO_WEIGHT_MEDIUM static_cast<PangoWeight>(500) -#define PANGO_WEIGHT_ULTRAHEAVY static_cast<PangoWeight>(1000) -#endif - struct font_style_hash : public std::unary_function<font_style, size_t> { size_t operator()(font_style const &x) const; diff --git a/src/libnrtype/Layout-TNG-Input.cpp b/src/libnrtype/Layout-TNG-Input.cpp index 07bf207c8..10310b4aa 100644 --- a/src/libnrtype/Layout-TNG-Input.cpp +++ b/src/libnrtype/Layout-TNG-Input.cpp @@ -19,12 +19,6 @@ #include "sp-string.h" #include "FontFactory.h" -#if !PANGO_VERSION_CHECK(1,24,0) -#define PANGO_WEIGHT_THIN static_cast<PangoWeight>(100) -#define PANGO_WEIGHT_BOOK static_cast<PangoWeight>(380) -#define PANGO_WEIGHT_MEDIUM static_cast<PangoWeight>(500) -#define PANGO_WEIGHT_ULTRAHEAVY static_cast<PangoWeight>(1000) -#endif namespace Inkscape { namespace Text { diff --git a/src/libnrtype/Layout-TNG-Output.cpp b/src/libnrtype/Layout-TNG-Output.cpp index 1d293e360..9e75473ce 100644 --- a/src/libnrtype/Layout-TNG-Output.cpp +++ b/src/libnrtype/Layout-TNG-Output.cpp @@ -22,12 +22,6 @@ #include <2geom/pathvector.h> #include "libunicode-convert/unicode-convert.h" -#if !PANGO_VERSION_CHECK(1,24,0) -#define PANGO_WEIGHT_THIN static_cast<PangoWeight>(100) -#define PANGO_WEIGHT_BOOK static_cast<PangoWeight>(380) -#define PANGO_WEIGHT_MEDIUM static_cast<PangoWeight>(500) -#define PANGO_WEIGHT_ULTRAHEAVY static_cast<PangoWeight>(1000) -#endif namespace Inkscape { namespace Extension { diff --git a/src/preferences-skeleton.h b/src/preferences-skeleton.h index 2cd391150..77ffe429a 100644 --- a/src/preferences-skeleton.h +++ b/src/preferences-skeleton.h @@ -337,6 +337,10 @@ static char const preferences_skeleton[] = " check_on_reading=\"0\" " " check_on_editing=\"0\" " " check_on_writing=\"0\"/>\n" +" <group id=\"externalresources\">\n" +" <group id=\"xml\" " +" allow_net_access=\"0\"/>\n" +" </group>\n" " <group id=\"forkgradientvectors\" value=\"1\"/>\n" " <group id=\"iconrender\" named_nodelay=\"0\"/>\n" " <group id=\"autosave\" enable=\"0\" interval=\"10\" path=\"\" max=\"10\"/>\n" diff --git a/src/selection.cpp b/src/selection.cpp index d769b402c..72f50137c 100644 --- a/src/selection.cpp +++ b/src/selection.cpp @@ -443,15 +443,13 @@ std::vector<Inkscape::SnapCandidatePoint> Selection::getSnapPoints(SnapPreferenc SnapPreferences snapprefs_dummy = *snapprefs; // create a local copy of the snapping prefs snapprefs_dummy.setTargetSnappable(Inkscape::SNAPTARGET_ROTATION_CENTER, false); // locally disable snapping to the item center - //snapprefs_dummy.setTargetSnappable(Inkscape::SNAPTARGET_NODE_CUSP, true); // consider any type of nodes as a snap source - //snapprefs_dummy.setTargetSnappable(Inkscape::SNAPTARGET_NODE_SMOOTH, true); // i.e. disregard the smooth / cusp node preference std::vector<Inkscape::SnapCandidatePoint> p; for (GSList const *iter = items; iter != NULL; iter = iter->next) { SPItem *this_item = SP_ITEM(iter->data); this_item->getSnappoints(p, &snapprefs_dummy); //Include the transformation origin for snapping - //For a selection or group only the overall origin is considered + //For a selection or group only the overall center is considered, not for each item individually if (snapprefs != NULL && snapprefs->isTargetSnappable(Inkscape::SNAPTARGET_ROTATION_CENTER)) { p.push_back(Inkscape::SnapCandidatePoint(this_item->getCenter(), SNAPSOURCE_ROTATION_CENTER)); } @@ -460,36 +458,6 @@ std::vector<Inkscape::SnapCandidatePoint> Selection::getSnapPoints(SnapPreferenc return p; } -// TODO: both getSnapPoints and getSnapPointsConvexHull are called, subsequently. Can we do this more efficient? -// Why do we need to include the transformation center in one case and not the other? -std::vector<Inkscape::SnapCandidatePoint> Selection::getSnapPointsConvexHull(SnapPreferences const *snapprefs) const { - GSList const *items = const_cast<Selection *>(this)->itemList(); - - SnapPreferences snapprefs_dummy = *snapprefs; // create a local copy of the snapping prefs - snapprefs_dummy.setTargetSnappable(Inkscape::SNAPTARGET_NODE_CUSP, true); // consider any type of nodes as a snap source - snapprefs_dummy.setTargetSnappable(Inkscape::SNAPTARGET_NODE_SMOOTH, true); // i.e. disregard the smooth / cusp node preference - - std::vector<Inkscape::SnapCandidatePoint> p; - for (GSList const *iter = items; iter != NULL; iter = iter->next) { - SP_ITEM(iter->data)->getSnappoints(p, &snapprefs_dummy); - } - - std::vector<Inkscape::SnapCandidatePoint> pHull; - if (!p.empty()) { - Geom::Rect cvh((p.front()).getPoint(), (p.front()).getPoint()); - for (std::vector<Inkscape::SnapCandidatePoint>::iterator i = p.begin(); i != p.end(); ++i) { - // these are the points we get back - cvh.expandTo((*i).getPoint()); - } - - for ( unsigned i = 0 ; i < 4 ; ++i ) { - pHull.push_back(Inkscape::SnapCandidatePoint(cvh.corner(i), SNAPSOURCE_CONVEX_HULL_CORNER)); - } - } - - return pHull; -} - void Selection::_removeObjectDescendants(SPObject *obj) { GSList *iter, *next; for ( iter = _objs ; iter ; iter = next ) { diff --git a/src/selection.h b/src/selection.h index 168c70dd4..85e06a5c6 100644 --- a/src/selection.h +++ b/src/selection.h @@ -267,12 +267,6 @@ public: std::vector<Inkscape::SnapCandidatePoint> getSnapPoints(SnapPreferences const *snapprefs) const; /** - * Gets the snap points of a selection that form a convex hull. - * @return Selection's convex hull points - */ - std::vector<Inkscape::SnapCandidatePoint> getSnapPointsConvexHull(SnapPreferences const *snapprefs) const; - - /** * Connects a slot to be notified of selection changes. * * This method connects the given slot such that it will diff --git a/src/seltrans.cpp b/src/seltrans.cpp index 15cea9198..64bb95508 100644 --- a/src/seltrans.cpp +++ b/src/seltrans.cpp @@ -298,30 +298,21 @@ void Inkscape::SelTrans::grab(Geom::Point const &p, gdouble x, gdouble y, bool s // Next, get all points to consider for snapping SnapManager const &m = _desktop->namedview->snap_manager; _snap_points.clear(); - _snap_points = selection->getSnapPoints(&m.snapprefs); - std::vector<Inkscape::SnapCandidatePoint> snap_points_hull = selection->getSnapPointsConvexHull(&m.snapprefs); + if (m.someSnapperMightSnap(false)) { // Only search for snap sources when really needed, to avoid unnecessary delays + _snap_points = selection->getSnapPoints(&m.snapprefs); // This might take some time! + } if (_snap_points.size() > 200 && !(prefs->getBool("/options/snapclosestonly/value", false))) { /* Snapping a huge number of nodes will take way too long, so limit the number of snappable nodes A typical user would rarely ever try to snap such a large number of nodes anyway, because (s)he would hardly be able to discern which node would be snapping */ - _snap_points = snap_points_hull; - //} + _snap_points.resize(200); // Unfortunately, by now we will have lost the font-baseline snappoints :-( } // Find bbox hulling all special points, which excludes stroke width. Here we need to include the // path nodes, for example because a rectangle which has been converted to a path doesn't have // any other special points - Geom::Rect snap_points_bbox; - if ( snap_points_hull.empty() == false ) { - std::vector<Inkscape::SnapCandidatePoint>::iterator i = snap_points_hull.begin(); - snap_points_bbox = Geom::Rect((*i).getPoint(), (*i).getPoint()); - i++; - while (i != snap_points_hull.end()) { - snap_points_bbox.expandTo((*i).getPoint()); - i++; - } - } + Geom::OptRect snap_points_bbox = selection->bounds(SPItem::GEOMETRIC_BBOX); _bbox_points.clear(); // Collect the bounding box's corners and midpoints for each selected item @@ -329,11 +320,8 @@ void Inkscape::SelTrans::grab(Geom::Point const &p, gdouble x, gdouble y, bool s bool c = m.snapprefs.isTargetSnappable(SNAPTARGET_BBOX_CORNER); bool mp = m.snapprefs.isTargetSnappable(SNAPTARGET_BBOX_MIDPOINT); bool emp = m.snapprefs.isTargetSnappable(SNAPTARGET_BBOX_EDGE_MIDPOINT); - // 1) Preferably we'd use the bbox of each selected item, instead of the bbox of the selection as a whole; for translations - // this is easy to do, but when snapping the visual bbox while scaling we will have to compensate for the scaling of the - // stroke width. (see get_scale_transform_for_stroke()). This however is currently only implemented for a single bbox. - // 2) More than 50 items will produce at least 200 bbox points, which might make Inkscape crawl - // (see the comment a few lines above). In that case we will use the bbox of the selection as a whole + // Preferably we'd use the bbox of each selected item, but for example 50 items will produce at least 200 bbox points, + // which might make Inkscape crawl(see the comment a few lines above). In that case we will use the bbox of the selection as a whole bool c1 = (_items.size() > 0) && (_items.size() < 50); bool c2 = prefs->getBool("/options/snapclosestonly/value", false); if (translating && (c1 || c2)) { @@ -353,10 +341,14 @@ void Inkscape::SelTrans::grab(Geom::Point const &p, gdouble x, gdouble y, bool s // - one for snapping the boundingbox, which can be either visual or geometric // - one for snapping the special points // The "opposite" in case of a geometric boundingbox always coincides with the "opposite" for the special points - // These distinct "opposites" are needed in the snapmanager to avoid bugs such as #sf1540195 (in which + // These distinct "opposites" are needed in the snapmanager to avoid bugs such as LP167905 (in which // a box is caught between two guides) _opposite_for_bboxpoints = _bbox->min() + _bbox->dimensions() * Geom::Scale(1-x, 1-y); - _opposite_for_specpoints = snap_points_bbox.min() + snap_points_bbox.dimensions() * Geom::Scale(1-x, 1-y); + if (snap_points_bbox) { + _opposite_for_specpoints = (*snap_points_bbox).min() + (*snap_points_bbox).dimensions() * Geom::Scale(1-x, 1-y); + } else { + _opposite_for_specpoints = _opposite_for_bboxpoints; + } _opposite = _opposite_for_bboxpoints; } diff --git a/src/snap-candidate.h b/src/snap-candidate.h index da65d4ea3..8bb7cb52f 100644 --- a/src/snap-candidate.h +++ b/src/snap-candidate.h @@ -25,6 +25,8 @@ namespace Inkscape { class SnapCandidatePoint { public: + SnapCandidatePoint() {}; // only needed / used for resizing() of a vector in seltrans.cpp; do not use uninitialized instances! + SnapCandidatePoint(Geom::Point const &point, Inkscape::SnapSourceType const source, long const source_num, Inkscape::SnapTargetType const target, Geom::OptRect const &bbox) : _point(point), _source_type(source), @@ -39,7 +41,7 @@ public: : _point(point), _source_type(source), _target_type(target), - _target_bbox(Geom::OptRect()), + _target_bbox(Geom::OptRect()), _dist() { _source_num = -1; @@ -50,7 +52,7 @@ public: _source_type(source), _target_type(Inkscape::SNAPTARGET_UNDEFINED), _source_num(-1), - _target_bbox(Geom::OptRect()), + _target_bbox(Geom::OptRect()), _dist() { }; diff --git a/src/snap.cpp b/src/snap.cpp index 1ee55fcf8..695424194 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -77,9 +77,14 @@ SnapManager::SnapperList SnapManager::getGridSnappers() const return s; } -bool SnapManager::someSnapperMightSnap() const +bool SnapManager::someSnapperMightSnap(bool immediately) const { - if ( !snapprefs.getSnapEnabledGlobally() || snapprefs.getSnapPostponedGlobally() ) { + if ( !snapprefs.getSnapEnabledGlobally() ) { + return false; + } + + // If we're asking if some snapper might snap RIGHT NOW (without the snap being postponed)... + if ( immediately && snapprefs.getSnapPostponedGlobally() ) { return false; } diff --git a/src/snap.h b/src/snap.h index 3a8e18ad3..67af20063 100644 --- a/src/snap.h +++ b/src/snap.h @@ -93,7 +93,7 @@ public: * * @return true if one of the snappers will try to snap to something. */ - bool someSnapperMightSnap() const; + bool someSnapperMightSnap(bool immediately = true) const; /** * @return true if one of the grids might be snapped to. diff --git a/src/sp-item.cpp b/src/sp-item.cpp index 3ca7d5d16..363aa8c17 100644 --- a/src/sp-item.cpp +++ b/src/sp-item.cpp @@ -1514,8 +1514,6 @@ Geom::Affine SPItem::i2dt_affine() const ret = i2doc_affine() * Geom::Scale(1, -1) * Geom::Translate(0, document->getHeight()); - - g_return_val_if_fail(desktop != NULL, ret); } return ret; } diff --git a/src/sp-pattern.cpp b/src/sp-pattern.cpp index 19c0180a7..137864101 100644 --- a/src/sp-pattern.cpp +++ b/src/sp-pattern.cpp @@ -608,8 +608,7 @@ sp_pattern_create_pattern(SPPaintServer *ps, double opacity) { SPPattern *pat = SP_PATTERN (ps); - Geom::Affine ps2user; - Geom::Affine vb2ps = Geom::identity(); + bool needs_opacity = (1.0 - opacity) >= 1e-3; bool visible = opacity >= 1e-3; @@ -646,6 +645,8 @@ sp_pattern_create_pattern(SPPaintServer *ps, } } + // viewBox to pattern server + Geom::Affine vb2ps = Geom::identity(); if (pat->viewBox_set) { Geom::Rect vb = *pattern_viewBox(pat); gdouble tmp_x = pattern_width (pat) / vb.width(); @@ -655,6 +656,11 @@ sp_pattern_create_pattern(SPPaintServer *ps, vb2ps = Geom::Affine(tmp_x, 0.0, 0.0, tmp_y, pattern_x(pat) - vb.left() * tmp_x, pattern_y(pat) - vb.top() * tmp_y); } + // We must determine the size and scaling of the pattern at the time it is displayed and render + // the pattern onto a surface with that size and at that resolution. + + // Pattern server to user + Geom::Affine ps2user; ps2user = pattern_patternTransform(pat); if (!pat->viewBox_set && pattern_patternContentUnits (pat) == SP_PATTERN_UNITS_OBJECTBOUNDINGBOX) { /* BBox to user coordinate system */ @@ -663,6 +669,7 @@ sp_pattern_create_pattern(SPPaintServer *ps, } ps2user = Geom::Translate (pattern_x (pat), pattern_y (pat)) * ps2user; + // Pattern size in pattern space Geom::Rect pattern_tile = Geom::Rect::from_xywh(pattern_x(pat), pattern_y(pat), pattern_width(pat), pattern_height(pat)); @@ -672,22 +679,34 @@ sp_pattern_create_pattern(SPPaintServer *ps, pattern_tile = pattern_tile * bbox2user; } + // Transform of object with pattern (includes screen scaling) cairo_matrix_t cm; cairo_get_matrix(base_ct, &cm); Geom::Affine full(cm.xx, cm.yx, cm.xy, cm.yy, 0, 0); + // The DrawingSurface class is suppose to handle the mapping from "logical space" + // (coordinates in the rendering) to "physical space" (surface pixels). + // An oversampling is done as the pattern may not pixel align with the final surface. + // The cairo surface is created when the DrawingContext is declared. + // oversample the pattern slightly // TODO: find optimum value // TODO: this is lame. instead of using descrim(), we should extract // the scaling component from the complete matrix and use it // to find the optimum tile size for rendering + // c is number of pixels in buffer x and y. Geom::Point c(pattern_tile.dimensions()*vb2ps.descrim()*ps2user.descrim()*full.descrim()*1.1); + c[Geom::X] = ceil(c[Geom::X]); c[Geom::Y] = ceil(c[Geom::Y]); - + + // Create drawing surface with size of pattern tile (in tile space) but with number of pixels + // based on required resolution (c). + Inkscape::DrawingSurface pattern_surface(pattern_tile, c.ceil()); + Inkscape::DrawingContext ct(pattern_surface); + + pattern_tile *= pattern_surface.drawingTransform(); Geom::IntRect one_tile = pattern_tile.roundOutwards(); - Inkscape::DrawingSurface temp(pattern_tile, c.ceil()); - Inkscape::DrawingContext ct(temp); // render pattern. if (needs_opacity) { @@ -695,9 +714,13 @@ sp_pattern_create_pattern(SPPaintServer *ps, } // TODO: make sure there are no leaks. - Inkscape::UpdateContext ctx; - ctx.ctm = vb2ps; + Inkscape::UpdateContext ctx; // UpdateContext is structure with only ctm! + ctx.ctm = vb2ps * pattern_surface.drawingTransform(); + ct.transform( pattern_surface.drawingTransform().inverse() ); drawing.update(Geom::IntRect::infinite(), ctx); + + // Render drawing to pattern_surface via drawing context, this calls root->render + // which is really DrawingItem->render(). drawing.render(ct, one_tile); for (SPObject *child = shown->firstChild() ; child != NULL; child = child->getNext() ) { if (SP_IS_ITEM (child)) { @@ -705,15 +728,23 @@ sp_pattern_create_pattern(SPPaintServer *ps, } } + // Uncomment to debug + // cairo_surface_t* raw = pattern_surface.raw(); + // std::cout << " cairo_surface (sp-pattern): " + // << " width: " << cairo_image_surface_get_width( raw ) + // << " height: " << cairo_image_surface_get_height( raw ) + // << std::endl; + // cairo_surface_write_to_png( pattern_surface.raw(), "sp-pattern.png" ); + if (needs_opacity) { ct.popGroupToSource(); // pop raw pattern ct.paint(opacity); // apply opacity } - cairo_pattern_t *cp = cairo_pattern_create_for_surface(temp.raw()); - + cairo_pattern_t *cp = cairo_pattern_create_for_surface(pattern_surface.raw()); // Apply transformation to user space. Also compensate for oversampling. - ink_cairo_pattern_set_matrix(cp, ps2user.inverse() * temp.drawingTransform()); + ink_cairo_pattern_set_matrix(cp, ps2user.inverse() * pattern_surface.drawingTransform()); + cairo_pattern_set_extend(cp, CAIRO_EXTEND_REPEAT); return cp; diff --git a/src/sp-shape.cpp b/src/sp-shape.cpp index ad73f226c..d5556ba9e 100644 --- a/src/sp-shape.cpp +++ b/src/sp-shape.cpp @@ -1193,10 +1193,10 @@ void SPShape::sp_shape_snappoints(SPItem const *item, std::vector<Inkscape::Snap // Find the internal intersections of each path and consider these for snapping // (using "Method 1" as described in Inkscape::ObjectSnapper::_collectNodes()) - if (snapprefs->isTargetSnappable(Inkscape::SNAPTARGET_PATH_INTERSECTION)) { + if (snapprefs->isTargetSnappable(Inkscape::SNAPTARGET_PATH_INTERSECTION) || snapprefs->isSourceSnappable(Inkscape::SNAPSOURCE_PATH_INTERSECTION)) { Geom::Crossings cs; try { - cs = self_crossings(*path_it); + cs = self_crossings(*path_it); // This can be slow! if (!cs.empty()) { // There might be multiple intersections... for (Geom::Crossings::const_iterator i = cs.begin(); i != cs.end(); ++i) { Geom::Point p_ix = (*path_it).pointAt((*i).ta); diff --git a/src/ui/dialog/clonetiler.cpp b/src/ui/dialog/clonetiler.cpp index f51470826..e971cfb09 100644 --- a/src/ui/dialog/clonetiler.cpp +++ b/src/ui/dialog/clonetiler.cpp @@ -815,9 +815,15 @@ CloneTiler::CloneTiler (void) : GtkWidget *frame = gtk_frame_new (_("1. Pick from the drawing:")); gtk_box_pack_start (GTK_BOX (vvb), frame, FALSE, FALSE, 0); +#if GTK_CHECK_VERSION(3,0,0) + GtkWidget *table = gtk_grid_new(); + gtk_grid_set_row_spacing(GTK_GRID(table), 4); + gtk_grid_set_column_spacing(GTK_GRID(table), 6); +#else GtkWidget *table = gtk_table_new (3, 3, FALSE); gtk_table_set_row_spacings (GTK_TABLE (table), 4); gtk_table_set_col_spacings (GTK_TABLE (table), 6); +#endif gtk_container_add(GTK_CONTAINER(frame), table); @@ -893,9 +899,16 @@ CloneTiler::CloneTiler (void) : GtkWidget *frame = gtk_frame_new (_("2. Tweak the picked value:")); gtk_box_pack_start (GTK_BOX (vvb), frame, FALSE, FALSE, VB_MARGIN); +#if GTK_CHECK_VERSION(3,0,0) + GtkWidget *table = gtk_grid_new(); + gtk_grid_set_row_spacing(GTK_GRID(table), 4); + gtk_grid_set_column_spacing(GTK_GRID(table), 6); +#else GtkWidget *table = gtk_table_new (4, 2, FALSE); gtk_table_set_row_spacings (GTK_TABLE (table), 4); gtk_table_set_col_spacings (GTK_TABLE (table), 6); +#endif + gtk_container_add(GTK_CONTAINER(frame), table); { @@ -935,10 +948,15 @@ CloneTiler::CloneTiler (void) : GtkWidget *frame = gtk_frame_new (_("3. Apply the value to the clones':")); gtk_box_pack_start (GTK_BOX (vvb), frame, FALSE, FALSE, 0); - +#if GTK_CHECK_VERSION(3,0,0) + GtkWidget *table = gtk_grid_new(); + gtk_grid_set_row_spacing(GTK_GRID(table), 4); + gtk_grid_set_column_spacing(GTK_GRID(table), 6); +#else GtkWidget *table = gtk_table_new (2, 2, FALSE); gtk_table_set_row_spacings (GTK_TABLE (table), 4); gtk_table_set_col_spacings (GTK_TABLE (table), 6); +#endif gtk_container_add(GTK_CONTAINER(frame), table); { @@ -987,10 +1005,17 @@ CloneTiler::CloneTiler (void) : // Rows/columns, width/height { +#if GTK_CHECK_VERSION(3,0,0) + GtkWidget *table = gtk_grid_new(); + gtk_grid_set_row_spacing(GTK_GRID(table), 4); + gtk_grid_set_column_spacing(GTK_GRID(table), 6); +#else GtkWidget *table = gtk_table_new (2, 2, FALSE); - gtk_container_set_border_width (GTK_CONTAINER (table), VB_MARGIN); gtk_table_set_row_spacings (GTK_TABLE (table), 4); gtk_table_set_col_spacings (GTK_TABLE (table), 6); +#endif + + gtk_container_set_border_width (GTK_CONTAINER (table), VB_MARGIN); gtk_box_pack_start (GTK_BOX (mainbox), table, FALSE, FALSE, 0); { @@ -2807,15 +2832,29 @@ void CloneTiler::clonetiler_table_attach(GtkWidget *table, GtkWidget *widget, fl { GtkWidget *a = gtk_alignment_new (align, 0, 0, 0); gtk_container_add(GTK_CONTAINER(a), widget); - gtk_table_attach ( GTK_TABLE (table), a, col, col + 1, row, row + 1, (GtkAttachOptions)4, (GtkAttachOptions)0, 0, 0 ); + +#if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_halign(table, GTK_ALIGN_FILL); + gtk_widget_set_valign(table, GTK_ALIGN_CENTER); + gtk_grid_attach(GTK_GRID(table), a, col, row, 1, 1); +#else + gtk_table_attach ( GTK_TABLE (table), a, col, col + 1, row, row + 1, GTK_FILL, (GtkAttachOptions)0, 0, 0 ); +#endif } GtkWidget * CloneTiler::clonetiler_table_x_y_rand(int values) { +#if GTK_CHECK_VERSION(3,0,0) + GtkWidget *table = gtk_grid_new(); + gtk_grid_set_row_spacing(GTK_GRID(table), 6); + gtk_grid_set_column_spacing(GTK_GRID(table), 8); +#else GtkWidget *table = gtk_table_new (values + 2, 5, FALSE); - gtk_container_set_border_width (GTK_CONTAINER (table), VB_MARGIN); gtk_table_set_row_spacings (GTK_TABLE (table), 6); gtk_table_set_col_spacings (GTK_TABLE (table), 8); +#endif + + gtk_container_set_border_width (GTK_CONTAINER (table), VB_MARGIN); { #if GTK_CHECK_VERSION(3,0,0) diff --git a/src/ui/dialog/document-metadata.cpp b/src/ui/dialog/document-metadata.cpp index 6318ffbbb..efe25d843 100644 --- a/src/ui/dialog/document-metadata.cpp +++ b/src/ui/dialog/document-metadata.cpp @@ -61,13 +61,30 @@ DocumentMetadata::getInstance() DocumentMetadata::DocumentMetadata() +#if WITH_GTKMM_3_0 + : UI::Widget::Panel ("", "/dialogs/documentmetadata", SP_VERB_DIALOG_METADATA) +#else : UI::Widget::Panel ("", "/dialogs/documentmetadata", SP_VERB_DIALOG_METADATA), _page_metadata1(1, 1), _page_metadata2(1, 1) +#endif { hide(); _getContents()->set_spacing (4); _getContents()->pack_start(_notebook, true, true); + _page_metadata1.set_border_width(2); + _page_metadata2.set_border_width(2); + +#if WITH_GTKMM_3_0 + _page_metadata1.set_column_spacing(2); + _page_metadata2.set_column_spacing(2); + _page_metadata1.set_row_spacing(2); + _page_metadata2.set_row_spacing(2); +#else + _page_metadata1.set_spacings(2); + _page_metadata2.set_spacings(2); +#endif + _notebook.append_page(_page_metadata1, _("Metadata")); _notebook.append_page(_page_metadata2, _("License")); @@ -98,50 +115,6 @@ DocumentMetadata::~DocumentMetadata() delete (*it); } -//======================================================================== - -/** - * Helper function that attachs widgets in a 3xn table. The widgets come in an - * array that has two entries per table row. The two entries code for four - * possible cases: (0,0) means insert space in first column; (0, non-0) means - * widget in columns 2-3; (non-0, 0) means label in columns 1-3; and - * (non-0, non-0) means two widgets in columns 2 and 3. - */ -inline void attach_all(Gtk::Table &table, const Gtk::Widget *arr[], unsigned size, int start = 0) -{ - for (unsigned i=0, r=start; i<size/sizeof(Gtk::Widget*); i+=2) - { - if (arr[i] && arr[i+1]) - { - table.attach (const_cast<Gtk::Widget&>(*arr[i]), 1, 2, r, r+1, - Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0,0,0); - table.attach (const_cast<Gtk::Widget&>(*arr[i+1]), 2, 3, r, r+1, - Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0,0,0); - } - else - { - if (arr[i+1]) - table.attach (const_cast<Gtk::Widget&>(*arr[i+1]), 1, 3, r, r+1, - Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0,0,0); - else if (arr[i]) - { - Gtk::Label& label = static_cast<Gtk::Label&> (const_cast<Gtk::Widget&>(*arr[i])); - label.set_alignment (0.0); - table.attach (label, 0, 3, r, r+1, - Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0,0,0); - } - else - { - Gtk::HBox *space = manage (new Gtk::HBox); - space->set_size_request (SPACE_SIZE_X, SPACE_SIZE_Y); - table.attach (*space, 0, 1, r, r+1, - (Gtk::AttachOptions)0, (Gtk::AttachOptions)0,0,0); - } - } - ++r; - } -} - void DocumentMetadata::build_metadata() { @@ -152,7 +125,14 @@ DocumentMetadata::build_metadata() Gtk::Label *label = manage (new Gtk::Label); label->set_markup (_("<b>Dublin Core Entities</b>")); label->set_alignment (0.0); - _page_metadata1.table().attach (*label, 0,3,0,1, Gtk::FILL, (Gtk::AttachOptions)0,0,0); + +#if WITH_GTKMM_3_0 + label->set_valign(Gtk::ALIGN_CENTER); + _page_metadata1.attach(*label, 0, 0, 3, 1); +#else + _page_metadata1.attach(*label, 0,3,0,1, Gtk::FILL, (Gtk::AttachOptions)0,0,0); +#endif + /* add generic metadata entry areas */ struct rdf_work_entity_t * entity; int row = 1; @@ -162,9 +142,22 @@ DocumentMetadata::build_metadata() _rdflist.push_back (w); Gtk::HBox *space = manage (new Gtk::HBox); space->set_size_request (SPACE_SIZE_X, SPACE_SIZE_Y); - _page_metadata1.table().attach (*space, 0,1, row, row+1, Gtk::FILL, (Gtk::AttachOptions)0,0,0); - _page_metadata1.table().attach (w->_label, 1,2, row, row+1, Gtk::FILL, (Gtk::AttachOptions)0,0,0); - _page_metadata1.table().attach (*w->_packable, 2,3, row, row+1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0,0,0); + +#if WITH_GTKMM_3_0 + space->set_valign(Gtk::ALIGN_CENTER); + _page_metadata1.attach(*space, 0, row, 1, 1); + + w->_label.set_valign(Gtk::ALIGN_CENTER); + _page_metadata1.attach(w->_label, 1, row, 1, 1); + + w->_packable->set_hexpand(); + w->_packable->set_valign(Gtk::ALIGN_CENTER); + _page_metadata1.attach(*w->_packable, 2, row, 1, 1); +#else + _page_metadata1.attach(*space, 0,1, row, row+1, Gtk::FILL, (Gtk::AttachOptions)0,0,0); + _page_metadata1.attach(w->_label, 1,2, row, row+1, Gtk::FILL, (Gtk::AttachOptions)0,0,0); + _page_metadata1.attach(*w->_packable, 2,3, row, row+1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0,0,0); +#endif } } @@ -174,14 +167,31 @@ DocumentMetadata::build_metadata() Gtk::Label *llabel = manage (new Gtk::Label); llabel->set_markup (_("<b>License</b>")); llabel->set_alignment (0.0); - _page_metadata2.table().attach (*llabel, 0,3, row, row+1, Gtk::FILL, (Gtk::AttachOptions)0,0,0); + +#if WITH_GTKMM_3_0 + llabel->set_valign(Gtk::ALIGN_CENTER); + _page_metadata2.attach(*llabel, 0, row, 3, 1); +#else + _page_metadata2.attach(*llabel, 0,3, row, row+1, Gtk::FILL, (Gtk::AttachOptions)0,0,0); +#endif + /* add license selector pull-down and URI */ ++row; _licensor.init (_wr); Gtk::HBox *space = manage (new Gtk::HBox); space->set_size_request (SPACE_SIZE_X, SPACE_SIZE_Y); - _page_metadata2.table().attach (*space, 0,1, row, row+1, Gtk::FILL, (Gtk::AttachOptions)0,0,0); - _page_metadata2.table().attach (_licensor, 1,3, row, row+1, Gtk::EXPAND|Gtk::FILL, (Gtk::AttachOptions)0,0,0); + +#if WITH_GTKMM_3_0 + space->set_valign(Gtk::ALIGN_CENTER); + _page_metadata2.attach(*space, 0, row, 1, 1); + + _licensor.set_hexpand(); + _licensor.set_valign(Gtk::ALIGN_CENTER); + _page_metadata2.attach(_licensor, 1, row, 2, 1); +#else + _page_metadata2.attach(*space, 0,1, row, row+1, Gtk::FILL, (Gtk::AttachOptions)0,0,0); + _page_metadata2.attach(_licensor, 1,3, row, row+1, Gtk::EXPAND|Gtk::FILL, (Gtk::AttachOptions)0,0,0); +#endif } /** diff --git a/src/ui/dialog/document-metadata.h b/src/ui/dialog/document-metadata.h index f201679b5..3b7ed1ec8 100644 --- a/src/ui/dialog/document-metadata.h +++ b/src/ui/dialog/document-metadata.h @@ -13,12 +13,22 @@ #ifndef INKSCAPE_UI_DIALOG_DOCUMENT_METADATA_H #define INKSCAPE_UI_DIALOG_DOCUMENT_METADATA_H +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + #include <list> #include <stddef.h> #include "ui/widget/panel.h" #include <gtkmm/notebook.h> + +#if WITH_GTKMM_3_0 +# include <gtkmm/grid.h> +#else +# include <gtkmm/table.h> +#endif + #include "ui/widget/licensor.h" -#include "ui/widget/notebook-page.h" #include "ui/widget/registry.h" namespace Inkscape { @@ -51,8 +61,13 @@ protected: Gtk::Notebook _notebook; - UI::Widget::NotebookPage _page_metadata1; - UI::Widget::NotebookPage _page_metadata2; +#if WITH_GTKMM_3_0 + Gtk::Grid _page_metadata1; + Gtk::Grid _page_metadata2; +#else + Gtk::Table _page_metadata1; + Gtk::Table _page_metadata2; +#endif //--------------------------------------------------------------- RDElist _rdflist; diff --git a/src/ui/dialog/guides.cpp b/src/ui/dialog/guides.cpp index d20f2a220..1f02002ca 100644 --- a/src/ui/dialog/guides.cpp +++ b/src/ui/dialog/guides.cpp @@ -168,30 +168,54 @@ void GuidelinePropertiesDialog::_setup() { Gtk::Box *mainVBox = get_vbox(); +#if WITH_GTKMM_3_0 + _layout_table.set_row_spacing(4); + _layout_table.set_column_spacing(4); +#else _layout_table.set_spacings(4); _layout_table.resize (3, 4); +#endif mainVBox->pack_start(_layout_table, false, false, 0); _label_name.set_label("foo0"); - _layout_table.attach(_label_name, - 0, 3, 0, 1, Gtk::FILL, Gtk::FILL); _label_name.set_alignment(0, 0.5); _label_descr.set_label("foo1"); - _layout_table.attach(_label_descr, - 0, 3, 1, 2, Gtk::FILL, Gtk::FILL); _label_descr.set_alignment(0, 0.5); + +#if WITH_GTKMM_3_0 + _label_name.set_halign(Gtk::ALIGN_FILL); + _label_name.set_valign(Gtk::ALIGN_FILL); + _layout_table.attach(_label_name, 0, 0, 3, 1); + + _label_descr.set_halign(Gtk::ALIGN_FILL); + _label_descr.set_valign(Gtk::ALIGN_FILL); + _layout_table.attach(_label_descr, 0, 1, 3, 1); + + _label_entry.set_halign(Gtk::ALIGN_FILL); + _label_entry.set_valign(Gtk::ALIGN_FILL); + _label_entry.set_hexpand(); + _layout_table.attach(_label_entry, 1, 2, 2, 1); + + _color.set_halign(Gtk::ALIGN_FILL); + _color.set_valign(Gtk::ALIGN_FILL); + _color.set_hexpand(); + _layout_table.attach(_color, 1, 3, 2, 1); +#else + _layout_table.attach(_label_name, + 0, 3, 0, 1, Gtk::FILL, Gtk::FILL); - // indent -// _layout_table.attach(*manage(new Gtk::Label(" ")), -// 0, 1, 2, 3, Gtk::FILL, Gtk::FILL, 10); + _layout_table.attach(_label_descr, + 0, 3, 1, 2, Gtk::FILL, Gtk::FILL); _layout_table.attach(_label_entry, 1, 3, 2, 3, Gtk::EXPAND | Gtk::FILL, Gtk::FILL); _layout_table.attach(_color, 1, 3, 3, 4, Gtk::EXPAND | Gtk::FILL, Gtk::FILL); +#endif + _color.signal_color_set().connect(sigc::mem_fun(*this, &GuidelinePropertiesDialog::_colorChanged)); @@ -211,6 +235,22 @@ void GuidelinePropertiesDialog::_setup() { _spin_button_y.setDigits(3); _spin_button_y.setIncrements(1.0, 10.0); _spin_button_y.setRange(-1e6, 1e6); + +#if WITH_GTKMM_3_0 + _spin_button_x.set_halign(Gtk::ALIGN_FILL); + _spin_button_x.set_valign(Gtk::ALIGN_FILL); + _spin_button_x.set_hexpand(); + _layout_table.attach(_spin_button_x, 1, 4, 1, 1); + + _spin_button_y.set_halign(Gtk::ALIGN_FILL); + _spin_button_y.set_valign(Gtk::ALIGN_FILL); + _spin_button_y.set_hexpand(); + _layout_table.attach(_spin_button_y, 1, 5, 1, 1); + + _unit_menu.set_halign(Gtk::ALIGN_FILL); + _unit_menu.set_valign(Gtk::ALIGN_FILL); + _layout_table.attach(_unit_menu, 2, 4, 1, 1); +#else _layout_table.attach(_spin_button_x, 1, 2, 4, 5, Gtk::EXPAND | Gtk::FILL, Gtk::FILL); _layout_table.attach(_spin_button_y, @@ -218,17 +258,33 @@ void GuidelinePropertiesDialog::_setup() { _layout_table.attach(_unit_menu, 2, 3, 4, 5, Gtk::FILL, Gtk::FILL); +#endif // angle spinbutton _spin_angle.setDigits(3); _spin_angle.setIncrements(1.0, 10.0); _spin_angle.setRange(-3600., 3600.); + +#if WITH_GTKMM_3_0 + _spin_angle.set_halign(Gtk::ALIGN_FILL); + _spin_angle.set_valign(Gtk::ALIGN_FILL); + _spin_angle.set_hexpand(); + _layout_table.attach(_spin_angle, 1, 6, 2, 1); + + // mode radio button + _relative_toggle.set_halign(Gtk::ALIGN_FILL); + _relative_toggle.set_valign(Gtk::ALIGN_FILL); + _relative_toggle.set_hexpand(); + _layout_table.attach(_relative_toggle, 1, 7, 2, 1); +#else _layout_table.attach(_spin_angle, 1, 3, 6, 7, Gtk::EXPAND | Gtk::FILL, Gtk::FILL); // mode radio button _layout_table.attach(_relative_toggle, 1, 3, 7, 8, Gtk::EXPAND | Gtk::FILL, Gtk::FILL); +#endif + _relative_toggle.signal_toggled().connect(sigc::mem_fun(*this, &GuidelinePropertiesDialog::_modeChanged)); _relative_toggle.set_active(_relative_toggle_status); diff --git a/src/ui/dialog/guides.h b/src/ui/dialog/guides.h index d06c3afc8..a15667152 100644 --- a/src/ui/dialog/guides.h +++ b/src/ui/dialog/guides.h @@ -11,8 +11,18 @@ #ifndef INKSCAPE_DIALOG_GUIDELINE_H #define INKSCAPE_DIALOG_GUIDELINE_H +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + #include <gtkmm/dialog.h> + +#if WITH_GTKMM_3_0 +#include <gtkmm/grid.h> +#else #include <gtkmm/table.h> +#endif + #include <gtkmm/label.h> #include <gtkmm/colorbutton.h> #include "ui/widget/button.h" @@ -62,7 +72,13 @@ private: SPDesktop *_desktop; SPGuide *_guide; + +#if WITH_GTKMM_3_0 + Gtk::Grid _layout_table; +#else Gtk::Table _layout_table; +#endif + Gtk::Label _label_name; Gtk::Label _label_descr; Inkscape::UI::Widget::CheckButton _relative_toggle; diff --git a/src/ui/dialog/input.cpp b/src/ui/dialog/input.cpp index 7e2b0a1e1..4c567a6e3 100644 --- a/src/ui/dialog/input.cpp +++ b/src/ui/dialog/input.cpp @@ -357,6 +357,15 @@ static std::map<Gdk::InputMode, Glib::ustring> &getModeToString() return mapping; } +static int getModeId(Gdk::InputMode im) +{ + if (im == Gdk::MODE_DISABLED) return 0; + if (im == Gdk::MODE_SCREEN) return 1; + if (im == Gdk::MODE_WINDOW) return 2; + + return 0; +} + static std::map<Glib::ustring, Gdk::InputMode> &getStringToMode() { static std::map<Glib::ustring, Gdk::InputMode> mapping; @@ -400,15 +409,59 @@ private: static void setCellStateToggle(Gtk::CellRenderer *rndr, Gtk::TreeIter const &iter); void saveSettings(); + void onTreeSelect(); void useExtToggled(); - Glib::RefPtr<Gtk::TreeStore> store; - Gtk::TreeIter tabletIter; - Gtk::TreeView tree; - Gtk::ScrolledWindow treeScroller; + void onModeChange(); + void setKeys(gint count); + void setAxis(gint count); + + Glib::RefPtr<Gtk::TreeStore> confDeviceStore; + Gtk::TreeIter confDeviceIter; + Gtk::TreeView confDeviceTree; + Gtk::ScrolledWindow confDeviceScroller; Blink watcher; Gtk::CheckButton useExt; Gtk::Button save; + + Gtk::HPaned pane; + Gtk::VBox detailsBox; + Gtk::HBox titleFrame; + Gtk::Label titleLabel; + Inkscape::UI::Widget::Frame axisFrame; + Inkscape::UI::Widget::Frame keysFrame; + Gtk::VBox axisVBox; + Gtk::ComboBoxText modeCombo; + Gtk::Label modeLabel; + Gtk::HBox modeBox; + + class KeysColumns : public Gtk::TreeModel::ColumnRecord + { + public: + KeysColumns() + { + add(name); + add(value); + } + virtual ~KeysColumns() {} + + Gtk::TreeModelColumn<Glib::ustring> name; + Gtk::TreeModelColumn<Glib::ustring> value; + }; + + KeysColumns keysColumns; + KeysColumns axisColumns; + + Glib::RefPtr<Gtk::ListStore> axisStore; + Gtk::TreeView axisTree; + Gtk::ScrolledWindow axisScroll; + + Glib::RefPtr<Gtk::ListStore> keysStore; + Gtk::TreeView keysTree; + Gtk::ScrolledWindow keysScroll; + Gtk::CellRendererAccel _kb_shortcut_renderer; + + }; static DeviceModelColumns &getCols(); @@ -425,11 +478,11 @@ private: GdkInputSource lastSourceSeen; Glib::ustring lastDevnameSeen; - Glib::RefPtr<Gtk::TreeStore> store; - Gtk::TreeIter tabletIter; - Gtk::TreeView tree; - Inkscape::UI::Widget::Frame detailFrame; + Glib::RefPtr<Gtk::TreeStore> deviceStore; + Gtk::TreeIter deviceIter; + Gtk::TreeView deviceTree; Inkscape::UI::Widget::Frame testFrame; + Inkscape::UI::Widget::Frame axisFrame; Gtk::ScrolledWindow treeScroller; Gtk::ScrolledWindow detailScroller; Gtk::HPaned splitter; @@ -439,12 +492,13 @@ private: Gtk::Label devAxesCount; Gtk::ComboBoxText axesCombo; Gtk::ProgressBar axesValues[6]; + Gtk::Table axisTable; + Gtk::ComboBoxText buttonCombo; Gtk::ComboBoxText linkCombo; sigc::connection linkConnection; Gtk::Label keyVal; Gtk::Entry keyEntry; - Gtk::Table devDetails; Gtk::Notebook topHolder; Gtk::Image testThumb; Gtk::Image testButtons[24]; @@ -454,6 +508,7 @@ private: ConfPanel cfgPanel; + static void setupTree( Glib::RefPtr<Gtk::TreeStore> store, Gtk::TreeIter &tablet ); void setupValueAndCombo( gint reported, gint actual, Gtk::Label& label, Gtk::ComboBoxText& combo ); void updateTestButtons( Glib::ustring const& key, gint hotButton ); @@ -526,17 +581,17 @@ InputDialogImpl::InputDialogImpl() : lastSourceSeen((GdkInputSource)-1), lastDevnameSeen(""), - store(Gtk::TreeStore::create(getCols())), - tabletIter(), - tree(store), - detailFrame(), + deviceStore(Gtk::TreeStore::create(getCols())), + deviceIter(), + deviceTree(deviceStore), testFrame(_("Test Area")), + axisFrame(_("Axis")), treeScroller(), detailScroller(), splitter(), split2(), + axisTable(11, 2), linkCombo(), - devDetails(12, 2), topHolder(), imageTable(8, 7), testDetector(), @@ -547,10 +602,12 @@ InputDialogImpl::InputDialogImpl() : treeScroller.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); treeScroller.set_shadow_type(Gtk::SHADOW_IN); - treeScroller.add(tree); + treeScroller.add(deviceTree); treeScroller.set_size_request(50, 0); - split2.pack1(testFrame, false, false); - split2.pack2(detailFrame, true, true); + + split2.pack1(axisFrame, false, false); + split2.pack2(testFrame, true, true); + splitter.pack1(treeScroller); splitter.pack2(split2); @@ -585,27 +642,35 @@ InputDialogImpl::InputDialogImpl() : } - topHolder.append_page(cfgPanel, _("Configuration")); - topHolder.append_page(splitter, _("Hardware")); - topHolder.show_all(); - topHolder.set_current_page(0); + // This is a hidden preference to enable the "hardware" details in a separate tab + // By default this is not available to users + if (Preferences::get()->getBool("/dialogs/inputdevices/test")) { + topHolder.append_page(cfgPanel, _("Configuration")); + topHolder.append_page(splitter, _("Hardware")); + topHolder.show_all(); + topHolder.set_current_page(0); + contents->pack_start(topHolder); + } else { + contents->pack_start(cfgPanel); + } - contents->pack_start(topHolder); int rowNum = 0; /* Gtk::Label* lbl = Gtk::manage(new Gtk::Label(_("Name:"))); - devDetails.attach(*lbl, 0, 1, rowNum, rowNum+ 1, + axisTable.attach(*lbl, 0, 1, rowNum, rowNum+ 1, ::Gtk::FILL, ::Gtk::SHRINK); - devDetails.attach(devName, 1, 2, rowNum, rowNum + 1, + axisTable.attach(devName, 1, 2, rowNum, rowNum + 1, ::Gtk::SHRINK, ::Gtk::SHRINK); rowNum++;*/ + axisFrame.add(axisTable); + Gtk::Label *lbl = Gtk::manage(new Gtk::Label(_("Link:"))); - devDetails.attach(*lbl, 0, 1, rowNum, rowNum+ 1, + axisTable.attach(*lbl, 0, 1, rowNum, rowNum+ 1, ::Gtk::FILL, ::Gtk::SHRINK); @@ -614,21 +679,23 @@ InputDialogImpl::InputDialogImpl() : linkCombo.set_sensitive(false); linkConnection = linkCombo.signal_changed().connect(sigc::mem_fun(*this, &InputDialogImpl::linkComboChanged)); - devDetails.attach(linkCombo, 1, 2, rowNum, rowNum + 1, + axisTable.attach(linkCombo, 1, 2, rowNum, rowNum + 1, ::Gtk::FILL, ::Gtk::SHRINK); rowNum++; + lbl = Gtk::manage(new Gtk::Label(_("Axes count:"))); - devDetails.attach(*lbl, 0, 1, rowNum, rowNum+ 1, + axisTable.attach(*lbl, 0, 1, rowNum, rowNum+ 1, ::Gtk::FILL, ::Gtk::SHRINK); - devDetails.attach(devAxesCount, 1, 2, rowNum, rowNum + 1, + axisTable.attach(devAxesCount, 1, 2, rowNum, rowNum + 1, ::Gtk::SHRINK, ::Gtk::SHRINK); rowNum++; + /* lbl = Gtk::manage(new Gtk::Label(_("Actual axes count:"))); devDetails.attach(*lbl, 0, 1, rowNum, rowNum+ 1, @@ -643,22 +710,24 @@ InputDialogImpl::InputDialogImpl() : for ( guint barNum = 0; barNum < static_cast<guint>(G_N_ELEMENTS(axesValues)); barNum++ ) { lbl = Gtk::manage(new Gtk::Label(_("axis:"))); - devDetails.attach(*lbl, 0, 1, rowNum, rowNum+ 1, - ::Gtk::FILL, + axisTable.attach(*lbl, 0, 1, rowNum, rowNum+ 1, + ::Gtk::EXPAND, ::Gtk::SHRINK); - devDetails.attach(axesValues[barNum], 1, 2, rowNum, rowNum + 1, + axisTable.attach(axesValues[barNum], 1, 2, rowNum, rowNum + 1, ::Gtk::EXPAND, ::Gtk::SHRINK); axesValues[barNum].set_sensitive(false); rowNum++; + + } lbl = Gtk::manage(new Gtk::Label(_("Button count:"))); - devDetails.attach(*lbl, 0, 1, rowNum, rowNum+ 1, + axisTable.attach(*lbl, 0, 1, rowNum, rowNum+ 1, ::Gtk::FILL, ::Gtk::SHRINK); - devDetails.attach(devKeyCount, 1, 2, rowNum, rowNum + 1, + axisTable.attach(devKeyCount, 1, 2, rowNum, rowNum + 1, ::Gtk::SHRINK, ::Gtk::SHRINK); @@ -676,7 +745,7 @@ InputDialogImpl::InputDialogImpl() : rowNum++; */ - devDetails.attach(keyVal, 0, 2, rowNum, rowNum + 1, + axisTable.attach(keyVal, 0, 2, rowNum, rowNum + 1, ::Gtk::FILL, ::Gtk::SHRINK); rowNum++; @@ -696,19 +765,18 @@ InputDialogImpl::InputDialogImpl() : #endif testDetector.add_events(Gdk::POINTER_MOTION_MASK|Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK |Gdk::PROXIMITY_IN_MASK|Gdk::PROXIMITY_OUT_MASK|Gdk::SCROLL_MASK); - devDetails.attach(keyEntry, 0, 2, rowNum, rowNum + 1, + axisTable.attach(keyEntry, 0, 2, rowNum, rowNum + 1, ::Gtk::FILL, ::Gtk::SHRINK); rowNum++; - devDetails.set_sensitive(false); - detailScroller.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); + axisTable.set_sensitive(false); + +/* detailScroller.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); detailScroller.set_shadow_type(Gtk::SHADOW_NONE); detailScroller.set_border_width (0); - detailScroller.add(devDetails); - detailFrame.add(detailScroller); - detailFrame.set_size_request(0, 60); + detailScroller.add(devDetails);*/ //- 16x16/devices // gnome-dev-mouse-optical @@ -717,25 +785,24 @@ InputDialogImpl::InputDialogImpl() : // mouse - //Add the TreeView's view columns: - tree.append_column("I", getCols().thumbnail); - tree.append_column("Bar", getCols().description); + deviceTree.append_column("I", getCols().thumbnail); + deviceTree.append_column("Bar", getCols().description); - tree.set_enable_tree_lines(); - tree.set_headers_visible(false); - tree.get_selection()->signal_changed().connect(sigc::mem_fun(*this, &InputDialogImpl::resyncToSelection)); + deviceTree.set_enable_tree_lines(); + deviceTree.set_headers_visible(false); + deviceTree.get_selection()->signal_changed().connect(sigc::mem_fun(*this, &InputDialogImpl::resyncToSelection)); - setupTree( store, tabletIter ); + setupTree( deviceStore, deviceIter ); Inkscape::DeviceManager::getManager().signalDeviceChanged().connect(sigc::mem_fun(*this, &InputDialogImpl::handleDeviceChange)); Inkscape::DeviceManager::getManager().signalAxesChanged().connect(sigc::mem_fun(*this, &InputDialogImpl::updateDeviceAxes)); Inkscape::DeviceManager::getManager().signalButtonsChanged().connect(sigc::mem_fun(*this, &InputDialogImpl::updateDeviceButtons)); - Glib::RefPtr<Gtk::TreeView> treePtr(&tree); - Inkscape::DeviceManager::getManager().signalLinkChanged().connect(sigc::bind(sigc::ptr_fun(&InputDialogImpl::updateDeviceLinks), tabletIter, treePtr)); + Glib::RefPtr<Gtk::TreeView> treePtr(&deviceTree); + Inkscape::DeviceManager::getManager().signalLinkChanged().connect(sigc::bind(sigc::ptr_fun(&InputDialogImpl::updateDeviceLinks), deviceIter, treePtr)); - tree.expand_all(); + deviceTree.expand_all(); show_all_children(); } @@ -777,12 +844,30 @@ static Glib::ustring getCommon( std::list<Glib::ustring> const &names ) return result; } + +void InputDialogImpl::ConfPanel::onModeChange() +{ + Glib::ustring newText = modeCombo.get_active_text(); + + Glib::RefPtr<Gtk::TreeSelection> sel = confDeviceTree.get_selection(); + Gtk::TreeModel::iterator iter = sel->get_selected(); + if (iter) { + Glib::RefPtr<InputDevice const> dev = (*iter)[getCols().device]; + if (dev && (getStringToMode().find(newText) != getStringToMode().end())) { + Gdk::InputMode mode = getStringToMode()[newText]; + Inkscape::DeviceManager::getManager().setMode( dev->getId(), mode ); + } + } + +} + + void InputDialogImpl::setupTree( Glib::RefPtr<Gtk::TreeStore> store, Gtk::TreeIter &tablet ) { std::list<Glib::RefPtr<InputDevice const> > devList = Inkscape::DeviceManager::getManager().getDevices(); if ( !devList.empty() ) { - Gtk::TreeModel::Row row = *(store->append()); - row[getCols().description] = _("Hardware"); + //Gtk::TreeModel::Row row = *(store->append()); + //row[getCols().description] = _("Hardware"); // Let's make some tablets!!! std::list<TabletTmp> tablets; @@ -807,7 +892,7 @@ void InputDialogImpl::setupTree( Glib::RefPtr<Gtk::TreeStore> store, Gtk::TreeIt // Phase 2 - build a UI for the present devices for ( std::list<TabletTmp>::iterator it = tablets.begin(); it != tablets.end(); ++it ) { - tablet = store->append(row.children()); + tablet = store->prepend(/*row.children()*/); Gtk::TreeModel::Row childrow = *tablet; if ( it->name.empty() ) { // Check to see if we can derive one @@ -870,13 +955,14 @@ void InputDialogImpl::setupTree( Glib::RefPtr<Gtk::TreeStore> store, Gtk::TreeIt for ( std::list<Glib::RefPtr<InputDevice const> >::iterator it = devList.begin(); it != devList.end(); ++it ) { Glib::RefPtr<InputDevice const> dev = *it; if ( dev && (consumed.find( dev->getId() ) == consumed.end()) ) { - Gtk::TreeModel::Row deviceRow = *(store->append(row.children())); + Gtk::TreeModel::Row deviceRow = *(store->prepend(/*row.children()*/)); deviceRow[getCols().description] = dev->getName(); deviceRow[getCols().device] = dev; deviceRow[getCols().mode] = dev->getMode(); deviceRow[getCols().thumbnail] = getPix(PIX_CORE); } } + } else { g_warning("No devices found"); } @@ -885,84 +971,158 @@ void InputDialogImpl::setupTree( Glib::RefPtr<Gtk::TreeStore> store, Gtk::TreeIt InputDialogImpl::ConfPanel::ConfPanel() : Gtk::VBox(), - store(Gtk::TreeStore::create(getCols())), - tabletIter(), - tree(store), - treeScroller(), + confDeviceStore(Gtk::TreeStore::create(getCols())), + confDeviceIter(), + confDeviceTree(confDeviceStore), + confDeviceScroller(), watcher(*this), useExt(_("_Use pressure-sensitive tablet (requires restart)"), true), - save(_("_Save"), true) + save(_("_Save"), true), + detailsBox(false, 4), + titleFrame(false, 4), + titleLabel(""), + axisFrame(_("Axes")), + keysFrame(_("Keys")), + modeLabel(_("Mode")), + modeBox(false, 4) + { - pack_start(treeScroller); - treeScroller.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); - treeScroller.add(tree); - class Foo : public Gtk::TreeModel::ColumnRecord { + confDeviceScroller.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); + confDeviceScroller.set_shadow_type(Gtk::SHADOW_IN); + confDeviceScroller.add(confDeviceTree); + confDeviceScroller.set_size_request(120, 0); + + /* class Foo : public Gtk::TreeModel::ColumnRecord { public : Gtk::TreeModelColumn<Glib::ustring> one; Foo() {add(one);} }; static Foo foo; - Glib::RefPtr<Gtk::ListStore> poppers = Gtk::ListStore::create(foo); - poppers->reference(); - - Gtk::TreeModel::Row row = *(poppers->append()); - row[foo.one] = getModeToString()[Gdk::MODE_DISABLED]; - row = *(poppers->append()); - row[foo.one] = getModeToString()[Gdk::MODE_SCREEN]; - row = *(poppers->append()); - row[foo.one] = getModeToString()[Gdk::MODE_WINDOW]; //Add the TreeView's view columns: { Gtk::CellRendererToggle *rendr = new Gtk::CellRendererToggle(); Gtk::TreeViewColumn *col = new Gtk::TreeViewColumn("xx", *rendr); if (col) { - tree.append_column(*col); + confDeviceTree.append_column(*col); col->set_cell_data_func(*rendr, sigc::ptr_fun(setCellStateToggle)); - rendr->signal_toggled().connect(sigc::bind(sigc::ptr_fun(commitCellStateChange), store)); + rendr->signal_toggled().connect(sigc::bind(sigc::ptr_fun(commitCellStateChange), confDeviceStore)); } - } + }*/ - int expPos = tree.append_column("", getCols().expander); + //int expPos = confDeviceTree.append_column("", getCols().expander); - tree.append_column("I", getCols().thumbnail); - tree.append_column("Bar", getCols().description); + confDeviceTree.append_column("I", getCols().thumbnail); + confDeviceTree.append_column("Bar", getCols().description); - { - Gtk::CellRendererCombo *rendr = new Gtk::CellRendererCombo(); - rendr->property_model().set_value(poppers); - rendr->property_text_column().set_value(0); - rendr->property_has_entry() = false; + //confDeviceTree.get_column(0)->set_fixed_width(100); + //confDeviceTree.get_column(1)->set_expand(); + +/* { Gtk::TreeViewColumn *col = new Gtk::TreeViewColumn("X", *rendr); if (col) { - tree.append_column(*col); + confDeviceTree.append_column(*col); col->set_cell_data_func(*rendr, sigc::ptr_fun(setModeCellString)); - rendr->signal_edited().connect(sigc::bind(sigc::ptr_fun(commitCellModeChange), store)); + rendr->signal_edited().connect(sigc::bind(sigc::ptr_fun(commitCellModeChange), confDeviceStore)); rendr->property_editable() = true; } - } + }*/ - tree.set_enable_tree_lines(); - tree.set_headers_visible(false); - tree.set_expander_column( *tree.get_column(expPos - 1) ); + //confDeviceTree.set_enable_tree_lines(); + confDeviceTree.property_enable_tree_lines() = false; + confDeviceTree.property_enable_grid_lines() = false; + confDeviceTree.set_headers_visible(false); + //confDeviceTree.set_expander_column( *confDeviceTree.get_column(expPos - 1) ); - setupTree( store, tabletIter ); + confDeviceTree.get_selection()->signal_changed().connect(sigc::mem_fun(*this, &InputDialogImpl::ConfPanel::onTreeSelect)); - Glib::RefPtr<Gtk::TreeView> treePtr(&tree); - Inkscape::DeviceManager::getManager().signalLinkChanged().connect(sigc::bind(sigc::ptr_fun(&InputDialogImpl::updateDeviceLinks), tabletIter, treePtr)); + setupTree( confDeviceStore, confDeviceIter ); - tree.expand_all(); + Glib::RefPtr<Gtk::TreeView> treePtr(&confDeviceTree); + Inkscape::DeviceManager::getManager().signalLinkChanged().connect(sigc::bind(sigc::ptr_fun(&InputDialogImpl::updateDeviceLinks), confDeviceIter, treePtr)); + + confDeviceTree.expand_all(); useExt.set_active(Preferences::get()->getBool("/options/useextinput/value")); useExt.signal_toggled().connect(sigc::mem_fun(*this, &InputDialogImpl::ConfPanel::useExtToggled)); - pack_start(useExt, Gtk::PACK_SHRINK); + Gtk::HButtonBox *buttonBox = manage (new Gtk::HButtonBox); + buttonBox->set_layout (Gtk::BUTTONBOX_END); + //Gtk::Alignment *align = new Gtk::Alignment(Gtk::ALIGN_END, Gtk::ALIGN_START, 0, 0); + buttonBox->add(save); save.signal_clicked().connect(sigc::mem_fun(*this, &InputDialogImpl::ConfPanel::saveSettings)); - Gtk::Alignment *align = new Gtk::Alignment(Gtk::ALIGN_END, Gtk::ALIGN_START, 0, 0); - align->add(save); - pack_start(*Gtk::manage(align), Gtk::PACK_SHRINK); + + titleFrame.pack_start(titleLabel, true, true); + //titleFrame.set_shadow_type(Gtk::SHADOW_IN); + + modeCombo.append(getModeToString()[Gdk::MODE_DISABLED]); + modeCombo.append(getModeToString()[Gdk::MODE_SCREEN]); + modeCombo.append(getModeToString()[Gdk::MODE_WINDOW]); + modeCombo.set_tooltip_text(_("A device can be 'Disabled', its co-ordinates mapped to the whole 'Screen', or to a single (usually focused) 'Window'")); + modeCombo.signal_changed().connect(sigc::mem_fun(*this, &InputDialogImpl::ConfPanel::onModeChange)); + + modeBox.pack_start(modeLabel, false, false); + modeBox.pack_start(modeCombo, true, true); + + axisVBox.add(axisScroll); + axisFrame.add(axisVBox); + + keysFrame.add(keysScroll); + + /** + * Scrolled Window + */ + keysScroll.add(keysTree); + keysScroll.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); + keysScroll.set_shadow_type(Gtk::SHADOW_IN); + keysScroll.set_size_request(120, 80); + + keysStore = Gtk::ListStore::create(keysColumns); + + _kb_shortcut_renderer.property_editable() = true; + + keysTree.set_model(keysStore); + keysTree.set_headers_visible(false); + keysTree.append_column("Name", keysColumns.name); + keysTree.append_column("Value", keysColumns.value); + + //keysTree.append_column("Value", _kb_shortcut_renderer); + //keysTree.get_column(1)->add_attribute(_kb_shortcut_renderer.property_text(), keysColumns.value); + //_kb_shortcut_renderer.signal_accel_edited().connect( sigc::mem_fun(*this, &InputDialogImpl::onKBTreeEdited) ); + //_kb_shortcut_renderer.signal_accel_cleared().connect( sigc::mem_fun(*this, &InputDialogImpl::onKBTreeCleared) ); + + axisStore = Gtk::ListStore::create(axisColumns); + + axisTree.set_model(axisStore); + axisTree.set_headers_visible(false); + axisTree.append_column("Name", axisColumns.name); + axisTree.append_column("Value", axisColumns.value); + + /** + * Scrolled Window + */ + axisScroll.add(axisTree); + axisScroll.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); + axisScroll.set_shadow_type(Gtk::SHADOW_IN); + axisScroll.set_size_request(0, 150); + + pane.pack1(confDeviceScroller); + pane.pack2(detailsBox); + + detailsBox.pack_start(titleFrame, false, false, 6); + detailsBox.pack_start(modeBox, false, false, 6); + detailsBox.pack_start(axisFrame, false, false); + detailsBox.pack_start(keysFrame, false, false); + + pack_start(pane, true, true); + pack_start(useExt, Gtk::PACK_SHRINK); + pack_start(*buttonBox, false, false); + + // Select the first device + confDeviceTree.get_selection()->select(confDeviceStore->get_iter("0")); + } InputDialogImpl::ConfPanel::~ConfPanel() @@ -995,6 +1155,8 @@ void InputDialogImpl::ConfPanel::commitCellModeChange(Glib::ustring const &path, Inkscape::DeviceManager::getManager().setMode( dev->getId(), mode ); } } + + } void InputDialogImpl::ConfPanel::setCellStateToggle(Gtk::CellRenderer *rndr, Gtk::TreeIter const &iter) @@ -1029,6 +1191,25 @@ void InputDialogImpl::ConfPanel::commitCellStateChange(Glib::ustring const &path } } +void InputDialogImpl::ConfPanel::onTreeSelect() +{ + Glib::RefPtr<Gtk::TreeSelection> treeSel = confDeviceTree.get_selection(); + Gtk::TreeModel::iterator iter = treeSel->get_selected(); + if (iter) { + Gtk::TreeModel::Row row = *iter; + Glib::ustring val = row[getCols().description]; + Glib::RefPtr<InputDevice const> dev = row[getCols().device]; + Gdk::InputMode mode = (*iter)[getCols().mode]; + modeCombo.set_active(getModeId(mode)); + + titleLabel.set_markup("<b>" + row[getCols().description] + "</b>"); + + if (dev) { + setKeys(dev->getNumKeys()); + setAxis(dev->getNumAxes()); + } + } +} void InputDialogImpl::ConfPanel::saveSettings() { Inkscape::DeviceManager::getManager().saveConfig(); @@ -1070,8 +1251,8 @@ void InputDialogImpl::handleDeviceChange(Glib::RefPtr<InputDevice const> device) { // g_message("OUCH!!!! for %p hits %s", &device, device->getId().c_str()); std::vector<Glib::RefPtr<Gtk::TreeStore> > stores; - stores.push_back(store); - stores.push_back(cfgPanel.store); + stores.push_back(deviceStore); + stores.push_back(cfgPanel.confDeviceStore); for (std::vector<Glib::RefPtr<Gtk::TreeStore> >::iterator it = stores.begin(); it != stores.end(); ++it) { Gtk::TreeModel::iterator deviceIter; @@ -1154,11 +1335,11 @@ bool InputDialogImpl::findDeviceByLink(const Gtk::TreeModel::iterator& iter, void InputDialogImpl::updateDeviceLinks(Glib::RefPtr<InputDevice const> device, Gtk::TreeIter tabletIter, Glib::RefPtr<Gtk::TreeView> tree) { - Glib::RefPtr<Gtk::TreeStore> store = Glib::RefPtr<Gtk::TreeStore>::cast_dynamic(tree->get_model()); + Glib::RefPtr<Gtk::TreeStore> deviceStore = Glib::RefPtr<Gtk::TreeStore>::cast_dynamic(tree->get_model()); // g_message("Links!!!! for %p hits [%s] with link of [%s]", &device, device->getId().c_str(), device->getLink().c_str()); Gtk::TreeModel::iterator deviceIter; - store->foreach_iter( sigc::bind<Glib::ustring, Gtk::TreeModel::iterator*>( + deviceStore->foreach_iter( sigc::bind<Glib::ustring, Gtk::TreeModel::iterator*>( sigc::ptr_fun(&InputDialogImpl::findDevice), device->getId(), &deviceIter) ); @@ -1176,16 +1357,16 @@ void InputDialogImpl::updateDeviceLinks(Glib::RefPtr<InputDevice const> device, Glib::ustring descr = (*deviceIter)[getCols().description]; Glib::RefPtr<Gdk::Pixbuf> thumb = (*deviceIter)[getCols().thumbnail]; - Gtk::TreeModel::Row deviceRow = *store->append(tabletIter->children()); + Gtk::TreeModel::Row deviceRow = *deviceStore->append(tabletIter->children()); deviceRow[getCols().description] = descr; deviceRow[getCols().thumbnail] = thumb; deviceRow[getCols().device] = dev; deviceRow[getCols().mode] = dev->getMode(); Gtk::TreeModel::iterator oldParent = deviceIter->parent(); - store->erase(deviceIter); + deviceStore->erase(deviceIter); if ( oldParent->children().empty() ) { - store->erase(oldParent); + deviceStore->erase(oldParent); } } } else { @@ -1193,7 +1374,7 @@ void InputDialogImpl::updateDeviceLinks(Glib::RefPtr<InputDevice const> device, if ( deviceIter->parent() == tabletIter ) { // Simple case. Not already linked - Gtk::TreeIter newGroup = store->append(tabletIter->children()); + Gtk::TreeIter newGroup = deviceStore->append(tabletIter->children()); (*newGroup)[getCols().description] = _("Pen"); (*newGroup)[getCols().thumbnail] = getPix(PIX_PEN); @@ -1201,7 +1382,7 @@ void InputDialogImpl::updateDeviceLinks(Glib::RefPtr<InputDevice const> device, Glib::ustring descr = (*deviceIter)[getCols().description]; Glib::RefPtr<Gdk::Pixbuf> thumb = (*deviceIter)[getCols().thumbnail]; - Gtk::TreeModel::Row deviceRow = *store->append(newGroup->children()); + Gtk::TreeModel::Row deviceRow = *deviceStore->append(newGroup->children()); deviceRow[getCols().description] = descr; deviceRow[getCols().thumbnail] = thumb; deviceRow[getCols().device] = dev; @@ -1209,7 +1390,7 @@ void InputDialogImpl::updateDeviceLinks(Glib::RefPtr<InputDevice const> device, Gtk::TreeModel::iterator linkIter; - store->foreach_iter( sigc::bind<Glib::ustring, Gtk::TreeModel::iterator*>( + deviceStore->foreach_iter( sigc::bind<Glib::ustring, Gtk::TreeModel::iterator*>( sigc::ptr_fun(&InputDialogImpl::findDeviceByLink), device->getId(), &linkIter) ); @@ -1218,22 +1399,22 @@ void InputDialogImpl::updateDeviceLinks(Glib::RefPtr<InputDevice const> device, descr = (*linkIter)[getCols().description]; thumb = (*linkIter)[getCols().thumbnail]; - deviceRow = *store->append(newGroup->children()); + deviceRow = *deviceStore->append(newGroup->children()); deviceRow[getCols().description] = descr; deviceRow[getCols().thumbnail] = thumb; deviceRow[getCols().device] = dev; deviceRow[getCols().mode] = dev->getMode(); Gtk::TreeModel::iterator oldParent = linkIter->parent(); - store->erase(linkIter); + deviceStore->erase(linkIter); if ( oldParent->children().empty() ) { - store->erase(oldParent); + deviceStore->erase(oldParent); } } Gtk::TreeModel::iterator oldParent = deviceIter->parent(); - store->erase(deviceIter); + deviceStore->erase(deviceIter); if ( oldParent->children().empty() ) { - store->erase(oldParent); + deviceStore->erase(oldParent); } tree->expand_row(Gtk::TreePath(newGroup), true); } @@ -1242,7 +1423,7 @@ void InputDialogImpl::updateDeviceLinks(Glib::RefPtr<InputDevice const> device, } void InputDialogImpl::linkComboChanged() { - Glib::RefPtr<Gtk::TreeSelection> treeSel = tree.get_selection(); + Glib::RefPtr<Gtk::TreeSelection> treeSel = deviceTree.get_selection(); Gtk::TreeModel::iterator iter = treeSel->get_selected(); if (iter) { Gtk::TreeModel::Row row = *iter; @@ -1268,14 +1449,15 @@ void InputDialogImpl::linkComboChanged() { void InputDialogImpl::resyncToSelection() { bool clear = true; - Glib::RefPtr<Gtk::TreeSelection> treeSel = tree.get_selection(); + Glib::RefPtr<Gtk::TreeSelection> treeSel = deviceTree.get_selection(); Gtk::TreeModel::iterator iter = treeSel->get_selected(); if (iter) { Gtk::TreeModel::Row row = *iter; Glib::ustring val = row[getCols().description]; Glib::RefPtr<InputDevice const> dev = row[getCols().device]; + if ( dev ) { - devDetails.set_sensitive(true); + axisTable.set_sensitive(true); linkConnection.block(); linkCombo.remove_all(); @@ -1300,21 +1482,60 @@ void InputDialogImpl::resyncToSelection() { clear = false; devName.set_label(row[getCols().description]); - detailFrame.set_label(row[getCols().description]); + axisFrame.set_label(row[getCols().description]); setupValueAndCombo( dev->getNumAxes(), dev->getNumAxes(), devAxesCount, axesCombo); setupValueAndCombo( dev->getNumKeys(), dev->getNumKeys(), devKeyCount, buttonCombo); + + } } - devDetails.set_sensitive(!clear); + axisTable.set_sensitive(!clear); if (clear) { - detailFrame.set_label(""); + axisFrame.set_label(""); devName.set_label(""); devAxesCount.set_label(""); devKeyCount.set_label(""); } } +void InputDialogImpl::ConfPanel::setAxis(gint count) +{ + /* + * TODO - Make each axis editable + */ + axisStore->clear(); + + static Glib::ustring axesLabels[6] = {_("X"), _("Y"), _("Pressure"), _("X tilt"), _("Y tilt"), _("Wheel")}; + + for ( gint barNum = 0; barNum < static_cast<gint>(G_N_ELEMENTS(axesLabels)); barNum++ ) { + + Gtk::TreeModel::Row row = *(axisStore->append()); + row[axisColumns.name] = axesLabels[barNum]; + if (barNum < count) { + row[axisColumns.value] = Glib::ustring::format(barNum+1); + } else { + row[axisColumns.value] = _("None"); + } + } + +} +void InputDialogImpl::ConfPanel::setKeys(gint count) +{ + /* + * TODO - Make each key assignable + */ + + keysStore->clear(); + + for (gint i = 0; i < count; i++) { + Gtk::TreeModel::Row row = *(keysStore->append()); + row[keysColumns.name] = Glib::ustring::format(i+1); + row[keysColumns.value] = _("Disabled"); + } + + +} void InputDialogImpl::setupValueAndCombo( gint reported, gint actual, Gtk::Label& label, Gtk::ComboBoxText& combo ) { gchar *tmp = g_strdup_printf("%d", reported); @@ -1350,9 +1571,9 @@ void InputDialogImpl::updateTestButtons( Glib::ustring const& key, gint hotButto void InputDialogImpl::updateTestAxes( Glib::ustring const& key, GdkDevice* dev ) { - static gdouble epsilon = 0.0001; + //static gdouble epsilon = 0.0001; { - Glib::RefPtr<Gtk::TreeSelection> treeSel = tree.get_selection(); + Glib::RefPtr<Gtk::TreeSelection> treeSel = deviceTree.get_selection(); Gtk::TreeModel::iterator iter = treeSel->get_selected(); if (iter) { Gtk::TreeModel::Row row = *iter; @@ -1364,7 +1585,6 @@ void InputDialogImpl::updateTestAxes( Glib::ustring const& key, GdkDevice* dev ) } } - for ( gint i = 0; i < static_cast<gint>(G_N_ELEMENTS(testAxes)); i++ ) { if ( axesMap[key].find(i) != axesMap[key].end() ) { switch ( axesMap[key][i].first ) { @@ -1379,7 +1599,6 @@ void InputDialogImpl::updateTestAxes( Glib::ustring const& key, GdkDevice* dev ) testAxes[i].set(getPix(PIX_AXIS_OFF)); axesValues[i].set_sensitive(true); if ( dev && (i < static_cast<gint>(G_N_ELEMENTS(axesValues)) ) ) { - // FIXME: Device axis ranges are inaccessible in GTK+ 3 and // are deprecated in GTK+ 2. Progress-bar ranges are disabled // until we find an alternative solution diff --git a/src/ui/dialog/layer-properties.cpp b/src/ui/dialog/layer-properties.cpp index 245dac5e0..6a1bc829e 100644 --- a/src/ui/dialog/layer-properties.cpp +++ b/src/ui/dialog/layer-properties.cpp @@ -42,18 +42,35 @@ LayerPropertiesDialog::LayerPropertiesDialog() { Gtk::Box *mainVBox = get_vbox(); +#if WITH_GTKMM_3_0 + _layout_table.set_row_spacing(4); + _layout_table.set_column_spacing(4); +#else _layout_table.set_spacings(4); _layout_table.resize (1, 2); +#endif // Layer name widgets _layer_name_entry.set_activates_default(true); _layer_name_label.set_label(_("Layer name:")); _layer_name_label.set_alignment(1.0, 0.5); +#if WITH_GTKMM_3_0 + _layer_name_label.set_halign(Gtk::ALIGN_FILL); + _layer_name_label.set_valign(Gtk::ALIGN_FILL); + _layout_table.attach(_layer_name_label, 0, 0, 1, 1); + + _layer_name_entry.set_halign(Gtk::ALIGN_FILL); + _layer_name_entry.set_valign(Gtk::ALIGN_FILL); + _layer_name_entry.set_hexpand(); + _layout_table.attach(_layer_name_entry, 1, 0, 1, 1); +#else _layout_table.attach(_layer_name_label, 0, 1, 0, 1, Gtk::FILL, Gtk::FILL); _layout_table.attach(_layer_name_entry, 1, 2, 0, 1, Gtk::FILL | Gtk::EXPAND, Gtk::FILL); +#endif + mainVBox->pack_start(_layout_table, true, true, 4); // Buttons @@ -149,7 +166,9 @@ LayerPropertiesDialog::_setup_position_controls() { _layer_position_combo.set_cell_data_func(_label_renderer, sigc::mem_fun(*this, &LayerPropertiesDialog::_prepareLabelRenderer)); +#if !WITH_GTKMM_3_0 _layout_table.resize (2, 2); +#endif Gtk::ListStore::iterator row; row = _dropdown_list->append(); @@ -163,12 +182,25 @@ LayerPropertiesDialog::_setup_position_controls() { row->set_value(_dropdown_columns.position, LPOS_CHILD); row->set_value(_dropdown_columns.name, Glib::ustring(_("As sublayer of current"))); - _layout_table.attach(_layer_position_combo, - 1, 2, 1, 2, Gtk::FILL | Gtk::EXPAND, Gtk::FILL); _layer_position_label.set_label(_("Position:")); _layer_position_label.set_alignment(1.0, 0.5); + +#if WITH_GTKMM_3_0 + _layer_position_combo.set_halign(Gtk::ALIGN_FILL); + _layer_position_combo.set_valign(Gtk::ALIGN_FILL); + _layer_position_combo.set_hexpand(); + _layout_table.attach(_layer_position_combo, 1, 1, 1, 1); + + _layer_position_label.set_halign(Gtk::ALIGN_FILL); + _layer_position_label.set_valign(Gtk::ALIGN_FILL); + _layout_table.attach(_layer_position_label, 0, 1, 1, 1); +#else + _layout_table.attach(_layer_position_combo, + 1, 2, 1, 2, Gtk::FILL | Gtk::EXPAND, Gtk::FILL); _layout_table.attach(_layer_position_label, 0, 1, 1, 2, Gtk::FILL, Gtk::FILL); +#endif + show_all_children(); } @@ -222,8 +254,17 @@ LayerPropertiesDialog::_setup_layers_controls() { _layout_table.remove(_layer_name_entry); _layout_table.remove(_layer_name_label); +#if WITH_GTKMM_3_0 + _scroller.set_halign(Gtk::ALIGN_FILL); + _scroller.set_valign(Gtk::ALIGN_FILL); + _scroller.set_hexpand(); + _scroller.set_vexpand(); + _layout_table.attach(_scroller, 0, 1, 2, 1); +#else _layout_table.attach(_scroller, 0, 2, 1, 2, Gtk::FILL | Gtk::EXPAND, Gtk::FILL | Gtk::EXPAND); +#endif + show_all_children(); } diff --git a/src/ui/dialog/layer-properties.h b/src/ui/dialog/layer-properties.h index 46b31ad35..9de303f89 100644 --- a/src/ui/dialog/layer-properties.h +++ b/src/ui/dialog/layer-properties.h @@ -12,10 +12,20 @@ #ifndef INKSCAPE_DIALOG_LAYER_PROPERTIES_H #define INKSCAPE_DIALOG_LAYER_PROPERTIES_H +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + #include <gtkmm/dialog.h> #include <gtkmm/entry.h> #include <gtkmm/label.h> + +#if WITH_GTKMM_3_0 +#include <gtkmm/grid.h> +#else #include <gtkmm/table.h> +#endif + #include <gtkmm/combobox.h> #include <gtkmm/liststore.h> #include <gtkmm/treeview.h> @@ -92,7 +102,13 @@ protected: Gtk::Entry _layer_name_entry; Gtk::Label _layer_position_label; Gtk::ComboBox _layer_position_combo; + +#if WITH_GTKMM_3_0 + Gtk::Grid _layout_table; +#else Gtk::Table _layout_table; +#endif + bool _position_visible; class ModelColumns : public Gtk::TreeModel::ColumnRecord diff --git a/src/ui/dialog/ocaldialogs.cpp b/src/ui/dialog/ocaldialogs.cpp index 174f361fd..c7bff185c 100644 --- a/src/ui/dialog/ocaldialogs.cpp +++ b/src/ui/dialog/ocaldialogs.cpp @@ -1112,8 +1112,14 @@ void ImportDialog::on_xml_file_read(const Glib::RefPtr<Gio::AsyncResult>& result xmlDoc *doc = NULL; xmlNode *root_element = NULL; - doc = xmlReadMemory(data, (int) length, xml_uri.c_str(), NULL, - XML_PARSE_RECOVER + XML_PARSE_NOWARNING + XML_PARSE_NOERROR); + int parse_options = XML_PARSE_RECOVER + XML_PARSE_NOWARNING + XML_PARSE_NOERROR; // do not use XML_PARSE_NOENT ! see bug lp:1025185 + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + bool allowNetAccess = prefs->getBool("/options/externalresources/xml/allow_net_access", false); + if (!allowNetAccess) { + parse_options |= XML_PARSE_NONET; + } + + doc = xmlReadMemory(data, (int) length, xml_uri.c_str(), NULL, parse_options); if (doc == NULL) { // If nothing is returned, no results could be found diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index cc441cc1c..3791ec73c 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -817,12 +817,15 @@ SPDesktopWidget::updateTitle(gchar const* uri) gchar const *fname = uri; GString *name = g_string_new (""); - gchar const *grayscalename = _("(grayscale) "); - gchar const *grayscalenamecomma = _(", grayscale"); - gchar const *printcolorsname = _("(print colors preview) "); - gchar const *printcolorsnamecomma = _(", print colors preview"); - gchar const *colormodename = ""; - gchar const *colormodenamecomma = ""; + gchar const *grayscalename = N_("grayscale"); + gchar const *grayscalenamecomma = N_(", grayscale"); + gchar const *printcolorsname = N_("print colors preview"); + gchar const *printcolorsnamecomma = N_(", print colors preview"); + gchar const *outlinename = N_("outline"); + gchar const *nofiltersname = N_("no filters"); + gchar const *colormodename = NULL; + gchar const *colormodenamecomma = NULL; + gchar const *rendermodename = NULL; gchar const *modifiedname = ""; SPDocument *doc = this->desktop->doc(); if (doc->isModifiedSinceSave()) { @@ -836,22 +839,40 @@ SPDesktopWidget::updateTitle(gchar const* uri) colormodename = printcolorsname; colormodenamecomma = printcolorsnamecomma; } + if (this->desktop->getMode() == Inkscape::RENDERMODE_OUTLINE) { + rendermodename = outlinename; + } else if (this->desktop->getMode() == Inkscape::RENDERMODE_NO_FILTERS) { + rendermodename = nofiltersname; + } + if (this->desktop->number > 1) { - if (this->desktop->getMode() == Inkscape::RENDERMODE_OUTLINE) { - g_string_printf (name, _("%s%s: %d (outline%s) - Inkscape"), modifiedname, fname, this->desktop->number, colormodenamecomma); - } else if (this->desktop->getMode() == Inkscape::RENDERMODE_NO_FILTERS) { - g_string_printf (name, _("%s%s: %d (no filters%s) - Inkscape"), modifiedname, fname, this->desktop->number, colormodenamecomma); + if (rendermodename) { + if (colormodenamecomma) { + g_string_printf (name, _("%s%s: %d (%s%s) - Inkscape"), modifiedname, fname, this->desktop->number, _(rendermodename), _(colormodenamecomma)); + } else { + g_string_printf (name, _("%s%s: %d (%s) - Inkscape"), modifiedname, fname, this->desktop->number, _(rendermodename)); + } } else { - g_string_printf (name, _("%s%s: %d %s- Inkscape"), modifiedname, fname, this->desktop->number, colormodename); + if (colormodename) { + g_string_printf (name, _("%s%s: %d (%s) - Inkscape"), modifiedname, fname, this->desktop->number, _(colormodename)); + } else { + g_string_printf (name, _("%s%s: %d - Inkscape"), modifiedname, fname, this->desktop->number); + } } } else { - if (this->desktop->getMode() == Inkscape::RENDERMODE_OUTLINE) { - g_string_printf (name, _("%s%s (outline%s) - Inkscape"), modifiedname, fname, colormodenamecomma); - } else if (this->desktop->getMode() == Inkscape::RENDERMODE_NO_FILTERS) { - g_string_printf (name, _("%s%s (no filters%s) - Inkscape"), modifiedname, fname, colormodenamecomma); + if (rendermodename) { + if (colormodenamecomma) { + g_string_printf (name, _("%s%s (%s%s) - Inkscape"), modifiedname, fname, _(rendermodename), _(colormodenamecomma)); + } else { + g_string_printf (name, _("%s%s (%s) - Inkscape"), modifiedname, fname, _(rendermodename)); + } } else { - g_string_printf (name, _("%s%s %s- Inkscape"), modifiedname, fname, colormodename); + if (colormodename) { + g_string_printf (name, _("%s%s (%s) - Inkscape"), modifiedname, fname, _(colormodename)); + } else { + g_string_printf (name, _("%s%s - Inkscape"), modifiedname, fname); + } } } window->set_title (name->str); diff --git a/src/widgets/spinbutton-events.cpp b/src/widgets/spinbutton-events.cpp index c718b6712..1d44b9190 100644 --- a/src/widgets/spinbutton-events.cpp +++ b/src/widgets/spinbutton-events.cpp @@ -66,26 +66,25 @@ spinbutton_defocus (GtkWidget *container) gboolean spinbutton_keypress(GtkWidget *w, GdkEventKey *event, gpointer data) { - SPWidget *spw = SP_WIDGET(data); gdouble v; gdouble step; gdouble page; switch (get_group0_keyval (event)) { case GDK_KEY_Escape: // defocus - spinbutton_undo (w); - spinbutton_defocus(GTK_WIDGET(spw)); + spinbutton_undo(w); + spinbutton_defocus(w); return TRUE; // I consumed the event break; case GDK_KEY_Return: // defocus case GDK_KEY_KP_Enter: - spinbutton_defocus (GTK_WIDGET(spw)); + spinbutton_defocus(w); return TRUE; // I consumed the event break; case GDK_KEY_Tab: case GDK_KEY_ISO_Left_Tab: // set the flag meaning "do not leave toolbar when changing value" - g_object_set_data (G_OBJECT (spw), "stay", GINT_TO_POINTER(TRUE)); + g_object_set_data(G_OBJECT(w), "stay", GINT_TO_POINTER(TRUE)); return FALSE; // I didn't consume the event break; @@ -94,45 +93,45 @@ gboolean spinbutton_keypress(GtkWidget *w, GdkEventKey *event, gpointer data) case GDK_KEY_Up: case GDK_KEY_KP_Up: - g_object_set_data (G_OBJECT (spw), "stay", GINT_TO_POINTER(TRUE)); - v = gtk_spin_button_get_value(GTK_SPIN_BUTTON (w)); - gtk_spin_button_get_increments(GTK_SPIN_BUTTON (w), &step, &page); + g_object_set_data(G_OBJECT(w), "stay", GINT_TO_POINTER(TRUE)); + v = gtk_spin_button_get_value(GTK_SPIN_BUTTON(w)); + gtk_spin_button_get_increments(GTK_SPIN_BUTTON(w), &step, &page); v += step; gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), v); return TRUE; // I consumed the event break; case GDK_KEY_Down: case GDK_KEY_KP_Down: - g_object_set_data (G_OBJECT (spw), "stay", GINT_TO_POINTER(TRUE)); - v = gtk_spin_button_get_value(GTK_SPIN_BUTTON (w)); - gtk_spin_button_get_increments(GTK_SPIN_BUTTON (w), &step, &page); + g_object_set_data(G_OBJECT(w), "stay", GINT_TO_POINTER(TRUE)); + v = gtk_spin_button_get_value(GTK_SPIN_BUTTON(w)); + gtk_spin_button_get_increments(GTK_SPIN_BUTTON(w), &step, &page); v -= step; gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), v); return TRUE; // I consumed the event break; case GDK_KEY_Page_Up: case GDK_KEY_KP_Page_Up: - g_object_set_data (G_OBJECT (spw), "stay", GINT_TO_POINTER(TRUE)); - v = gtk_spin_button_get_value(GTK_SPIN_BUTTON (w)); - gtk_spin_button_get_increments(GTK_SPIN_BUTTON (w), &step, &page); + g_object_set_data(G_OBJECT(w), "stay", GINT_TO_POINTER(TRUE)); + v = gtk_spin_button_get_value(GTK_SPIN_BUTTON(w)); + gtk_spin_button_get_increments(GTK_SPIN_BUTTON(w), &step, &page); v += page; gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), v); return TRUE; // I consumed the event break; case GDK_KEY_Page_Down: case GDK_KEY_KP_Page_Down: - g_object_set_data (G_OBJECT (spw), "stay", GINT_TO_POINTER(TRUE)); - v = gtk_spin_button_get_value(GTK_SPIN_BUTTON (w)); - gtk_spin_button_get_increments(GTK_SPIN_BUTTON (w), &step, &page); + g_object_set_data(G_OBJECT(w), "stay", GINT_TO_POINTER(TRUE)); + v = gtk_spin_button_get_value(GTK_SPIN_BUTTON(w)); + gtk_spin_button_get_increments(GTK_SPIN_BUTTON(w), &step, &page); v -= page; gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), v); return TRUE; // I consumed the event break; case GDK_KEY_z: case GDK_KEY_Z: - g_object_set_data (G_OBJECT (spw), "stay", GINT_TO_POINTER(TRUE)); + g_object_set_data(G_OBJECT(w), "stay", GINT_TO_POINTER(TRUE)); if (event->state & GDK_CONTROL_MASK) { - spinbutton_undo (w); + spinbutton_undo(w); return TRUE; // I consumed the event } break; @@ -142,3 +141,14 @@ gboolean spinbutton_keypress(GtkWidget *w, GdkEventKey *event, gpointer data) } return FALSE; // I didn't consume the event } + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/widgets/spw-utilities.cpp b/src/widgets/spw-utilities.cpp index 8adc72cd7..ce8ce388d 100644 --- a/src/widgets/spw-utilities.cpp +++ b/src/widgets/spw-utilities.cpp @@ -19,7 +19,12 @@ #include <gtkmm/box.h> #include <gtkmm/label.h> + +#if GTK_CHECK_VERSION(3,0,0) +#include <gtkmm/grid.h> +#else #include <gtkmm/table.h> +#endif #include "selection.h" @@ -32,8 +37,11 @@ * Creates a label widget with the given text, at the given col, row * position in the table. */ -Gtk::Label * -spw_label(Gtk::Table *table, const gchar *label_text, int col, int row, Gtk::Widget* target) +#if GTK_CHECK_VERSION(3,0,0) +Gtk::Label * spw_label(Gtk::Grid *table, const gchar *label_text, int col, int row, Gtk::Widget* target) +#else +Gtk::Label * spw_label(Gtk::Table *table, const gchar *label_text, int col, int row, Gtk::Widget* target) +#endif { Gtk::Label *label_widget = new Gtk::Label(); g_assert(label_widget != NULL); @@ -48,7 +56,18 @@ spw_label(Gtk::Table *table, const gchar *label_text, int col, int row, Gtk::Wid } label_widget->set_alignment(1.0, 0.5); label_widget->show(); + +#if GTK_CHECK_VERSION(3,0,0) + label_widget->set_hexpand(); + label_widget->set_halign(Gtk::ALIGN_FILL); + label_widget->set_valign(Gtk::ALIGN_CENTER); + label_widget->set_margin_left(4); + label_widget->set_margin_right(4); + table->attach(*label_widget, col, row, 1, 1); +#else table->attach(*label_widget, col, col+1, row, row+1, (Gtk::EXPAND | Gtk::FILL), static_cast<Gtk::AttachOptions>(0), 4, 0); +#endif + return label_widget; } @@ -61,8 +80,19 @@ spw_label_old(GtkWidget *table, const gchar *label_text, int col, int row) g_assert(label_widget != NULL); gtk_misc_set_alignment (GTK_MISC (label_widget), 1.0, 0.5); gtk_widget_show (label_widget); - gtk_table_attach (GTK_TABLE (table), label_widget, col, col+1, row, row+1, + +#if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_margin_left(label_widget, 4); + gtk_widget_set_margin_right(label_widget, 4); + gtk_widget_set_hexpand(label_widget, TRUE); + gtk_widget_set_halign(label_widget, GTK_ALIGN_FILL); + gtk_widget_set_valign(label_widget, GTK_ALIGN_CENTER); + gtk_grid_attach(GTK_GRID(table), label_widget, col, row, 1, 1); +#else + gtk_table_attach(GTK_TABLE (table), label_widget, col, col+1, row, row+1, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)0, 4, 0); +#endif + return label_widget; } @@ -70,14 +100,26 @@ spw_label_old(GtkWidget *table, const gchar *label_text, int col, int row) * Creates a horizontal layout manager with 4-pixel spacing between children * and space for 'width' columns. */ -Gtk::HBox * -spw_hbox(Gtk::Table * table, int width, int col, int row) +#if GTK_CHECK_VERSION(3,0,0) +Gtk::HBox * spw_hbox(Gtk::Grid * table, int width, int col, int row) +#else +Gtk::HBox * spw_hbox(Gtk::Table * table, int width, int col, int row) +#endif { /* Create a new hbox with a 4-pixel spacing between children */ Gtk::HBox *hb = new Gtk::HBox(false, 4); g_assert(hb != NULL); hb->show(); + +#if GTK_CHECK_VERSION(3,0,0) + hb->set_hexpand(); + hb->set_halign(Gtk::ALIGN_FILL); + hb->set_valign(Gtk::ALIGN_CENTER); + table->attach(*hb, col, row, width, 1); +#else table->attach(*hb, col, col+width, row, row+1, (Gtk::EXPAND | Gtk::FILL), static_cast<Gtk::AttachOptions>(0), 0, 0); +#endif + return hb; } @@ -117,16 +159,33 @@ spw_checkbutton(GtkWidget * dialog, GtkWidget * table, g_assert(dialog != NULL); g_assert(table != NULL); - GtkWidget *l = gtk_label_new (label); - gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0.5); - gtk_widget_show (l); + GtkWidget *l = gtk_label_new (label); + gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0.5); + gtk_widget_show (l); + +#if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_halign(l, GTK_ALIGN_FILL); + gtk_widget_set_hexpand(l, TRUE); + gtk_widget_set_valign(l, GTK_ALIGN_CENTER); + gtk_grid_attach(GTK_GRID(table), l, 0, row, 1, 1); +#else gtk_table_attach (GTK_TABLE (table), l, 0, 1, row, row+1, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)0, 0, 0); +#endif b = gtk_check_button_new (); gtk_widget_show (b); + +#if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_halign(b, GTK_ALIGN_FILL); + gtk_widget_set_hexpand(b, TRUE); + gtk_widget_set_valign(b, GTK_ALIGN_CENTER); + gtk_grid_attach(GTK_GRID(table), b, 1, row, 1, 1); +#else gtk_table_attach (GTK_TABLE (table), b, 1, 2, row, row+1, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)0, 0, 0); +#endif + g_object_set_data (G_OBJECT (b), "key", key); g_object_set_data (G_OBJECT (dialog), key, b); g_signal_connect (G_OBJECT (b), "toggled", cb, dialog); @@ -153,8 +212,17 @@ spw_dropdown(GtkWidget * dialog, GtkWidget * table, spw_label_old(table, label_text, 0, row); gtk_widget_show (selector); + +#if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_halign(selector, GTK_ALIGN_FILL); + gtk_widget_set_hexpand(selector, TRUE); + gtk_widget_set_valign(selector, GTK_ALIGN_CENTER); + gtk_grid_attach(GTK_GRID(table), selector, 1, row, 1, 1); +#else gtk_table_attach (GTK_TABLE (table), selector, 1, 2, row, row+1, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)0, 0, 0); +#endif + g_object_set_data (G_OBJECT (dialog), key, selector); return selector; } @@ -189,8 +257,17 @@ spw_unit_selector(GtkWidget * dialog, GtkWidget * table, GtkWidget * sb = gtk_spin_button_new (GTK_ADJUSTMENT (a), 1.0, 4); g_assert(sb != NULL); gtk_widget_show (sb); + +#if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_halign(sb, GTK_ALIGN_FILL); + gtk_widget_set_hexpand(sb, TRUE); + gtk_widget_set_valign(sb, GTK_ALIGN_CENTER); + gtk_grid_attach(GTK_GRID(table), sb, 1, row, 1, 1); +#else gtk_table_attach (GTK_TABLE (table), sb, 1, 2, row, row+1, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)0, 0, 0); +#endif + g_signal_connect (G_OBJECT (a), "value_changed", cb, dialog); return sb; } diff --git a/src/widgets/spw-utilities.h b/src/widgets/spw-utilities.h index 263abbcaf..fb8c04ebf 100644 --- a/src/widgets/spw-utilities.h +++ b/src/widgets/spw-utilities.h @@ -20,18 +20,26 @@ namespace Gtk { class Label; + +#if GTK_CHECK_VERSION(3,0,0) + class Grid; +#else class Table; +#endif + class HBox; class Widget; } -Gtk::Label * -spw_label(Gtk::Table *table, gchar const *label_text, int col, int row, Gtk::Widget *target); -GtkWidget * -spw_label_old(GtkWidget *table, gchar const *label_text, int col, int row); +#if GTK_CHECK_VERSION(3,0,0) +Gtk::Label * spw_label(Gtk::Grid *table, gchar const *label_text, int col, int row, Gtk::Widget *target); +Gtk::HBox * spw_hbox(Gtk::Grid *table, int width, int col, int row); +#else +Gtk::Label * spw_label(Gtk::Table *table, gchar const *label_text, int col, int row, Gtk::Widget *target); +Gtk::HBox * spw_hbox(Gtk::Table *table, int width, int col, int row); +#endif -Gtk::HBox * -spw_hbox(Gtk::Table *table, int width, int col, int row); +GtkWidget * spw_label_old(GtkWidget *table, gchar const *label_text, int col, int row); GtkWidget * spw_vbox_checkbutton(GtkWidget *dialog, GtkWidget *table, diff --git a/src/widgets/stroke-style.cpp b/src/widgets/stroke-style.cpp index 4e8431454..7912b654a 100644 --- a/src/widgets/stroke-style.cpp +++ b/src/widgets/stroke-style.cpp @@ -122,10 +122,17 @@ StrokeStyle::StrokeStyle() : f->show(); add(*f); +#if WITH_GTKMM_3_0 + table = new Gtk::Grid(); + table->set_border_width(4); + table->set_row_spacing(4); +#else table = new Gtk::Table(3, 6, false); - table->show(); table->set_border_width(4); table->set_row_spacings(4); +#endif + + table->show(); f->add(*table); gint i = 0; @@ -282,7 +289,16 @@ StrokeStyle::StrokeStyle() : dashSelector = manage(new SPDashSelector); dashSelector->show(); + +#if WITH_GTKMM_3_0 + dashSelector->set_hexpand(); + dashSelector->set_halign(Gtk::ALIGN_FILL); + dashSelector->set_valign(Gtk::ALIGN_CENTER); + table->attach(*dashSelector, 1, i, 3, 1); +#else table->attach(*dashSelector, 1, 4, i, i+1, (Gtk::EXPAND | Gtk::FILL), static_cast<Gtk::AttachOptions>(0), 0, 0); +#endif + dashSelector->changed_signal.connect(sigc::mem_fun(*this, &StrokeStyle::lineDashChangedCB)); i++; @@ -298,7 +314,16 @@ StrokeStyle::StrokeStyle() : sigc::bind<MarkerComboBox *, StrokeStyle *, SPMarkerLoc>( sigc::ptr_fun(&StrokeStyle::markerSelectCB), startMarkerCombo, this, SP_MARKER_LOC_START)); startMarkerCombo->show(); + +#if WITH_GTKMM_3_0 + startMarkerCombo->set_hexpand(); + startMarkerCombo->set_halign(Gtk::ALIGN_FILL); + startMarkerCombo->set_valign(Gtk::ALIGN_CENTER); + table->attach(*startMarkerCombo, 1, i, 3, 1); +#else table->attach(*startMarkerCombo, 1, 4, i, i+1, (Gtk::EXPAND | Gtk::FILL), static_cast<Gtk::AttachOptions>(0), 0, 0); +#endif + i++; midMarkerCombo = manage(new MarkerComboBox("marker-mid", SP_MARKER_LOC_MID)); @@ -308,7 +333,16 @@ StrokeStyle::StrokeStyle() : sigc::bind<MarkerComboBox *, StrokeStyle *, SPMarkerLoc>( sigc::ptr_fun(&StrokeStyle::markerSelectCB), midMarkerCombo, this, SP_MARKER_LOC_MID)); midMarkerCombo->show(); + +#if WITH_GTKMM_3_0 + midMarkerCombo->set_hexpand(); + midMarkerCombo->set_halign(Gtk::ALIGN_FILL); + midMarkerCombo->set_valign(Gtk::ALIGN_CENTER); + table->attach(*midMarkerCombo, 1, i, 3, 1); +#else table->attach(*midMarkerCombo, 1, 4, i, i+1, (Gtk::EXPAND | Gtk::FILL), static_cast<Gtk::AttachOptions>(0), 0, 0); +#endif + i++; endMarkerCombo = manage(new MarkerComboBox("marker-end", SP_MARKER_LOC_END)); @@ -318,7 +352,16 @@ StrokeStyle::StrokeStyle() : sigc::bind<MarkerComboBox *, StrokeStyle *, SPMarkerLoc>( sigc::ptr_fun(&StrokeStyle::markerSelectCB), endMarkerCombo, this, SP_MARKER_LOC_END)); endMarkerCombo->show(); + +#if WITH_GTKMM_3_0 + endMarkerCombo->set_hexpand(); + endMarkerCombo->set_halign(Gtk::ALIGN_FILL); + endMarkerCombo->set_valign(Gtk::ALIGN_CENTER); + table->attach(*endMarkerCombo, 1, i, 3, 1); +#else table->attach(*endMarkerCombo, 1, 4, i, i+1, (Gtk::EXPAND | Gtk::FILL), static_cast<Gtk::AttachOptions>(0), 0, 0); +#endif + i++; setDesktop(desktop); diff --git a/src/widgets/stroke-style.h b/src/widgets/stroke-style.h index d437f7e12..5f05b97d1 100644 --- a/src/widgets/stroke-style.h +++ b/src/widgets/stroke-style.h @@ -15,9 +15,19 @@ #ifndef SEEN_DIALOGS_STROKE_STYLE_H #define SEEN_DIALOGS_STROKE_STYLE_H +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + #include "widgets/dash-selector.h" #include <gtkmm/radiobutton.h> + +#if WITH_GTKMM_3_0 +#include <gtkmm/grid.h> +#else #include <gtkmm/table.h> +#endif + #include <glibmm/i18n.h> #include "desktop.h" @@ -139,11 +149,12 @@ private: MarkerComboBox *startMarkerCombo; MarkerComboBox *midMarkerCombo; MarkerComboBox *endMarkerCombo; - Gtk::Table *table; #if WITH_GTKMM_3_0 + Gtk::Grid *table; Glib::RefPtr<Gtk::Adjustment> *widthAdj; Glib::RefPtr<Gtk::Adjustment> *miterLimitAdj; #else + Gtk::Table *table; Gtk::Adjustment *widthAdj; Gtk::Adjustment *miterLimitAdj; #endif diff --git a/src/xml/repr-io.cpp b/src/xml/repr-io.cpp index 29a5b4a78..1258617c7 100644 --- a/src/xml/repr-io.cpp +++ b/src/xml/repr-io.cpp @@ -297,12 +297,18 @@ Document *sp_repr_read_file (const gchar * filename, const gchar *default_ns) XmlSource src; if ( (src.setFile(filename) == 0) ) { + int parse_options = XML_PARSE_HUGE; // do not use XML_PARSE_NOENT ! see bug lp:1025185 + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + bool allowNetAccess = prefs->getBool("/options/externalresources/xml/allow_net_access", false); + if (!allowNetAccess) { + parse_options |= XML_PARSE_NONET; + } doc = xmlReadIO( XmlSource::readCb, XmlSource::closeCb, &src, localFilename, src.getEncoding(), - XML_PARSE_NOENT | XML_PARSE_HUGE); + parse_options); } } |
