From a39b92f278f6d1530cb151875b445185951634df Mon Sep 17 00:00:00 2001 From: tpearson Date: Wed, 10 Mar 2010 20:44:18 +0000 Subject: Added KDE3 version of POTraceGUI git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/potracegui@1101754 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- src/MainWidgetBase.ui | 2939 +++++++++++++++++++++++++++++++++++++++++++ src/Makefile.am | 34 + src/autotraceformats.cpp | 71 ++ src/autotraceformats.h | 86 ++ src/hi16-app-potracegui.png | Bin 0 -> 1032 bytes src/hi32-app-potracegui.png | Bin 0 -> 2748 bytes src/main.cpp | 57 + src/mainwidget.cpp | 1055 ++++++++++++++++ src/mainwidget.h | 200 +++ src/options.cpp | 87 ++ src/options.h | 66 + src/potracegui.cpp | 158 +++ src/potracegui.desktop | 27 + src/potracegui.h | 98 ++ src/potracegui.lsm | 16 + src/potraceguiui.rc | 5 + 16 files changed, 4899 insertions(+) create mode 100644 src/MainWidgetBase.ui create mode 100644 src/Makefile.am create mode 100644 src/autotraceformats.cpp create mode 100644 src/autotraceformats.h create mode 100644 src/hi16-app-potracegui.png create mode 100644 src/hi32-app-potracegui.png create mode 100644 src/main.cpp create mode 100644 src/mainwidget.cpp create mode 100644 src/mainwidget.h create mode 100644 src/options.cpp create mode 100644 src/options.h create mode 100644 src/potracegui.cpp create mode 100644 src/potracegui.desktop create mode 100644 src/potracegui.h create mode 100644 src/potracegui.lsm create mode 100644 src/potraceguiui.rc (limited to 'src') diff --git a/src/MainWidgetBase.ui b/src/MainWidgetBase.ui new file mode 100644 index 0000000..e1a5a43 --- /dev/null +++ b/src/MainWidgetBase.ui @@ -0,0 +1,2939 @@ + +MainWidgetBase + + + MainWidgetBase + + + + 0 + 0 + 555 + 642 + + + + 0 + + + MainWidgetBase + + + true + + + + unnamed + + + + imagesTabs + + + + 7 + 7 + 0 + 0 + + + + + 800 + 600 + + + + + tab + + + &Original image + + + + unnamed + + + + + + + layout7 + + + + unnamed + + + + backendStack + + + + potracePage + + + 0 + + + + unnamed + + + + tabWidget3 + + + + 1 + 7 + 0 + 0 + + + + + tab + + + &Input-Output + + + + unnamed + + + + groupBox2 + + + Input + + + + unnamed + + + + textLabel2_3 + + + Black level: + + + Pixel threshold for B&W conversion of the image + + + + + blackLevel + + + 0.5 + + + 1 + + + Pixel threshold for B&W conversion of the image + + + + + invertInput + + + In&vert + + + Alt+V + + + Inverts the image before processing + + + + + + + groupBox8 + + + Color + + + + unnamed + + + + foregroundBtn + + + + 0 + 0 + 0 + 0 + + + + + + + Output foreground color + + + + + textLabel4_2_2_3 + + + Foreground color: + + + Output foreground color + + + + + opaque + + + Opa&que: + + + Fill in the white parts of the image opaquely + + + + + backgroundBtn + + + false + + + + 0 + 0 + 0 + 0 + + + + + + + Fill color + + + + + + + groupBox1 + + + Output + + + + unnamed + + + + kSqueezedTextLabel2 + + + + 0 + 0 + 0 + 0 + + + + Format: + + + + + + eps + + + + + postscript + + + + + SVG + + + + + pgm + + + + + Gimp path + + + + + Xfig + + + + outputFormat + + + + 7 + 0 + 0 + 0 + + + + Output format + + + + + + + optionsStack + + + + psPage + + + 0 + + + + unnamed + + + + psFrame + + + PS-EPS output + + + + unnamed + + + + textLabel3_3 + + + Page size: + + + Output page size + + + + + + a4 + + + + + a3 + + + + + a5 + + + + + b5 + + + + + letter + + + + + legal + + + + + tabloid + + + + + statement + + + + + executive + + + + + folio + + + + + quarto + + + + + 10x14 + + + + pageSize + + + true + + + 4 + + + Output page size + + + + + optimizedNumericalCode + + + Optimized numerical code + + + true + + + Use a compact numerical format to represent Bezier curves in +PostScript + + + + + compressionLevel + + + Compression level + + + + unnamed + + + + level1 + + + None + + + 3 + + + No compression + + + + + level2 + + + Level 2 + + + true + + + 3 + + + Standard compression (needs LZW-enabled compress) + + + + + level3 + + + Level 3 + + + 3 + + + Maximum compression + + + + + + + + + + + svgPage + + + 1 + + + + unnamed + + + + svgFrame + + + SVG + + + + unnamed + + + + SVGGroup + + + Group + + + Try to group related paths together in the SVG output + + + + + + + + + pgmPage + + + 2 + + + + unnamed + + + + pgmFrame + + + PGM + + + + unnamed + + + + textLabel5_2 + + + Antialias gamma: + + + Gamma value for anti-aliasing + + + + + antialiasGamma + + + 2.2 + + + Gamma value for anti-aliasing + + + + + buttonGroup1 + + + Scale + + + + unnamed + + + + layout3 + + + + unnamed + + + + scaleAllBTN + + + All + + + true + + + All dimesions at once + + + + + scaleAll + + + Scale factor (>1 enlarges, <1 shrinks) + + + + + + + layout4 + + + + unnamed + + + + textLabel10_3 + + + false + + + Y + + + Scale factor (>1 enlarges, <1 shrinks) + + + + + scaleY + + + false + + + Scale factor (>1 enlarges, <1 shrinks) + + + + + textLabel9_3 + + + false + + + X + + + Scale factor (>1 enlarges, <1 shrinks) + + + + + scaleXYBTN + + + Each + + + -1 + + + Each dimension separately + + + + + scaleX + + + false + + + Scale factor (>1 enlarges, <1 shrinks) + + + + + + + + + + + + + undefinedPage + + + 3 + + + + unnamed + + + + kActiveLabel1 + + + + 1 + 1 + 0 + 0 + + + + Sorry, no options for this format. + + + + + spacer8 + + + Vertical + + + Expanding + + + + 20 + 40 + + + + + + spacer9 + + + Vertical + + + Expanding + + + + 20 + 40 + + + + + + spacer10 + + + Horizontal + + + Expanding + + + + 40 + 20 + + + + + + spacer11 + + + Horizontal + + + Expanding + + + + 40 + 20 + + + + + + + + + spacer6 + + + Vertical + + + Expanding + + + + 20 + 16 + + + + + + + + tab + + + A&lgorithm + + + + unnamed + + + + spacer5_2 + + + Vertical + + + Expanding + + + + 20 + 297 + + + + + + curveOptimization + + + Cur&ve optimization + + + true + + + Join adiacent bezier curves (off=larger file) + + + + + optimizationTolerance + + + + 1 + 0 + 0 + 0 + + + + 0.2 + + + Curve optimization tolerance (default = 0.2) + + + Set the curve optimization tolerance. The default value is 0.2. Larger values allow more consecutive Bezier curve segments to be joined together in a single segment, at the expense of accuracy. + + + + + cornerThreshold + + + 1 + + + -1 + + + 1.34 + + + 2 + + + Corner Threshold parameter (<1 hard corners, >1 soft corners) + + + Set the corner threshold parameter. The default value is 1. The smaller this value, the more sharp corners will be produced. If this parameter is negative, then no smoothing will be performed and the output is a polygon. The largest useful value is 4/3 or 1.334, which suppresses all corners and leads to completely smooth output. + + + + + despeckle + + + + 1 + 0 + 0 + 0 + + + + 0 + + + Suppress speckles of up to this many pixels + + + + + + black + + + + + white + + + + + right + + + + + left + + + + + minority + + + + + majority + + + + + random + + + + policy + + + + 7 + 0 + 0 + 0 + + + + 4 + + + How to resolve ambiguities in path +decomposition + + + + + outputQuantization + + + 10 + + + 0 + + + To how many points/pixel the output is rounded + + + Set output quantization. Coordinates in the output are rounded to 1/value pixels. The default value of 10 usually gives good results. In the case of the gimppath backend, this option is used to set the desired magnification. This option has no effect for the XFig backend, which always rasterizes to 1/1200 inch. + + + + + textLabel1_4 + + + Output quantization: + + + How exactly the output is rounded + + + Set output quantization. Coordinates in the output are rounded to 1/value pixels. The default value of 10 usually gives good results. In the case of the gimppath backend, this option is used to set the desired magnification. This option has no effect for the XFig backend, which always rasterizes to 1/1200 inch. + + + + + textLabel4 + + + Optimization tolerance: + + + Curve optimization tolerance (default = 0.2) + + + Set the curve optimization tolerance. The default value is 0.2. Larger values allow more consecutive Bezier curve segments to be joined together in a single segment, at the expense of accuracy. + + + + + textLabel3 + + + Corner Threshold: + + + Corner Threshold parameter (<1 hard corners, >1 soft corners) + + + Set the corner threshold parameter. The default value is 1. The smaller this value, the more sharp corners will be produced. If this parameter is negative, then no smoothing will be performed and the output is a polygon. The largest useful value is 4/3 or 1.334, which suppresses all corners and leads to completely smooth output. + + + + + textLabel2 + + + Despeckle: + + + Suppress speckles of up to this many pixels + + + + + textLabel1 + + + Policy: + + + How to resolve ambiguities in path +decomposition + + + + + + + TabPage + + + &Scaling and transformations + + + + unnamed + + + + groupBox7 + + + Transformation + + + + unnamed + + + + spacer17 + + + Horizontal + + + Expanding + + + + 80 + 31 + + + + + + spacer17_2 + + + Horizontal + + + Expanding + + + + 80 + 31 + + + + + + rotation + + + -360 + + + 360 + + + Rotate output by x degrees + + + + + stretch + + + 1 + + + 2 + + + Aspect ratio (<1 stretched in the x direction, >1 stretched in the y direction) + + + + + spacer17_3 + + + Horizontal + + + Expanding + + + + 80 + 31 + + + + + + height + + + Output image height + + + + + width + + + + 1 + 0 + 0 + 0 + + + + Output image width + + + + + spacer17_4 + + + Horizontal + + + Expanding + + + + 80 + 31 + + + + + + textLabel1_3 + + + + 1 + 1 + 0 + 0 + + + + cm + + + + + textLabel1_3_2 + + + + 1 + 1 + 0 + 0 + + + + cm + + + + + textLabel1_3_4 + + + + 1 + 1 + 0 + 0 + + + + degree + + + + + textLabel3_2 + + + Rotation: + + + Rotate output by x degrees + + + + + textLabel8 + + + Stretch: + + + Aspect ratio (<1 stretched in the x direction, >1 stretched in the y direction) + + + + + textLabel6 + + + Height: + + + Output image height + + + + + textLabel5 + + + Width: + + + Output image width + + + + + + + buttonGroup3 + + + Resolution (dpi) + + + + unnamed + + + + resolutionAllBTN + + + All + + + true + + + 2 + + + All dimensions + + + + + textLabel1_2 + + + false + + + X + + + + + textLabel2_2 + + + false + + + Y + + + + + resolutionXYBTN + + + Each + + + 2 + + + Each dimension separately + + + + + resolutionX + + + false + + + set the resolution (in dpi). One inch in the output image corresponds to this many +pixels in the input + + + + + resolutionY + + + false + + + set the resolution (in dpi). One inch in the output image corresponds to this many +pixels in the input + + + + + resolutionAll + + + set the resolution (in dpi). One inch in the output image corresponds to this many +pixels in the input + + + + + + + spacer7 + + + Vertical + + + Expanding + + + + 20 + 40 + + + + + + + + TabPage + + + &Margins + + + + unnamed + + + + spacer5 + + + Vertical + + + Expanding + + + + 20 + 270 + + + + + + buttonGroup2 + + + Margins + + + + unnamed + + + + textLabel1_3_7 + + + + 1 + 1 + 0 + 0 + + + + cm + + + + + marginsB + + + true + + + Set output margins + + + + + marginsT + + + true + + + Set output margins + + + + + marginsR + + + true + + + Set output margins + + + + + textLabel1_3_3 + + + + 1 + 1 + 0 + 0 + + + + cm + + + + + textLabel1_3_5 + + + + 1 + 1 + 0 + 0 + + + + cm + + + + + textLabel1_3_6 + + + + 1 + 1 + 0 + 0 + + + + cm + + + + + marginsL + + + true + + + + 1 + 0 + 0 + 0 + + + + Set output margins + + + + + spacer22 + + + Horizontal + + + Expanding + + + + 71 + 21 + + + + + + spacer22_2 + + + Horizontal + + + Expanding + + + + 71 + 21 + + + + + + spacer22_3 + + + Horizontal + + + Expanding + + + + 71 + 21 + + + + + + spacer22_4 + + + Horizontal + + + Expanding + + + + 71 + 21 + + + + + + textLabel13 + + + true + + + + 1 + 1 + 0 + 0 + + + + Top: + + + + + textLabel12 + + + true + + + + 1 + 1 + 0 + 0 + + + + Right: + + + + + textLabel11 + + + true + + + + 1 + 1 + 0 + 0 + + + + Left: + + + + + textLabel14 + + + true + + + + 1 + 1 + 0 + 0 + + + + Bottom: + + + + + checkBoxSyncronizeMargins + + + true + + + syncronize + + + true + + + + + + + + + + + + autotracePage + + + 1 + + + + unnamed + + + + autotraceTabs + + + + + + + tab + + + &Input - output + + + + unnamed + + + + groupBox11 + + + &Output format + + + + unnamed + + + + autotraceOutputFormat + + + Select wanted output format + + + + + + + groupBox9 + + + Input image + + + + unnamed + + + + autotraceDpiCheckbox + + + &DPI: + + + Alt+D + + + <p>Dot per inch of input image</p><p>(affects scaling in mif output)</p> + + + + + autotraceCheckBoxReduceColors + + + &reduce color count to: + + + Alt+R + + + true + + + <p>Reduce input image to this number of colors (range: 2 - 256)</p> + + + + + autotraceDpiInput + + + false + + + 0 + + + <p>Dot per inch of input image</p><p>(affects scaling in mif output)</p> + + + + + autotraceColorCount + + + 2 + + + 2 + + + 256 + + + <p>Reduce input image to this number of colors (range: 2 - 256)</p> + + + + + + + groupBox8_2 + + + Transparent color + + + + unnamed + + + + autotraceUseBackground + + + &Use: + + + Alt+U + + + <p>Toggle transparent color</p> + + + + + autotraceBackground + + + false + + + + + + + 255 + 255 + 255 + + + + <p>Ignore this color in input file</p><p>(The color will be rendered as transparent in the output image)</p> + + + + + + + groupBox10 + + + false + + + Log + + + + unnamed + + + + autotraceLog + + + false + + + Create &logfile + + + Alt+L + + + Not working at the moment + + + + + + + spacer14 + + + Vertical + + + Expanding + + + + 20 + 30 + + + + + + + + tab + + + &Corners and curves + + + + unnamed + + + + groupBox12 + + + Corners + + + + unnamed + + + + textLabel3_4 + + + Thre&shold: + + + autotraceThreshold + + + <p>Consider any pixel which forms an angle with its predecessor(s) and successor(s) that is smaller than the specified angle (in degrees) as a corner.</p> + + + + + textLabel4_2 + + + Alwa&ys threshold: + + + autotraceAlwaysThreshold + + + <p>Consider any angle at a pixel which falls below the specified angle (in degrees) as a corner, even if it is bordered by other corner pixels.</p> + + + + + textLabel5_3 + + + NoFocus + + + &Surround: + + + autotraceSurround + + + <p>Consider the specified number of pixels on either side of a point when determining if that point is a corner.</p> + + + + + autotraceSurround + + + 4 + + + 0 + + + <p>Consider the specified number of pixels on either side of a point when determining if that point is a corner.</p> + + + + + autotraceAlwaysThreshold + + + 60 + + + 0 + + + 360 + + + <p>Consider any angle at a pixel which falls below the specified angle (in degrees) as a corner, even if it is bordered by other corner pixels.</p> + + + + + autotraceThreshold + + + 100 + + + 0 + + + 360 + + + <p>Consider any pixel which forms an angle with its predecessor(s) and successor(s) that is smaller than the specified angle (in degrees) as a corner.</p> + + + + + autotraceAdjacentCorners + + + &Remove adjacent corners + + + Alt+R + + + + + + + + + + spacer15 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + groupBox13 + + + Curves + + + + unnamed + + + + autotraceReversionThreshold + + + 0.01 + + + <p>When a spline is closer to a straight line than the specified real number weighted by the square of the curve length, maintain it as a straight line, even if it is a list with curves.</p> + + + + + autotraceIterations + + + 4 + + + 0 + + + <p>Smooth the curve the specified number of times prior to fitting</p> + + + + + autotraceLineThreshold + + + 1 + + + <p>If a spline does not deviate from the straight line defined by its endpoints by more than the specified number of pixels, then treat it as a straight line.</p> + + + + + textLabel7 + + + Re&version threshold: + + + autotraceReversionThreshold + + + <p>When a spline is closer to a straight line than the specified real number weighted by the square of the curve length, maintain it as a straight line, even if it is a list with curves.</p> + + + + + textLabel8_2 + + + &Filter iterations: + + + autotraceIterations + + + <p>Smooth the curve the specified number of times prior to fitting</p> + + + + + autotraceErrorThreshold + + + 2 + + + <p>Subdivide fitted curves that are offset by a number of pixels exceeding the specified real number</p> + + + + + textLabel6_2 + + + &Error threshold: + + + autotraceErrorThreshold + + + <p>Subdivide fitted curves that are offset by a number of pixels exceeding the specified real number</p> + + + + + textLabel1_5 + + + &Line threshold: + + + autotraceLineThreshold + + + <p>If a spline does not deviate from the straight line defined by its endpoints by more than the specified number of pixels, then treat it as a straight line.</p> + + + + + autotracePreserveWidth + + + &Preserve width + + + Alt+P + + + <p>Preserve line width prior to thinning</p> + + + + + + + + + TabPage + + + &Various + + + + unnamed + + + + buttonGroup5 + + + Object recognition + + + + unnamed + + + + autotraceNoCenterline + + + &Outline + + + Alt+O + + + true + + + + + autotraceCenterline + + + C&enterline + + + Alt+E + + + false + + + + + + + groupBox15 + + + Tangent + + + + unnamed + + + + textLabel9 + + + &Surround: + + + autotraceTangentSurround + + + <p>Consider the specified number of points to either side of a point when computing the tangent at that point</p> + + + + + autotraceTangentSurround + + + 3 + + + 0 + + + <p>Consider the specified number of points to either side of a point when computing the tangent at that point</p> + + + + + + + spacer16 + + + Vertical + + + Expanding + + + + 20 + 110 + + + + + + groupBox16 + + + Despeckle + + + + unnamed + + + + autotraceDespeckleTightness + + + false + + + 2 + + + 8 + + + <p>Employ the specified real number as the value for despeckle tightness (range: 0-8)</p> + + + + + autotraceDespeckleLevel + + + false + + + 1 + + + 20 + + + <p>Employ the specified integer as the value for despeckling(range: 1-20)</p> + + + + + textLabel10 + + + &Level: + + + autotraceDespeckleLevel + + + <p>Employ the specified integer as the value for despeckling(range: 1-20)</p> + + + + + textLabel11_2 + + + T&ightness: + + + autotraceDespeckleTightness + + + <p>Employ the specified real number as the value for despeckle tightness (range: 0-8)</p> + + + + + autotraceDoDespeckle + + + despec&kle + + + Alt+K + + + + + + + + + + + + + + + + layout6 + + + + unnamed + + + + spacer12 + + + Horizontal + + + Expanding + + + + 40 + 20 + + + + + + kActiveLabel2 + + + + 7 + 0 + 0 + 0 + + + + NoFocus + + + Backend: + + + + + + potrace + + + + + autotrace + + + + backendCombo + + + + + spacer13 + + + Horizontal + + + Expanding + + + + 40 + 20 + + + + + + + + spacer7_2 + + + Vertical + + + Expanding + + + + 20 + 16 + + + + + + layout3 + + + + unnamed + + + + spacer3 + + + Horizontal + + + Expanding + + + + 113 + 20 + + + + + + traceBtn + + + &Trace + + + Alt+T + + + + + spacer4 + + + Horizontal + + + Expanding + + + + 60 + 20 + + + + + + defaultBtn + + + D&efault options + + + Alt+E + + + + + + + layout2 + + + + unnamed + + + + autoTraceCheck + + + Automatic Preview + + + + + + true + + + + + preserveCheck + + + Preserve options + + + + + + + + + + + opaque + toggled(bool) + backgroundBtn + setEnabled(bool) + + + scaleAllBTN + toggled(bool) + scaleAll + setEnabled(bool) + + + scaleXYBTN + toggled(bool) + textLabel9_3 + setEnabled(bool) + + + scaleXYBTN + toggled(bool) + scaleX + setEnabled(bool) + + + scaleXYBTN + toggled(bool) + textLabel10_3 + setEnabled(bool) + + + scaleXYBTN + toggled(bool) + scaleY + setEnabled(bool) + + + resolutionAllBTN + toggled(bool) + resolutionAll + setEnabled(bool) + + + resolutionXYBTN + toggled(bool) + textLabel1_2 + setEnabled(bool) + + + resolutionXYBTN + toggled(bool) + resolutionX + setEnabled(bool) + + + resolutionXYBTN + toggled(bool) + textLabel2_2 + setEnabled(bool) + + + resolutionXYBTN + toggled(bool) + resolutionY + setEnabled(bool) + + + outputFormat + activated(const QString&) + MainWidgetBase + showOptions(const QString&) + + + backendCombo + activated(const QString&) + MainWidgetBase + backendChoosen(const QString&) + + + autotraceDpiCheckbox + toggled(bool) + autotraceDpiInput + setEnabled(bool) + + + autotraceUseBackground + toggled(bool) + autotraceBackground + setEnabled(bool) + + + autotraceCheckBoxReduceColors + toggled(bool) + autotraceColorCount + setEnabled(bool) + + + marginsL + valueChanged(double) + MainWidgetBase + marginValueChanged(double) + + + marginsR + valueChanged(double) + MainWidgetBase + marginValueChanged(double) + + + marginsB + valueChanged(double) + MainWidgetBase + marginValueChanged(double) + + + marginsT + valueChanged(double) + MainWidgetBase + marginValueChanged(double) + + + checkBoxSyncronizeMargins + toggled(bool) + MainWidgetBase + syncronizeMarginsChanged(bool) + + + autotraceDoDespeckle + toggled(bool) + autotraceDespeckleLevel + setEnabled(bool) + + + autotraceDoDespeckle + toggled(bool) + autotraceDespeckleTightness + setEnabled(bool) + + + + tabWidget3 + blackLevel + invertInput + foregroundBtn + opaque + backgroundBtn + outputFormat + kActiveLabel1 + pageSize + optimizedNumericalCode + level2 + SVGGroup + antialiasGamma + scaleAllBTN + scaleAll + scaleXYBTN + scaleX + scaleY + policy + despeckle + cornerThreshold + optimizationTolerance + outputQuantization + curveOptimization + width + height + stretch + rotation + resolutionAllBTN + resolutionAll + resolutionX + resolutionY + marginsL + marginsR + marginsT + marginsB + checkBoxSyncronizeMargins + autotraceTabs + autotraceOutputFormat + autotraceDpiCheckbox + autotraceDpiInput + autotraceCheckBoxReduceColors + autotraceColorCount + autotraceUseBackground + autotraceBackground + autotraceLog + autotraceThreshold + autotraceAlwaysThreshold + autotraceSurround + autotraceAdjacentCorners + autotraceErrorThreshold + autotraceReversionThreshold + autotraceIterations + autotracePreserveWidth + autotraceNoCenterline + autotraceTangentSurround + autotraceDespeckleLevel + autotraceDespeckleTightness + kActiveLabel2 + backendCombo + traceBtn + defaultBtn + autoTraceCheck + preserveCheck + imagesTabs + + + showOptions( const QString & ) + backendChoosen( const QString & ) + valueChanged() + marginValueChanged( double ) + syncronizeMarginsChanged( bool isChecked ) + + + + knuminput.h + knuminput.h + kcolorbutton.h + kcolorbutton.h + ksqueezedtextlabel.h + kcombobox.h + kcombobox.h + klineedit.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + kactivelabel.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + kcombobox.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + kcombobox.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + kcolorbutton.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + knuminput.h + kactivelabel.h + kcombobox.h + kpushbutton.h + kpushbutton.h + + diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..377314a --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,34 @@ +# set the include path for X, qt and KDE +INCLUDES = $(all_includes) + +# these are the headers for your project +noinst_HEADERS = potracegui.h autotraceformats.h mainwidget.h options.h + +# let automoc handle all of the meta source files (moc) +METASOURCES = AUTO + +messages: rc.cpp + $(XGETTEXT) *.cpp -o $(podir)/potracegui.pot + +KDE_ICON = potracegui + +######################################################################### +# APPLICATION SECTION +######################################################################### +# this is the program that gets installed. it's name is used for all +# of the other Makefile.am variables +bin_PROGRAMS = potracegui + +# the application source, library search path, and link libraries +potracegui_SOURCES = main.cpp potracegui.cpp autotraceformats.cpp MainWidgetBase.ui mainwidget.cpp options.cpp +potracegui_LDFLAGS = $(KDE_RPATH) $(all_libraries) +potracegui_LDADD = $(LIB_KIO) $(LIB_KDEUI) + +# this is where the desktop file will go +shelldesktopdir = $(kde_appsdir)/Utilities +shelldesktop_DATA = potracegui.desktop + +# this is where the shell's XML-GUI resource file goes +shellrcdir = $(kde_datadir)/potracegui +shellrc_DATA = potraceguiui.rc + diff --git a/src/autotraceformats.cpp b/src/autotraceformats.cpp new file mode 100644 index 0000000..4f8ff9c --- /dev/null +++ b/src/autotraceformats.cpp @@ -0,0 +1,71 @@ +/*************************************************************************** + * Copyright (C) 2004 by Antonio Fasolato * + * Antonio.Fasolato@poste.it * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ +#include "autotraceformats.h" + +AutotraceFormats::AutotraceFormats(QObject *parent, const char *name): QObject(parent, name), allOK(true) { + inputProcess=new QProcess(this); + outputProcess=new QProcess(this); + + inputProcess->addArgument("autotrace"); + inputProcess->addArgument("--list-input-formats"); + + outputProcess->addArgument("autotrace"); + outputProcess->addArgument("--list-output-formats"); + + connect(inputProcess,SIGNAL(readyReadStderr()),this,SLOT(inputRead())); + connect(outputProcess,SIGNAL(readyReadStderr()),this,SLOT(outputRead())); + + if(!(inputProcess->start()) || !(outputProcess->start())) { + allOK=false; + } +} + +void AutotraceFormats::inputRead( ) { + while(inputProcess->canReadLineStderr()) { + input+=inputProcess->readLineStderr(); + } +} + +void AutotraceFormats::outputRead( ) { + while(outputProcess->canReadLineStderr()) { + QString tmp=outputProcess->readLineStderr(); + if(!(tmp.startsWith("Supported"))) + output+=tmp.stripWhiteSpace(); + } +} + +bool AutotraceFormats::OK( ) { + return allOK; +} + +bool AutotraceFormats::done( ) { + return (!(inputProcess->isRunning()) && !(outputProcess->isRunning())); +} + +QStringList AutotraceFormats::inputFormats( ) { + return input; +} + +QStringList AutotraceFormats::outputFormats( ) { + return output; +} + + +#include "autotraceformats.moc" diff --git a/src/autotraceformats.h b/src/autotraceformats.h new file mode 100644 index 0000000..00359d8 --- /dev/null +++ b/src/autotraceformats.h @@ -0,0 +1,86 @@ +/*************************************************************************** + * Copyright (C) 2004 by Antonio Fasolato * + * Antonio.Fasolato@poste.it * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ +#ifndef AUTOTRACEFORMATS_H +#define AUTOTRACEFORMATS_H + +#include +#include +#include + +//! Class to read autotrace input and output formats +/** This class executes autotrace to gain informations about the formats it can use + * \author Antonio Fasolato + */ +class AutotraceFormats : public QObject +{ +Q_OBJECT +public: + //! Standard QObject-like constructor + /** The constructor, nothing fancy + * \param parent The parent of the QObject + * \param name The name of the QObject + */ + AutotraceFormats(QObject *parent = 0, const char *name = 0); + //!Returns the list of supported input formats + /** This class returns the list of formats returned by autotrace -list-input-formats + * \return The supported formats + */ + QStringList inputFormats(); + //!Returns the list of supported output formats + /** This class returns the list of formats returned by autotrace -list-output-formats + * \return The supported formats + */ + QStringList outputFormats(); + //! Function to test the execution of autotrace + /** This functions returns true if the autotrace command could be run succesfully. If it returns + * false autotrace executable can not be found in the environment + * \return true if autotrace ran, false otherways + */ + bool OK(); + //! Tests if the class has ended its work + /** This class tests if the autotrace processes ended, thus completing the formats listing + * \return true if the processes has ended, false otherways + */ + bool done(); + +private: + //! The process to get input formats + QProcess *inputProcess; + //! The process to get output formats + QProcess *outputProcess; + //! The list of input formats + QStringList input; + //! The list of output formats + QStringList output; + //! true if autotrace could be run + bool allOK; + +private slots: + //! Reads from inputProcess stderr + /** Reads, when possible, the output of AutotraceFormats::inputProcess + */ + void inputRead(); + //! Reads from outputProcess stderr + /** Reads, when possible, the output of AutotraceFormats::outputProcess + */ + void outputRead(); +}; + +#endif diff --git a/src/hi16-app-potracegui.png b/src/hi16-app-potracegui.png new file mode 100644 index 0000000..1160eab Binary files /dev/null and b/src/hi16-app-potracegui.png differ diff --git a/src/hi32-app-potracegui.png b/src/hi32-app-potracegui.png new file mode 100644 index 0000000..82121d6 Binary files /dev/null and b/src/hi32-app-potracegui.png differ diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..d0d8a76 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,57 @@ +/*************************************************************************** + * Copyright (C) 2004 by Antonio Fasolato * + * Antonio.Fasolato@poste.it * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include "potracegui.h" + +#include +#include +#include +#include + +static const char description[] = + I18N_NOOP("An interface for potrace and autotrace"); + +static KCmdLineOptions options[] = +{ + { "+[URL]", I18N_NOOP( "Document to open" ), 0 }, + KCmdLineLastOption +}; + +int main(int argc, char **argv) +{ + KAboutData about("potracegui", I18N_NOOP("potracegui"), "1.3", description, + KAboutData::License_GPL, "(C) 2004 Antonio Fasolato", 0, 0, "Antonio.Fasolato@poste.it"); + about.addAuthor( "Antonio Fasolato", 0, "Antonio.Fasolato@poste.it" ); + about.addCredit( "Tim Fechtner", I18N_NOOP("German translation"), "Tim.Fechtner@gmx.de"); + KCmdLineArgs::init(argc, argv, &about); + KCmdLineArgs::addCmdLineOptions( options ); + KApplication app; + potracegui *firstWidget = 0; + + KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); + + firstWidget = new potracegui(); + firstWidget->show(); + + args->clear(); + + return app.exec(); +} + diff --git a/src/mainwidget.cpp b/src/mainwidget.cpp new file mode 100644 index 0000000..6e85ce1 --- /dev/null +++ b/src/mainwidget.cpp @@ -0,0 +1,1055 @@ +/*************************************************************************** + * Copyright (C) 2004 by Antonio Fasolato * + * Antonio.Fasolato@poste.it * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + + +#include "mainwidget.h" +#include "options.h" +#include "autotraceformats.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +using namespace std; + +MainWidget::MainWidget(QWidget* parent, const char* name, WFlags fl): MainWidgetBase(parent,name,fl), m_changed(false) { + KImageIO::registerFormats(); + + setAcceptDrops(true); + + /*Scrolled image viewers*/ + delete imagesTabs->page(0); + QScrollView *originalScroll=new QScrollView(this); + QScrollView *previewScroll=new QScrollView(this); + imagesTabs->addTab(originalScroll,i18n("Original image")); + imagesTabs->addTab(previewScroll,i18n("Preview")); + originalLabel=new QLabel(this); + previewLabel=new QLabel(this); + originalLabel->setGeometry(0,0,10,10); + previewLabel->setGeometry(0,0,10,10); + originalScroll->addChild(originalLabel); + previewScroll->addChild(previewLabel); + + /*Load default options*/ + marginValueSynconizingNecessary=true; + Options *o=new Options(); + o->defaultOptions(); + m_state.clear(); + m_oldPreviews.clear(); + m_state.push_back(o); + m_oldPreviews.push_back(QPixmap()); + m_currentState=m_state.begin(); + m_currentPreview=m_oldPreviews.begin(); + + connect(&tracer,SIGNAL(processExited()),this,SLOT(tracerExited())); + connect(&tracer,SIGNAL(wroteToStdin()),this,SLOT(writeCompleted())); + connect(traceBtn,SIGNAL(clicked()),this,SLOT(trace())); + connect(defaultBtn,SIGNAL(clicked()),this,SLOT(defaultOptions())); + + emit(signalChangeStatusbar(i18n("Checking autotrace formats."))); + AutotraceFormats *formats=new AutotraceFormats(); + if(formats->OK()) { + while(!(formats->done())); //wait till AutotraceFormats has finished + autotraceOutputFormat->insertStringList(formats->outputFormats()); + emit(signalChangeStatusbar(i18n("Done."))); + } + else { + emit(signalChangeStatusbar(i18n("Autotrace not found."))); + backendCombo->setEnabled(false); + } + + readOptions(); +} + +MainWidget::~MainWidget() { + if (tracer.isRunning()) + tracer.tryTerminate(); + if(m_tmpFilename!="") + deleteTmpFilename(); +} + +void MainWidget::fileOpen() { + KFileDialog d(QString::null,KImageIO::pattern(),this,i18n("Select an image"),true); + d.exec(); + + if(d.result()==QDialog::Accepted) + getImageFromURL(d.selectedURL()); +} + +void MainWidget::fileSave() { + if(m_outputFilename=="" && m_changed) + { + QString filter; + if(backendCombo->currentText()=="potrace") { //potrace formats + if((**m_currentState)["outputFormat"]==i18n("eps")) + filter=i18n("*.eps|Encapsulated postscript"); + else if((**m_currentState)["outputFormat"]==i18n("postscript")) + filter=i18n("*.ps|Postscript"); + else if((**m_currentState)["outputFormat"]==i18n("SVG")) + filter=i18n("*.svg|SVG images"); + else if((**m_currentState)["outputFormat"]==i18n("Gimp path")) + filter=i18n("*.*|Gimp path"); + else if((**m_currentState)["outputFormat"]==i18n("Xfig")) + filter=i18n("*.fig|XFig drawing"); + else + filter=i18n("*.pgm|PGM image"); + } + else { //autotrace formats + filter="*."+(**m_currentState)["outputFormat"]; + } + QString saveFilename=KFileDialog::getSaveFileName(QString::null,filter,this,i18n("Select the file to save to")); + + bool salva=false; + while(saveFilename!="") + { + int res; + if(QFile::exists(saveFilename)) + res=KMessageBox::warningYesNo(this, i18n("Overwrite %1 ?").arg(saveFilename)); + else + { + salva=true; + break; + } + if(res==KMessageBox::Yes) + { + salva=true; + break; + } + else + saveFilename=KFileDialog::getSaveFileName(QString::null,filter,this,i18n("Select the file to save to")); + } + + if(salva) + { + m_outputFilename=saveFilename; + ifstream in(m_tmpFilename); + ofstream out(m_outputFilename); + if(!in || !out) + { + emit signalChangeStatusbar(i18n(i18n("Error while saving file"))); + return; + } + emit signalChangeStatusbar(i18n("Saving %1...").arg(m_outputFilename)); + char ch; + while(in.get(ch)) + out.put(ch); + in.close(); + out.close(); + m_changed=false; + emit signalChangeStatusbar(i18n("File %1 saved.").arg(m_outputFilename)); + } + else + emit signalChangeStatusbar(i18n("File not saved")); + } + else if (m_changed) + { + ifstream in(m_tmpFilename); + ofstream out(m_outputFilename); + if(!in || !out) + { + emit signalChangeStatusbar(i18n("Error while saving file")); + return; + } + emit signalChangeStatusbar(i18n("Saving %1...").arg(m_outputFilename)); + char ch; + while(in.get(ch)) + out.put(ch); + + in.close(); + out.close(); + emit signalChangeStatusbar(i18n("File %1 saved.").arg(m_outputFilename)); + m_changed=false; + } +} + +void MainWidget::fileSaveAs() { + if(previewLabel->pixmap()!=0 || previewLabel->text()!="") + { + QString filter; + if(backendCombo->currentText()=="potrace") { //potrace formats + if((**m_currentState)["outputFormat"]==i18n("eps")) + filter=i18n("*.eps|Encapsulated postscript"); + else if((**m_currentState)["outputFormat"]==i18n("postscript")) + filter=i18n("*.ps|Postscript"); + else if((**m_currentState)["outputFormat"]==i18n("SVG")) + filter=i18n("*.svg|SVG images"); + else if((**m_currentState)["outputFormat"]==i18n("Gimp path")) + filter=i18n("*.*|Gimp path"); + else if((**m_currentState)["outputFormat"]==i18n("Xfig")) + filter=i18n("*.fig|XFig drawing"); + else + filter=i18n("*.pgm|PGM image"); + } + else { //autotrace formats + filter="*."+(**m_currentState)["outputFormat"]; + } + QString saveFilename=KFileDialog::getSaveFileName(QString::null,filter,this,i18n("Select the file to save to")); + + bool salva=false; + while(saveFilename!="") + { + int res; + if(QFile::exists(saveFilename)) + res=KMessageBox::warningYesNo(this,i18n("Overwrite %1 ?").arg(saveFilename)); + else + { + salva=true; + break; + } + if(res==KMessageBox::Yes) + { + salva=true; + break; + } + else + saveFilename=KFileDialog::getSaveFileName(QString::null,filter,this,i18n("Select the file to save to")); + } + + if(salva) + { + m_outputFilename=saveFilename; + ifstream in(m_tmpFilename); + ofstream out(m_outputFilename); + if(!in || !out) + { + emit signalChangeStatusbar(i18n("Error while saving file")); + return; + } + emit signalChangeStatusbar(i18n("Saving %1...").arg(m_outputFilename)); + char ch; + while(in.get(ch)) + out.put(ch); + in.close(); + out.close(); + m_changed=false; + emit signalChangeStatusbar(i18n("File %1 saved.").arg(m_outputFilename)); + } + else + emit signalChangeStatusbar(i18n("File not saved")); + } +} + +void MainWidget::fileClose() { + originalLabel->clear(); + originalLabel->setGeometry(0,0,10,10); + previewLabel->clear(); + previewLabel->setGeometry(0,0,10,10); + if(m_tmpFilename!="" && !deleteTmpFilename()) + emit signalChangeStatusbar(i18n("Warning: could not remove temporary file.")); + Options *o=new Options(); + o->defaultOptions(); + m_state.clear(); + m_oldPreviews.clear(); + m_state.push_back(o); + m_oldPreviews.push_back(QPixmap()); + m_currentState=m_state.begin(); + m_currentPreview=m_oldPreviews.begin(); + readOptions(); +} + +void MainWidget::cut() { + if(originalLabel->pixmap()!=0) + { + QApplication::clipboard()->setPixmap(QPixmap(*(originalLabel->pixmap()))); + fileClose(); + } +} + +void MainWidget::copy() { + if(originalLabel->pixmap()!=0) + { + QApplication::clipboard()->setPixmap(QPixmap(*(originalLabel->pixmap()))); + } +} + +void MainWidget::paste() { + QPixmap clip=QApplication::clipboard()->pixmap(); + if(!clip.isNull()) + { + if(!createTmpFilename()) + { + emit signalChangeStatusbar(i18n("Could not create temporary filename")); + return; + } + + m_outputFilename=""; + QPixmap pix(QApplication::clipboard()->pixmap()); + originalLabel->clear(); + originalLabel->setGeometry(0,0,pix.width(),pix.height()); + originalLabel->setPixmap(pix); + previewLabel->clear(); + previewLabel->setGeometry(0,0,10,10); + imagesTabs->setCurrentPage(0); + emit signalChangeStatusbar(i18n("Image pasted.")); + + Options *o=new Options(); + if (!preserveCheck->isChecked()) + { //I have to reset the options + o->defaultOptions(); + } + else + { + o=*m_currentState; + } + m_state.clear(); + m_oldPreviews.clear(); + m_state.push_back(o); + if(previewLabel->pixmap()!=0) + m_oldPreviews.push_back(*(previewLabel->pixmap())); + else + m_oldPreviews.push_back(QPixmap()); + m_currentState=m_state.begin(); + m_currentPreview=m_oldPreviews.begin(); + + readOptions(); + } +} + +void MainWidget::getImageFromURL(KURL url) { + QString filename; // prevent overwriting previous local file with current remote one + if (!url.isLocalFile()) + { // download to temporary file + if (!KIO::NetAccess::download(url,filename,this)) + emit signalChangeStatusbar(i18n("Selected URL is not a valid image.")); + return; + } + else + filename=url.path(); + + if(!createTmpFilename()) + { + emit signalChangeStatusbar(i18n("Could not create temporary filename.")); + return; + } + + m_outputFilename=""; + QPixmap pix(filename); + originalLabel->clear(); + originalLabel->setGeometry(0,0,pix.width(),pix.height()); + originalLabel->setPixmap(pix); + previewLabel->clear(); + previewLabel->setGeometry(0,0,10,10); + imagesTabs->setCurrentPage(0); + emit signalChangeStatusbar(i18n("File %1 loaded.").arg(filename)); + + if (!url.isLocalFile()) + KIO::NetAccess::removeTempFile(filename); + + Options *o=new Options(); + if (!preserveCheck->isChecked()) + { //I have to reset the options + o->defaultOptions(); + } + else + { + o=*m_currentState; + } + m_state.clear(); + m_oldPreviews.clear(); + m_state.push_back(o); + if(previewLabel->pixmap()!=0) + m_oldPreviews.push_back(*(previewLabel->pixmap())); + else + m_oldPreviews.push_back(QPixmap()); + m_currentState=m_state.begin(); + m_currentPreview=m_oldPreviews.begin(); + + readOptions(); +} + +void MainWidget::readOptions() { + //input + blackLevel->setValue(((**m_currentState)["blackLevel"]).toFloat()); + invertInput->setChecked((**m_currentState)["invertInput"]=="y"); + + //output + outputFormat->setCurrentText((**m_currentState)["outputFormat"]); + if((**m_currentState)["outputFormat"]==i18n("eps") || (**m_currentState)["outputFormat"]==i18n("postscript")) + { //eps format + pageSize->setCurrentText((**m_currentState)["pageSize"]); + optimizedNumericalCode->setChecked((**m_currentState)["optimizedNumericalCode"]=="y"); + level1->setChecked((**m_currentState)["compressionLevel"]=="1"); + level2->setChecked((**m_currentState)["compressionLevel"]=="2"); + level3->setChecked((**m_currentState)["compressionLevel"]=="3"); + } + else if((**m_currentState)["outputFormat"]==i18n("SVG")) //SVG format + SVGGroup->setChecked((**m_currentState)["SVGGroup"]=="y"); + else if((**m_currentState)["outputFormat"]==i18n("Gimp path")); //Gimp format + else if((**m_currentState)["outputFormat"]==i18n("Xfig path")); //Xfig format + else + { //pgm format + antialiasGamma->setValue(((**m_currentState)["antialiasGamma"]).toFloat()); + //Scale + if(((**m_currentState)["scale"]).find('x')==-1) + { //only one value + scaleAll->setValue(((**m_currentState)["scale"]).toFloat()); + scaleAllBTN->setChecked(true); + } + else + { + QString tmp=(**m_currentState)["scale"]; + scaleX->setValue((tmp.section('x',0,0)).toFloat()); + scaleY->setValue((tmp.section('x',1,1)).toFloat()); + scaleXYBTN->setChecked(true); + } + } + + //Color + foregroundBtn->setColor(QColor((**m_currentState)["foregroundBtn"])); + opaque->setChecked((**m_currentState)["opaque"]=="y"); + backgroundBtn->setColor(QColor((**m_currentState)["backgroundBtn"])); + + //Algorithm + policy->setCurrentItem(((**m_currentState)["policy"]).toInt()); + despeckle->setValue(((**m_currentState)["despeckle"]).toInt()); + cornerThreshold->setValue(((**m_currentState)["cornerThreshold"]).toFloat()); + optimizationTolerance->setValue(((**m_currentState)["optimizationTolerance"]).toFloat()); + outputQuantization->setValue(((**m_currentState)["outputQuantization"]).toInt()); + curveOptimization->setChecked((**m_currentState)["curveOptimization"]=="y"); + + //Transformation + width->setValue(((**m_currentState)["width"]).toFloat()); + height->setValue(((**m_currentState)["height"]).toFloat()); + stretch->setValue(((**m_currentState)["stretch"]).toFloat()); + rotation->setValue(((**m_currentState)["rotation"]).toFloat()); + + //Resolution + if(((**m_currentState)["resolution"]).find('x')==-1) + { //only one value + resolutionAll->setValue(((**m_currentState)["resolution"]).toFloat()); + resolutionAllBTN->setChecked(true); + } + else + { + QString tmp=(**m_currentState)["resolution"]; + resolutionX->setValue((tmp.section('x',0,0)).toFloat()); + resolutionY->setValue((tmp.section('x',1,1)).toFloat()); + resolutionXYBTN->setChecked(true); + } + + //Margins + QString tmp=(**m_currentState)["margins"]; + marginsL->setValue((tmp.section('x',0,0)).toFloat()); + marginsR->setValue((tmp.section('x',1,1)).toFloat()); + marginsT->setValue((tmp.section('x',2,2)).toFloat()); + marginsB->setValue((tmp.section('x',3,3)).toFloat()); + checkBoxSyncronizeMargins->setChecked((**m_currentState)["syncronizeMargins"]=="y"); + + //missing restoring for autotrace interface part + +} + +void MainWidget::getOptions() { + if(backendCombo->currentText()=="potrace") + getPotraceOptions(); + else + getAutotraceOptions(); +} + +void MainWidget::getPotraceOptions( ) { + //input-output + (*m_currentState)->setValue("blackLevel",QString::number(blackLevel->value())); + if(invertInput->isChecked()) + (*m_currentState)->setValue("invertInput","y"); + else + (*m_currentState)->setValue("invertInput","n"); + (*m_currentState)->setValue("outputFormat",outputFormat->currentText()); + if(outputFormat->currentText()==i18n("eps") || outputFormat->currentText()==i18n("postscript")) + { //ps options + (*m_currentState)->setValue("pageSize",pageSize->currentText()); + (*m_currentState)->setValue("optimizedNumericalCode",(optimizedNumericalCode->isChecked())?"y":"n"); + QButton *b=compressionLevel->selected(); + if(b->text()=="None") + (*m_currentState)->setValue("compressionLevel","1"); + else if(b->text()=="Level 2") + (*m_currentState)->setValue("compressionLevel","2"); + else + (*m_currentState)->setValue("compressionLevel","3"); + } + else if(outputFormat->currentText()==i18n("SVG")) + { //SVG options + (*m_currentState)->setValue("SVGGroup",(SVGGroup->isChecked())?"y":"n"); + } + else if(outputFormat->currentText()==i18n("Gimp path")) + { //Gimp options + } + else if(outputFormat->currentText()==i18n("Xfig")) + { //Xfig options + } + else + { //pgm options + (*m_currentState)->setValue("antialiasGamma",QString::number(antialiasGamma->value())); + //Scale + if(scaleAll->isEnabled()) + (*m_currentState)->setValue("scale",QString::number(scaleAll->value())); + else + (*m_currentState)->setValue("scale",QString::number(scaleX->value())+"x"+QString::number(scaleY->value())); + } + + //Color + QColor c=foregroundBtn->color(); + (*m_currentState)->setValue("foregroundBtn",c.name()); + (*m_currentState)->setValue("opaque",(opaque->isChecked())?"y":"n"); + c=backgroundBtn->color(); + (*m_currentState)->setValue("backgroundBtn",c.name()); + + //Algorithm + (*m_currentState)->setValue("policy",QString::number(policy->currentItem())); + (*m_currentState)->setValue("despeckle",QString::number(despeckle->value())); + (*m_currentState)->setValue("cornerThreshold",QString::number(cornerThreshold->value())); + (*m_currentState)->setValue("optimizationTolerance",QString::number(optimizationTolerance->value())); + (*m_currentState)->setValue("outputQuantization",QString::number(outputQuantization->value())); + (*m_currentState)->setValue("curveOptimization",(curveOptimization->isChecked())?"y":"n"); + + //Transformation + (*m_currentState)->setValue("width",QString::number(width->value())); + (*m_currentState)->setValue("height",QString::number(height->value())); + (*m_currentState)->setValue("stretch",QString::number(stretch->value())); + (*m_currentState)->setValue("rotation",QString::number(rotation->value())); + + //Resolution + if(resolutionAll->isEnabled()) + (*m_currentState)->setValue("resolution",QString::number(resolutionAll->value())); + else + (*m_currentState)->setValue("resolution",QString::number(resolutionX->value())+"x"+QString::number(resolutionY->value())); + + //Margins + (*m_currentState)->setValue("syncronizeMargins",checkBoxSyncronizeMargins->isChecked()?"y":"n"); + (*m_currentState)->setValue("margins",QString::number(marginsL->value())+"x"+QString::number(marginsR->value())+"x"+QString::number(marginsT->value())+"x"+QString::number(marginsB->value())); +} + +void MainWidget::getAutotraceOptions( ) { + Options *opt=*m_currentState; + + opt->clear(); + + //input output + QString tmp=autotraceOutputFormat->currentText(); + tmp.truncate(tmp.find(" ")); + opt->setValue("outputFormat",tmp); + if(autotraceDpiCheckbox->isChecked() && autotraceDpiInput->value()!=0) + opt->setValue("dpi",QString::number(autotraceDpiInput->value())); + opt->setValue("reduceColorsEnabled",(autotraceCheckBoxReduceColors->isChecked())?"y":"n"); + opt->setValue("colorCount",QString::number(autotraceColorCount->value())); + if(autotraceUseBackground->isChecked()) + opt->setValue("background",autotraceBackground->color().name().upper()); + if(autotraceLog->isChecked()) + opt->setValue("log","y"); + + //corners and curves + if(autotraceThreshold->value()!=100) + opt->setValue("threshold",QString::number(autotraceThreshold->value())); + if(autotraceAlwaysThreshold->value()!=60) + opt->setValue("alwaysThreshold",QString::number(autotraceAlwaysThreshold->value())); + if(autotraceSurround->value()!=4) + opt->setValue("surround",QString::number(autotraceSurround->value())); + if(autotraceAdjacentCorners->isChecked()) + opt->setValue("removeAdjacentCorners","y"); + if(autotraceErrorThreshold->value()!=2) + opt->setValue("errorThreshold",QString::number(autotraceErrorThreshold->value())); + if(autotraceLineThreshold->value()!=1) + opt->setValue("lineThreshold",QString::number(autotraceLineThreshold->value())); + if(autotraceReversionThreshold->value()!=0.01) + opt->setValue("reversionThreshold",QString::number(autotraceReversionThreshold->value())); + if(autotraceIterations->value()!=4) + opt->setValue("iterations",QString::number(autotraceIterations->value())); + if(autotracePreserveWidth->isChecked()) + opt->setValue("preserveWidth","y"); + + //various + if(autotraceCenterline->isChecked()) + opt->setValue("centerline","y"); + if(autotraceTangentSurround->value()!=3) + opt->setValue("tangentSurround",QString::number(autotraceTangentSurround->value())); + + //despeckle + opt->setValue("doDespeckle",(autotraceDoDespeckle->isChecked()?"y":"n")); + opt->setValue("despeckleLevel",QString::number(autotraceDespeckleLevel->value())); + opt->setValue("despeckleTightness",QString::number(autotraceDespeckleTightness->value())); +} + +QStringList MainWidget::createCommandLine() { + if(backendCombo->currentText()=="potrace") + return createPotraceCommandLine(); + else + return createAutotraceCommandLine(); +} + +QStringList MainWidget::createPotraceCommandLine( ) { + QStringList toReturn; + toReturn+="potrace"; + + //input + if((**m_currentState)["blackLevel"]!="0.5") //only if it is not the default value + toReturn+="-k"+(**m_currentState)["blackLevel"]; + if((**m_currentState)["invertInput"]=="y") + toReturn+="-i"; + + //output + toReturn+="-o"; + toReturn+=m_tmpFilename; + if((**m_currentState)["outputFormat"]==i18n("eps")) + { //eps format + toReturn+="-e"; + toReturn+="-P"+(**m_currentState)["pageSize"]; + toReturn+="-C"+(**m_currentState)["foregroundBtn"]; + if((**m_currentState)["opaque"]=="y") + { + toReturn+="--opaque"; + //toReturn+="--fillcolor"+(**m_currentState)["backgroundBtn"]; + } + if((**m_currentState)["optimizedNumericalCode"]=="n") + toReturn+="-q"; + if((**m_currentState)["compressionLevel"]=="1") + toReturn+="-c"; + if((**m_currentState)["compressionLevel"]=="2") + toReturn+="-2"; + if((**m_currentState)["compressionLevel"]=="3") + toReturn+="-3"; + } + else if((**m_currentState)["outputFormat"]==i18n("postscript")) + { //ps format + toReturn+="-p"; + toReturn+="-P"+(**m_currentState)["pageSize"]; + toReturn+="-C"+(**m_currentState)["foregroundBtn"]; + if((**m_currentState)["opaque"]=="y") + { + toReturn+="--opaque"; + //toReturn+="--fillcolor"+(**m_currentState)["backgroundBtn"]; + } + if((**m_currentState)["optimizedNumericalCode"]=="n") + toReturn+="-q"; + if((**m_currentState)["compressionLevel"]=="1") + toReturn+="-c"; + if((**m_currentState)["compressionLevel"]=="2") + toReturn+="-2"; + if((**m_currentState)["compressionLevel"]=="3") + toReturn+="-3"; + } + else if((**m_currentState)["outputFormat"]==i18n("SVG")) + { //SVG format + toReturn+="-s"; + toReturn+="-C"+(**m_currentState)["foregroundBtn"]; + if((**m_currentState)["opaque"]=="y") + { + toReturn+="--opaque"; + //toReturn+="--fillcolor"+(**m_currentState)["backgroundBtn"]; + } + if((**m_currentState)["SVGGroup"]=="y") + toReturn+="--group"; + } + else if((**m_currentState)["outputFormat"]==i18n("Gimp path")) + { //Gimp format + toReturn+="-bgimppath"; + } + else if((**m_currentState)["outputFormat"]==i18n("Xfig")) + { //Xfig format + toReturn+="-bxfig"; + toReturn+="-C"+(**m_currentState)["foregroundBtn"]; + if((**m_currentState)["opaque"]=="y") + { + toReturn+="--opaque"; + //toReturn+="--fillcolor"+(**m_currentState)["backgroundBtn"]; + } + } + else + { //pgm format + toReturn+="-g"; + toReturn+="-G"+(**m_currentState)["antialiasGamma"]; + if((**m_currentState)["opaque"]=="y") + { + toReturn+="--opaque"; + //toReturn+="--fillcolor"+(**m_currentState)["backgroundBtn"]; + } + } + + //Algorithm + switch((**m_currentState)["policy"].toInt()) { + case 0: + toReturn+="-zblack"; + break; + case 1: + toReturn+="-zwhite"; + break; + case 2: + toReturn+="-zright"; + break; + case 3: + toReturn+="-zleft"; + break; + case 4: + toReturn+="-zminority"; + break; + case 5: + toReturn+="-zmajority"; + break; + case 6: + toReturn+="-zrandom"; + break; + default: + toReturn+="-zminority"; + break; + } + toReturn+="-t"+(**m_currentState)["despeckle"]; + toReturn+="-a"+(**m_currentState)["cornerThreshold"]; + toReturn+="-O"+(**m_currentState)["optimizationTolerance"]; + toReturn+="-u"+(**m_currentState)["outputQuantization"]; + if((**m_currentState)["curveOptimization"]=="n") + toReturn+="-n"; + + //Transformation + if((**m_currentState)["width"]!="0") + toReturn+="-W"+(**m_currentState)["width"]+"cm"; + if((**m_currentState)["height"]!="0") + toReturn+="-H"+(**m_currentState)["height"]+"cm"; + if((**m_currentState)["stretch"]!="1") + toReturn+="-S"+(**m_currentState)["stretch"]; + if((**m_currentState)["rotation"]!="0") + toReturn+="-A"+(**m_currentState)["rotation"]; + + //Resolution + if((**m_currentState)["resolution"]!="0" && (**m_currentState)["resolution"]!="0x0") + toReturn+="-r"+(**m_currentState)["resolution"]; + + //Margins + if((**m_currentState)["margins"]!="0" && (**m_currentState)["margins"]!="0x0x0x0") + { + if((**m_currentState)["margins"].find('x')==-1) + toReturn+="-M"+(**m_currentState)["margins"]+"cm"; + else + { + QString tmp=(**m_currentState)["margins"]; + toReturn+="-L"+tmp.section('x',0,0)+"cm"; + toReturn+="-R"+tmp.section('x',1,1)+"cm"; + toReturn+="-T"+tmp.section('x',2,2)+"cm"; + toReturn+="-B"+tmp.section('x',3,3)+"cm"; + } + } + + return toReturn; +} + +QStringList MainWidget::createAutotraceCommandLine( ) { + QStringList toReturn; + QString tmp; + toReturn+="autotrace"; + + //iput-output + toReturn+="--output-file"; + toReturn+=m_tmpFilename; + toReturn+="-output-format"; + toReturn+=(**m_currentState)["outputFormat"]; + if((**m_currentState)["dpi"]!="") + toReturn+="--dpi="+(**m_currentState)["dpi"]; + if((**m_currentState)["reduceColorsEnabled"]=="y") + toReturn+="--color-count="+(**m_currentState)["colorCount"]; + if((**m_currentState)["background"]!="") { + tmp=(**m_currentState)["background"]; + tmp=tmp.right(tmp.length()-1); + toReturn+="-background-color="+tmp; + } + if((**m_currentState)["log"]=="y") + toReturn+="-log"; + + //corner and curves + if((**m_currentState)["threshold"]!="") + toReturn+="--corner-threshold="+(**m_currentState)["threshold"]; + if((**m_currentState)["alwaysThreshold"]!="") + toReturn+="--corner-always-threshold="+(**m_currentState)["alwaysThreshold"]; + if((**m_currentState)["surround"]!="") + toReturn+="--corner-surround="+(**m_currentState)["surround"]; + if((**m_currentState)["removeAdjacentCorners"]=="y") + toReturn+="--remove-adjacent-corners"; + if((**m_currentState)["errorThreshold"]!="") + toReturn+="--error-threshold="+(**m_currentState)["errorThreshold"]; + if((**m_currentState)["lineThreshold"]!="") + toReturn+="--line-threshold="+(**m_currentState)["lineThreshold"]; + if((**m_currentState)["reversionThreshold"]!="") + toReturn+="--line-reversion-threshold="+(**m_currentState)["reversionThreshold"]; + if((**m_currentState)["iterations"]!="") + toReturn+="--filter-iterations="+(**m_currentState)["iterations"]; + if((**m_currentState)["preserveWidth"]=="y") + toReturn+="--preserve-width"; + + //various + if((**m_currentState)["centerline"]=="y") + toReturn+="--centerline"; + if((**m_currentState)["tangentSurround"]!="") + toReturn+="--tangent-surround="+(**m_currentState)["tangentSurround"]; + + //despeckle + if((**m_currentState)["doDespeckle"]=="y") { + toReturn+="--despeckle-level="+(**m_currentState)["despeckleLevel"]; + toReturn+="--despeckle-tightness="+(**m_currentState)["despeckleTightness"]; + }; + + //input file + char inputFile[]="/tmp/potraceguiTmp-XXXXXX"; + mkstemp(inputFile); + m_tmpInputFilename=QString(inputFile); + originalLabel->pixmap()->save(m_tmpInputFilename,"PPM"); + toReturn+="--input-format=PPM"; + toReturn+=m_tmpInputFilename; + + qDebug("Executed:\n%s",toReturn.join(" ").ascii()); + + return toReturn; +} + +void MainWidget::trace() { + if(originalLabel->pixmap()==0) + { + emit(signalChangeStatusbar(i18n("You must open an image first."))); + return; + } + setCursor(WaitCursor); + if (tracer.isRunning()) + { // already tracing, this means abort + aborted=true; + tracer.tryTerminate(); + return; + } + aborted=false; + + getOptions(); + QStringList commandLine=createCommandLine(); + tracer.clearArguments(); + tracer.setArguments(commandLine); + + if(!(tracer.start())) + { + previewLabel->setText(i18n("The process couldn't be started\nThe process executed was:\n")+commandLine.join(" ")); + emit(signalChangeStatusbar("Error executing command")); + setCursor(ArrowCursor); + imagesTabs->setCurrentPage(1); + } + else + { + emit(signalChangeStatusbar(i18n("Tracing..."))); + traceBtn->setText(i18n("Abort")); + QByteArray pixData; + QBuffer buf(pixData); + buf.open(IO_WriteOnly); + originalLabel->pixmap()->save(&buf,"PPM"); + tracer.writeToStdin(pixData); + } +} + +void MainWidget::tracerExited() { + traceBtn->setText(i18n("&Trace")); + if (aborted) + { + emit(signalChangeStatusbar(i18n("Aborted"))); + setCursor(ArrowCursor); + return; + } + if(tracer.exitStatus()!=0) + { + emit(signalChangeStatusbar(i18n("Finished with errors"))); + QString tmp(i18n("Error during the process:")); + tmp+=i18n("Standard output:\n"); + QString t=tracer.readLineStdout(); + while(t!=QString::null) + { + tmp+= t+"\n"; + t=tracer.readLineStdout(); + } + tmp+=i18n("Standard error:\n"); + t=tracer.readLineStderr(); + while(t!=QString::null) + { + tmp+=t+"\n"; + t=tracer.readLineStderr(); + } + QStringList l=tracer.arguments(); + tmp+=i18n("Executed:\n")+l.join(" "); + previewLabel->setText(tmp); + setCursor(ArrowCursor); + imagesTabs->setCurrentPage(1); + return; + } + + if(autoTraceCheck->isChecked()) + { + emit(signalChangeStatusbar(i18n("Loading preview image..."))); + QImage img(m_tmpFilename); + QPixmap pix; + if(pix.convertFromImage(img,0)) + { + previewLabel->clear(); + previewLabel->setGeometry(0,0,pix.width(),pix.height()); + previewLabel->setPixmap(pix); + } + else + { + emit(signalChangeStatusbar(i18n("Output format not recognized"))); + previewLabel->setText(i18n("Sorry, but the image format which you are working with\nis not recognized by KDE.\nThe image will be correctly saved if you want to,\nbut to see a preview try working with another image format (EPS and PGM showld work well)\nand only when you are satisfied with the result revert to the format\nof your choiche and save the result.")); + imagesTabs->setCurrentPage(1); + setCursor(ArrowCursor); + return; + } + + imagesTabs->setCurrentPage(1); + } + + //delete autotrace tempfile + if(backendCombo->currentText()=="autotrace") { + QFile tmp(m_tmpInputFilename); + tmp.remove(); + } + + setCursor(ArrowCursor); + m_changed=true; + emit(signalChangeStatusbar(i18n("Image traced"))); +} + +void MainWidget::writeCompleted() { + tracer.closeStdin(); +} + +bool MainWidget::createTmpFilename() { + char tmp[]="/tmp/potraceguiTmp-XXXXXX"; + if (mkstemp(tmp)!=-1) + { + m_tmpFilename=QString(tmp); + return true; + } + else + return false; +} + +bool MainWidget::deleteTmpFilename() { + QFile tmp(m_tmpFilename); + bool toReturn=tmp.remove(); + if(toReturn==true) + m_tmpFilename=""; + return toReturn; +} + +int MainWidget::notificationDialog(QString caption, QString text) { + KDialogBase w(this, "potracegui", true, caption, KDialogBase::Ok|KDialogBase::Cancel,KDialogBase::Ok,true); + w.setMainWidget(new QLabel(text,&w)); + w.exec(); + return w.result(); +} + +void MainWidget::dragEnterEvent(QDragEnterEvent* event) { + event->accept(KURLDrag::canDecode(event)); +} + +void MainWidget::dropEvent(QDropEvent* event) { + KURL::List urls; + if (KURLDrag::decode(event,urls)) + { + getImageFromURL(urls[0]); + } +} + +void MainWidget::defaultOptions() { + /*Load default options*/ + backendCombo->setCurrentItem(0); + backendStack->raiseWidget(potracePage); + Options *o=new Options(); + o->defaultOptions(); + m_state.clear(); + m_oldPreviews.clear(); + m_state.push_back(o); + m_oldPreviews.push_back(QPixmap()); + m_currentState=m_state.begin(); + m_currentPreview=m_oldPreviews.begin(); + + //default options for autotrace + autotraceTabs->setCurrentPage(0); + autotraceOutputFormat->setCurrentItem(0); + autotraceDpiCheckbox->setChecked(false); + autotraceDpiInput->setValue(0); + autotraceCheckBoxReduceColors->setChecked(true); + autotraceColorCount->setValue(2); + autotraceUseBackground->setChecked(false); + autotraceBackground->setColor("#ffffff"); + autotraceLog->setChecked(false); + autotraceThreshold->setValue(100); + autotraceAlwaysThreshold->setValue(60); + autotraceSurround->setValue(4); + autotraceAdjacentCorners->setChecked(false); + autotraceErrorThreshold->setValue(2); + autotraceLineThreshold->setValue(1); + autotraceReversionThreshold->setValue(0.01); + autotraceIterations->setValue(4); + autotracePreserveWidth->setChecked(false); + autotraceNoCenterline->setChecked(true); + autotraceTangentSurround->setValue(3); + autotraceDoDespeckle->setChecked(false); + autotraceDespeckleLevel->setValue(1); + autotraceDespeckleTightness->setValue(2); + + readOptions(); + optionsStack->raiseWidget(psPage); +} + +void MainWidget::showOptions(const QString &selection) { + if(selection==i18n("SVG")) + optionsStack->raiseWidget(svgPage); + else if(selection==i18n("pgm")) + optionsStack->raiseWidget(pgmPage); + else if(selection==i18n("postscript") || selection==i18n("eps")) + optionsStack->raiseWidget(psPage); + else + optionsStack->raiseWidget(undefinedPage); +} + +void MainWidget::backendChoosen( const QString & back ) { + if(back=="potrace") + backendStack->raiseWidget(potracePage); + else + backendStack->raiseWidget(autotracePage); +} + +void MainWidget::marginValueChanged( double newValue) { + if (marginValueSynconizingNecessary and checkBoxSyncronizeMargins->isChecked()) { + marginValueSynconizingNecessary=false; + marginsL->setValue(newValue); + marginsR->setValue(newValue); + marginsT->setValue(newValue); + marginsB->setValue(newValue); + marginValueSynconizingNecessary=true; + } +} + +#include "mainwidget.moc" diff --git a/src/mainwidget.h b/src/mainwidget.h new file mode 100644 index 0000000..51f65fc --- /dev/null +++ b/src/mainwidget.h @@ -0,0 +1,200 @@ +/*************************************************************************** + * Copyright (C) 2004 by Antonio Fasolato * + * Antonio.Fasolato@poste.it * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#ifndef MAINWIDGET_H +#define MAINWIDGET_H + +#include "MainWidgetBase.h" + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +using namespace std; + +class Options; + +//! The app's main widget +/*! + * \author Antonio Fasolato + * \version 1.2 + * + * This is the widget containing all the facilities to work with the image the user is tracing. It shows the current image and potrace output (if it exists), an interface to set the options and the buttons to control the execution of potrace. + */ +class MainWidget : public MainWidgetBase +{ + Q_OBJECT + + //! For simplicity + friend class potracegui; + +public: + //! Default constructor (all parameters are simply passed to MainWidgetBase) + MainWidget(QWidget* parent = 0, const char* name = 0, WFlags fl = 0 ); + //! Default destructor + ~MainWidget(); + +private: + //! Contains the temporary file name used while tracing + QString m_tmpFilename; + //! Contains the input file name for autotrace + QString m_tmpInputFilename; + //! Contains the real file name where to save the traced image + QString m_outputFilename; + //! The process of potrace (used to abort it and to control its exit status) + QProcess tracer; + //! To know if the tracing has exited normally, or it has been interrupted + bool aborted; + //! To know if the current document is different from the saved one + bool m_changed; + //! The history of the options (not used yet, it will permit undo/redo in the future) + vector m_state; + //! The history of the previews (not used yet, it will permit undo/redo in the future) + vector m_oldPreviews; + //! The current options + vector::iterator m_currentState; + //! The current preview image + vector::iterator m_currentPreview; + //! Label to display the original image + QLabel *originalLabel; + //! Label to display the traced image + QLabel *previewLabel; + + //! Retrives an image from an URL + /*! + * \param url The url of the image + * + * Retrives an image from an URL and loads into the original image viewer: if it is a local file, it simply loads it, if it is a remote URL, first it downloads it, then it loads it.
+ * After loading the image, it resets the options for the document (unless otherwise specified by the user.) + */ + void getImageFromURL(KURL url); + //! Gets the options from m_currentState and sets up all the widget from this informations + /*! + * \sa getOptions() + */ + void readOptions(); + //! Gets the options from all the widget and saves them into m_currentState + /*! + * \sa readOptions() + */ + void getOptions(); + //! Gets the options for potrace from all the widget and saves them into m_currentState + /*! + * \sa readOptions() + */ + void getPotraceOptions(); + //! Gets the options for autotrace from all the widget and saves them into m_currentState + /*! + * \sa readOptions() + */ + void getAutotraceOptions(); + //! Creates the command line for tracing + /*! + * It reads m_currentState and creates from all the options a commandline to be executed + * \returns A QStringList that can be used as a commandline to a QProcess + */ + QStringList createCommandLine(); + //! Creates the command line for tracing with potrace + /*! + * It reads m_currentState and creates from all the options a commandline to be executed + * \returns A QStringList that can be used as a commandline to a QProcess + */ + QStringList createPotraceCommandLine(); + //! Creates the command line for tracing with autotrace + /*! + * It reads m_currentState and creates from all the options a commandline to be executed + * \returns A QStringList that can be used as a commandline to a QProcess + */ + QStringList createAutotraceCommandLine(); + //! Sets m_tmpFilename to a new temporary filename (generated through mkstemp()) + bool createTmpFilename(); + //! Deletes the file pointed by m_tmpFilename + bool deleteTmpFilename(); + //! Shows a KDialog whit nformations + /*! + * \param caption The caption of the dialog + * \param text The text to display into the dialog + * \returns The code of the dialog button pressed. + */ + int notificationDialog(QString caption, QString text); + //! Accepts only a KURL + void dragEnterEvent(QDragEnterEvent* event); + //! Receives a KURL and loads it. + /*! + * \sa getImageFromURL() + */ + void dropEvent(QDropEvent* event); + +private slots: + //! Opens a file (whith a KFileDialog) + void fileOpen(); + //! Saves the current image + void fileSave(); + //! Saves the current image whith an alternate name + void fileSaveAs(); + //! Closes the file (and the window) + void fileClose(); + //! Cuts the original image into the clipboard + void cut(); + //! Copies the current image into the clipboard + void copy(); + //! Gets an image (if any) from the clipboard + void paste(); + //! Executed when the tracer process has ended. + /*! + * Executed when the tracer process has ended. If the process was successful it loads the traced image into the preview widget (unless otherways specified by the user) + */ + void tracerExited(); + //! Closes tracer stdin after passing the original image to it + void writeCompleted(); + //! Executes potrace whith the options specified by the user + /*! + * \sa createCommandLine() + */ + void trace(); + //! Reverts to the default options + void defaultOptions(); + //! When an output format for potrace has been selected, it shows the relevant options + void showOptions(const QString &selection); + //! When a backend has been selected, it shows the relevant options + void backendChoosen(const QString &back); + //! Syncronize margins if corresponding checkbox is checked + void marginValueChanged( double newValue); + + +signals: + //! Emitted to change the statusbar + /*! + * \param message The message to display into the statusbar + */ + void signalChangeStatusbar(QString message); +protected: + bool marginValueSynconizingNecessary; +}; + +#endif + diff --git a/src/options.cpp b/src/options.cpp new file mode 100644 index 0000000..e3aaa71 --- /dev/null +++ b/src/options.cpp @@ -0,0 +1,87 @@ +/*************************************************************************** + * Copyright (C) 2003 by Antonio Fasolato * + * Antonio.Fasolato@poste.it * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ +#include "options.h" + +#include +#include +using namespace std; + +#include + +Options::Options(): options() +{ +} + +void Options::setValue(QString key, QString value) { + if(options.find(key)!=options.end()) + options.erase(options.find(key)); + map::value_type v(key,value); + options.insert(v); +} + +bool Options::isEmpty() { + return options.empty(); +} + +void Options::clear() { + options.clear(); +} + +QString Options::operator[](QString key) { + if(options.find(key)!=options.end()) + return options[key]; + else + return ""; +} + +void Options::defaultOptions(){ + clear(); + + //input-output + setValue("blackLevel","0.5"); + setValue("invertInput","n"); + setValue("outputFileName",""); + setValue("outputFormat","eps"); + setValue("pageSize","letter"); + setValue("optimizedNumericalCode","y"); + setValue("compressionLevel","2"); + + //Color + setValue("foregroundBtn","#000000"); + setValue("backgroundBtn","#F8F9FB"); + + //Algorithm + setValue("policy","4"); + setValue("despeckle","0"); + setValue("cornerThreshold","1.00"); + setValue("optimizationTolerance","0.2"); + setValue("outputQuantization","10"); + setValue("curveOptimization","y"); + + //Transformation + setValue("width","0.0"); + setValue("height","0.0"); + setValue("stretch","1.0"); + setValue("rotation","0.0"); + + //Resolution + setValue("resolution","0.0"); + + //Margins + setValue("syncronizeMargins","y"); + setValue("margins","0.0"); +} + +void Options::debug() { + for(map::iterator i=options.begin(); i!=options.end(); i++) + cout << (*i).first << "=" << (*i).second << endl; +} + + diff --git a/src/options.h b/src/options.h new file mode 100644 index 0000000..3ab53c0 --- /dev/null +++ b/src/options.h @@ -0,0 +1,66 @@ +/*************************************************************************** + * Copyright (C) 2003 by Antonio Fasolato * + * Antonio.Fasolato@poste.it * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ +#ifndef OPTIONS_H +#define OPTIONS_H + +#include +using namespace std; + +#include + + +//! Class that contains all the options for a document. +/*! + * \author Antonio Fasolato + * \version 1.0 + * + * Class that contains all the options for a document. These options regards the most disparate values: output formats, algorithm to use with potrace...
+ * Mainly this class contains options relevant to potrace. + */ +class Options{ +public: + //! Default constructor + Options(); + + //! Sets a pair (key,value) in this Options object. + /*! + * \param key The name of the option. Later on it will be used to read its value + * \param value The value associated with the key + * + * Sets a pair (key,value) in this Options object. If name is not in this object, it is added. + * + * \sa operator[]() + */ + void setValue(QString key, QString value); + //! Checks if the object contains no keys + /*! + * \returns \b true if the object is empty, \b false otherwise + */ + bool isEmpty(); + //! Clears all the options in the object + void clear(); + + //! Retrives an option value from the key associated whith it + /*! + * \param key the key of the option to retrive + * \returns The value associated with the key + * \sa setValue() + */ + QString operator[](QString key); + //! Sets all the options to their default value. + void defaultOptions(); + //! Prints the list of options + void debug(); + +private: + map options; /*!< The map containing the options */ +}; + +#endif diff --git a/src/potracegui.cpp b/src/potracegui.cpp new file mode 100644 index 0000000..70168b2 --- /dev/null +++ b/src/potracegui.cpp @@ -0,0 +1,158 @@ +/*************************************************************************** + * Copyright (C) 2004 by Antonio Fasolato * + * Antonio.Fasolato@poste.it * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include "potracegui.h" +#include "mainwidget.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +potracegui::potracegui() + : KMainWindow( 0, "potracegui" ), m_centralWidget(new MainWidget(this)) +{ + // set the shell's ui resource file + setXMLFile("potraceguiui.rc"); + KImageIO::registerFormats(); + + setCentralWidget(m_centralWidget); + + setAcceptDrops(true); + + statusBar()->show(); + statusBar()->message(i18n("Welcome to PotraceGui 1.3")); + setAutoSaveSettings(); + setAcceptDrops(true); + + connect(m_centralWidget,SIGNAL(signalChangeStatusbar(QString)),this,SLOT(changeStatusbar(QString))); + + createInterface(); +} + +potracegui::~potracegui() +{ +} + +void potracegui::createInterface() +{ + /*handled by potracegui*/ + KStdAction::openNew(this, SLOT(fileNew()),actionCollection()); + KStdAction::quit(this, SLOT(quit()),actionCollection()); + m_toolbarAction=KStdAction::showToolbar(this, SLOT(showToolbar()),actionCollection()); + m_statusbarAction=KStdAction::showStatusbar(this, SLOT(showStatusbar()),actionCollection()); + KStdAction::keyBindings(this, SLOT(configureKeys()),actionCollection()); + KStdAction::configureToolbars(this, SLOT(configureTB()),actionCollection()); + + /*handled by MainWidget*/ + KStdAction::open(m_centralWidget, SLOT(fileOpen()),actionCollection()); + KStdAction::save(m_centralWidget, SLOT(fileSave()),actionCollection()); + KStdAction::saveAs(m_centralWidget, SLOT(fileSaveAs()),actionCollection()); + KStdAction::close(m_centralWidget, SLOT(fileClose()),actionCollection()); + KStdAction::cut(m_centralWidget, SLOT(cut()),actionCollection()); + KStdAction::copy(m_centralWidget, SLOT(copy()),actionCollection()); + KStdAction::paste(m_centralWidget, SLOT(paste()),actionCollection()); + + /*Create menu and toolbar*/ + createGUI(); +} + + +//MENU ACTIONS +void potracegui::fileNew() +{ + (new potracegui)->show(); +} + +void potracegui::quit() +{ + close(); +} + +void potracegui::showToolbar() +{ + if(m_toolbarAction->isChecked()) + toolBar()->show(); + else + toolBar()->hide(); +} + +void potracegui::showStatusbar() +{ + if(m_statusbarAction->isChecked()) + statusBar()->show(); + else + statusBar()->hide(); +} + +void potracegui::configureKeys() +{ + KKeyDialog::configure(actionCollection(),"potraceguiui.rc"); +} + +void potracegui::configureTB() +{ + KEditToolbar dlg(actionCollection()); + connect(&dlg,SIGNAL(newToolbarConfig()),this,SLOT(NewTBConfig())); + dlg.exec(); +} + +void potracegui::NewTBConfig() +{ + createGUI(); + saveMainWindowSettings(KGlobal::config()); +} + +void potracegui::changeStatusbar(QString message) +{ + statusBar()->message(message); +} + +bool potracegui::queryClose() { + if(m_centralWidget->m_changed) { + int res= KMessageBox::warningYesNoCancel(this, i18n("Save changes?")); + if(res==KMessageBox::Yes) { + m_centralWidget->fileSave(); + return true; + } + else if(res==KMessageBox::Cancel) { + return false; + } + if(res==KMessageBox::No) { + return true; + } + } + return true; +} + +#include "potracegui.moc" diff --git a/src/potracegui.desktop b/src/potracegui.desktop new file mode 100644 index 0000000..3e7e0a4 --- /dev/null +++ b/src/potracegui.desktop @@ -0,0 +1,27 @@ +[Desktop Entry] +Encoding=UTF-8 +Name=potracegui +Name[xx]=xxpotraceguixx +Exec=potracegui +Icon=potracegui +Type=Application +Comment=A simple KDE Application +Comment[ca]=Una simple aplicació KDE +Comment[da]=Et simpelt KDE program +Comment[de]=Eine einfache KDE-Anwendung +Comment[el]=Μια απλή εφαρμογή του KDE +Comment[es]=Una aplicación de KDE sencilla +Comment[et]=Lihtne KDE rakendus +Comment[fr]=Une application simple pour KDE. +Comment[hu]=Egyszerű KDE-alkalmazás +Comment[it]=Una semplice applicazione KDE +Comment[nl]=Een eenvoudige KDE-toepassing +Comment[pt]=Uma aplicação KDE simples +Comment[pt_BR]=Um simples Aplicativo do KDE +Comment[ru]=Простое приложение KDE +Comment[sl]=Preprost program za KDE +Comment[sr]=Једноставан KDE програм +Comment[sv]=Ett enkelt KDE-program +Comment[ta]=ஒரு சாஅதரன கெடி பயன்பாடு +Comment[xx]=xxA simple KDE Applicationxx +Comment[zh_CN]=一个简单的KDE应用程序 diff --git a/src/potracegui.h b/src/potracegui.h new file mode 100644 index 0000000..ab0aeaa --- /dev/null +++ b/src/potracegui.h @@ -0,0 +1,98 @@ +/*************************************************************************** + * Copyright (C) 2004 by Antonio Fasolato * + * Antonio.Fasolato@poste.it * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#ifndef _POTRACEGUI_H_ +#define _POTRACEGUI_H_ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +#include + +class KToggleAction; +class MainWidget; + +/** + * @short Application Main Window + * @author Antonio Fasolato + * @version 1.0 + * + * This is potracegui main window. It controls the menu, the toolbar and the statusbar. Its main widget (MainWidget object) copes with the actual options gaining and image tracing. + */ +class potracegui : public KMainWindow +{ + Q_OBJECT +public: + /** + * @short Default Constructor + * + * Nothing special. + */ + potracegui(); + + /** + * @short Default Destructor + * + * Nothing special + */ + virtual ~potracegui(); + +private: + MainWidget *m_centralWidget; /**< Main widget: everithing not related to menu, toolbar or statusbar */ + KToggleAction *m_toolbarAction; /**< Action for showing/hiding the toolbar */ + KToggleAction *m_statusbarAction; /**< Action for showing/hiding the statusbar */ + + //! Connects all the signals and calls createGUI() + void createInterface(); + //! If the window is being closed with unsaved changes to the document + /*! + * Asks the user if he wants to save the document if he is closing the window and there are unsaved changes + */ + bool queryClose(); + +// Menu and toolbar operations +private slots: + //! Used to create a new document (new window) + void fileNew(); + //! Used when exiting the app + void quit(); + + //! Used to show/hide the toolbar + void showToolbar(); + //! Used to show/hide the statusbar + void showStatusbar(); + //! Used to call the key configuration dialog + void configureKeys(); + //! Used to call the toolbar configuration dialog + void configureTB(); + //! Used to update the toolbar after having changed it + void NewTBConfig(); + //! Used to set a message in the statusbar (used by MainWidget) + /*! + * \param message The message to show + */ + void changeStatusbar(QString message); +}; + +#endif // _POTRACEGUI_H_ diff --git a/src/potracegui.lsm b/src/potracegui.lsm new file mode 100644 index 0000000..8b62775 --- /dev/null +++ b/src/potracegui.lsm @@ -0,0 +1,16 @@ +Begin3 +Title: potracegui -- Some description +Version: 1.3 +Entered-date: +Description: +Keywords: KDE Qt +Author: Antonio Fasolato +Maintained-by: Antonio Fasolato +Home-page: +Alternate-site: +Primary-site: ftp://ftp.kde.org/pub/kde/unstable/apps/utils + xxxxxx potracegui-1.3.tar.gz + xxx potracegui-1.3.lsm +Platform: Linux. Needs KDE +Copying-policy: GPL +End diff --git a/src/potraceguiui.rc b/src/potraceguiui.rc new file mode 100644 index 0000000..3a3954b --- /dev/null +++ b/src/potraceguiui.rc @@ -0,0 +1,5 @@ + + + + + -- cgit v1.2.3