tracedialog.cpp revision d039414a8d792d757777c158c74cdf9a53c5d48e
/** @file
* @brief Bitmap tracing settings dialog - implementation
*/
/* Authors:
* Bob Jamison <rjamison@titan.com>
* Stéphane Gimenez <dev@gim.name>
* Other dudes from The Inkscape Organization
*
* Copyright (C) 2004-2006 Authors
*
* Released under GNU GPL, read the file 'COPYING' for more information
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <gtkmm/notebook.h>
#include <gtkmm/frame.h>
#include <gtkmm/spinbutton.h>
#include <gtkmm/stock.h>
#include <gtk/gtkdialog.h> //for GTK_RESPONSE* types
#include <glibmm/i18n.h>
#include "desktop.h"
#include "tracedialog.h"
#include "trace/potrace/inkscape-potrace.h"
namespace Inkscape {
namespace UI {
namespace Dialog {
//#########################################################################
//## I M P L E M E N T A T I O N
//#########################################################################
/**
* A dialog for adjusting bitmap->vector tracing parameters
*/
class TraceDialogImpl : public TraceDialog
{
public:
/**
* Constructor
*/
TraceDialogImpl();
/**
* Destructor
*/
~TraceDialogImpl();
/**
* Callback from OK or Cancel
*/
void responseCallback(int response_id);
private:
/**
* This is the big almighty McGuffin
*/
Inkscape::Trace::Tracer tracer;
/**
* This does potrace processing
* Only preview if do_i_trace is false
*/
void potraceProcess(bool do_i_trace);
/**
* Abort processing
*/
void abort();
void previewCallback();
//############ General items
Gtk::HBox mainHBox;
Gtk::Tooltips tips;
Gtk::Button *mainOkButton;
Gtk::Button *mainCancelButton;
//######## Left pannel
Gtk::VBox leftVBox;
//#### Notebook
Gtk::Notebook notebook;
//## Modes
Gtk::VBox modePageBox;
Gtk::RadioButtonGroup modeGroup;
//# Single scan mode
//brightness
Gtk::Frame modeBrightnessFrame;
Gtk::VBox modeBrightnessVBox;
Gtk::HBox modeBrightnessBox;
Gtk::RadioButton modeBrightnessRadioButton;
Gtk::Label modeBrightnessSpinnerLabel;
Gtk::SpinButton modeBrightnessSpinner;
//edge detection
Gtk::Frame modeCannyFrame;
Gtk::HBox modeCannyBox;
Gtk::VBox modeCannyVBox;
Gtk::RadioButton modeCannyRadioButton;
//Gtk::HSeparator modeCannySeparator;
//Gtk::Label modeCannyLoSpinnerLabel;
//Gtk::SpinButton modeCannyLoSpinner;
Gtk::Label modeCannyHiSpinnerLabel;
Gtk::SpinButton modeCannyHiSpinner;
//quantization
Gtk::Frame modeQuantFrame;
Gtk::HBox modeQuantBox;
Gtk::VBox modeQuantVBox;
Gtk::RadioButton modeQuantRadioButton;
Gtk::Label modeQuantNrColorLabel;
Gtk::SpinButton modeQuantNrColorSpinner;
//params
Gtk::CheckButton modeInvertButton;
Gtk::HBox modeInvertBox;
//# Multiple path scanning mode
Gtk::Frame modeMultiScanFrame;
Gtk::VBox modeMultiScanVBox;
//brightness
Gtk::HBox modeMultiScanHBox1;
Gtk::RadioButton modeMultiScanBrightnessRadioButton;
Gtk::SpinButton modeMultiScanNrColorSpinner;
//colors
Gtk::HBox modeMultiScanHBox2;
Gtk::RadioButton modeMultiScanColorRadioButton;
//grays
Gtk::HBox modeMultiScanHBox3;
Gtk::RadioButton modeMultiScanMonoRadioButton;
Gtk::Label modeMultiScanNrColorLabel;
//params
Gtk::HBox modeMultiScanHBox4;
Gtk::CheckButton modeMultiScanStackButton;
Gtk::CheckButton modeMultiScanSmoothButton;
Gtk::CheckButton modeMultiScanBackgroundButton;
//## Options
Gtk::VBox optionsPageBox;
// potrace parameters
Gtk::Frame optionsFrame;
Gtk::VBox optionsVBox;
Gtk::HBox optionsSpecklesBox;
Gtk::CheckButton optionsSpecklesButton;
Gtk::Label optionsSpecklesSizeLabel;
Gtk::SpinButton optionsSpecklesSizeSpinner;
Gtk::HBox optionsCornersBox;
Gtk::CheckButton optionsCornersButton;
Gtk::Label optionsCornersThresholdLabel;
Gtk::SpinButton optionsCornersThresholdSpinner;
Gtk::HBox optionsOptimBox;
Gtk::CheckButton optionsOptimButton;
Gtk::Label optionsOptimToleranceLabel;
Gtk::SpinButton optionsOptimToleranceSpinner;
//#### Credits
Gtk::VBox potraceCreditsVBox;
Gtk::Label potraceCreditsLabel;
//######## Right pannel
Gtk::VBox rightVBox;
//#### SIOX selection
Gtk::HBox sioxBox;
Gtk::CheckButton sioxButton;
//#### Preview
Gtk::Frame previewFrame;
Gtk::VBox previewVBox;
Gtk::Button previewButton;
Gtk::Image previewImage;
};
//#########################################################################
//## E V E N T S
//#########################################################################
/**
* This does potrace processing
* Only preview if do_i_trace is false
*/
void TraceDialogImpl::potraceProcess(bool do_i_trace)
{
SPDesktop *desktop = SP_ACTIVE_DESKTOP;
if (desktop)
desktop->setWaitingCursor();
//##### Get the tracer and engine
Inkscape::Trace::Potrace::PotraceTracingEngine pte;
/* inversion */
bool invert = modeInvertButton.get_active();
pte.setInvert(invert);
//##### Get the preprocessor settings
/* siox -- performed by Tracer, and before any of the others */
if (sioxButton.get_active())
tracer.enableSiox(true);
else
tracer.enableSiox(false);
/* one of the following */
if (modeBrightnessRadioButton.get_active())
pte.setTraceType(Inkscape::Trace::Potrace::TRACE_BRIGHTNESS);
else if (modeMultiScanBrightnessRadioButton.get_active())
pte.setTraceType(Inkscape::Trace::Potrace::TRACE_BRIGHTNESS_MULTI);
else if (modeCannyRadioButton.get_active())
pte.setTraceType(Inkscape::Trace::Potrace::TRACE_CANNY);
else if (modeQuantRadioButton.get_active())
pte.setTraceType(Inkscape::Trace::Potrace::TRACE_QUANT);
else if (modeMultiScanColorRadioButton.get_active())
{
pte.setTraceType(Inkscape::Trace::Potrace::TRACE_QUANT_COLOR);
pte.setInvert(false);
}
else if (modeMultiScanMonoRadioButton.get_active())
{
pte.setTraceType(Inkscape::Trace::Potrace::TRACE_QUANT_MONO);
pte.setInvert(false);
}
/* params */
int paramsSpecklesSize =
optionsSpecklesButton.get_active() ?
optionsSpecklesSizeSpinner.get_value_as_int() :
0;
pte.setParamsTurdSize(paramsSpecklesSize);
double paramsCornersThreshold =
optionsCornersButton.get_active() ?
optionsCornersThresholdSpinner.get_value() :
0.;
pte.setParamsAlphaMax(paramsCornersThreshold);
bool paramsOptim = optionsOptimButton.get_active();
pte.setParamsOptiCurve(paramsOptim);
double paramsOptimTolerance = optionsOptimToleranceSpinner.get_value();
pte.setParamsOptTolerance(paramsOptimTolerance);
//##### Get the single-scan settings
/* brightness */
double brightnessThreshold = modeBrightnessSpinner.get_value();
pte.setBrightnessThreshold(brightnessThreshold);
/* canny */
double cannyHighThreshold = modeCannyHiSpinner.get_value();
pte.setCannyHighThreshold(cannyHighThreshold);
/* quantization */
int quantNrColors = modeQuantNrColorSpinner.get_value_as_int();
pte.setQuantizationNrColors(quantNrColors);
//##### Get multiple-scan settings
int multiScanNrColors = modeMultiScanNrColorSpinner.get_value_as_int();
pte.setMultiScanNrColors(multiScanNrColors);
bool do_i_stack = modeMultiScanStackButton.get_active();
pte.setMultiScanStack(do_i_stack);
bool do_i_smooth = modeMultiScanSmoothButton.get_active();
pte.setMultiScanSmooth(do_i_smooth);
bool do_i_remove_background = modeMultiScanBackgroundButton.get_active();
pte.setMultiScanRemoveBackground(do_i_remove_background);
//##### Get intermediate bitmap image
Glib::RefPtr<Gdk::Pixbuf> pixbuf = tracer.getSelectedImage();
if (pixbuf)
{
Glib::RefPtr<Gdk::Pixbuf> preview = pte.preview(pixbuf);
if (preview)
{
int width = preview->get_width();
int height = preview->get_height();
double scaleFX = 200.0 / (double)width;
double scaleFY = 200.0 / (double)height;
double scaleFactor = scaleFX > scaleFY ? scaleFY : scaleFX;
int newWidth = (int) (((double)width) * scaleFactor);
int newHeight = (int) (((double)height) * scaleFactor);
Glib::RefPtr<Gdk::Pixbuf> scaledPreview =
preview->scale_simple(newWidth, newHeight,
Gdk::INTERP_NEAREST);
//g_object_unref(preview);
previewImage.set(scaledPreview);
}
}
//##### Convert
if (do_i_trace)
{
if (mainCancelButton)
mainCancelButton->set_sensitive(true);
if (mainOkButton)
mainOkButton->set_sensitive(false);
tracer.trace(&pte);
if (mainCancelButton)
mainCancelButton->set_sensitive(false);
if (mainOkButton)
mainOkButton->set_sensitive(true);
}
if (desktop)
desktop->clearWaitingCursor();
}
/**
* Abort processing
*/
void TraceDialogImpl::abort()
{
SPDesktop *desktop = SP_ACTIVE_DESKTOP;
if (desktop)
desktop->setWaitingCursor();
if (mainCancelButton)
mainCancelButton->set_sensitive(false);
if (mainOkButton)
mainOkButton->set_sensitive(true);
//### Make the abort() call to the tracer
tracer.abort();
}
//#########################################################################
//## E V E N T S
//#########################################################################
/**
* Callback from the Preview button. Can be called from elsewhere.
*/
void TraceDialogImpl::previewCallback()
{
potraceProcess(false);
}
/**
* Default response from the dialog. Let's intercept it
*/
void TraceDialogImpl::responseCallback(int response_id)
{
if (response_id == GTK_RESPONSE_OK)
{
// for now, we assume potrace, as it's the only one we have
potraceProcess(true);
}
else if (response_id == GTK_RESPONSE_CANCEL)
{
abort();
}
else
{
hide();
return;
}
}
//#########################################################################
//## C O N S T R U C T O R / D E S T R U C T O R
//#########################################################################
/**
* Constructor
*/
TraceDialogImpl::TraceDialogImpl() :
TraceDialog()
{
Gtk::Box *contents = _getContents();
#define MARGIN 2
//#### begin left panel
//### begin notebook
//## begin mode page
//# begin single scan
// brightness
modeBrightnessRadioButton.set_label(_("Brightness cutoff"));
modeGroup = modeBrightnessRadioButton.get_group();
modeBrightnessBox.pack_start(modeBrightnessRadioButton, false, false, MARGIN);
tips.set_tip(modeBrightnessRadioButton,
_("Trace by a given brightness level"));
modeBrightnessSpinner.set_digits(3);
modeBrightnessSpinner.set_increments(0.01, 0.1);
modeBrightnessSpinner.set_range(0.0, 1.0);
modeBrightnessSpinner.set_value(0.45);
modeBrightnessBox.pack_end(modeBrightnessSpinner, false, false, MARGIN);
tips.set_tip(modeBrightnessSpinner,
_("Brightness cutoff for black/white"));
modeBrightnessSpinnerLabel.set_label(_("Threshold:"));
modeBrightnessBox.pack_end(modeBrightnessSpinnerLabel, false, false, MARGIN);
modeBrightnessVBox.pack_start(modeBrightnessBox, false, false, MARGIN);
modeBrightnessFrame.set_label(_("Single scan: creates a path"));
// canny edge detection
// TRANSLATORS: "Canny" is the name of the inventor of this edge detection method
modeCannyRadioButton.set_label(_("Edge detection"));
modeCannyRadioButton.set_group(modeGroup);
modeCannyBox.pack_start(modeCannyRadioButton, false, false, MARGIN);
tips.set_tip(modeCannyRadioButton,
_("Trace with optimal edge detection by J. Canny's algorithm"));
/*
modeCannyBox.pack_start(modeCannySeparator);
modeCannyLoSpinnerLabel.set_label(_("Low"));
modeCannyBox.pack_start(modeCannyLoSpinnerLabel);
modeCannyLoSpinner.set_digits(5);
modeCannyLoSpinner.set_increments(0.01, 0.1);
modeCannyLoSpinner.set_range(0.0, 1.0);
modeCannyLoSpinner.set_value(0.1);
modeCannyBox.pack_start(modeCannyLoSpinner);
*/
modeCannyHiSpinner.set_digits(3);
modeCannyHiSpinner.set_increments(0.01, 0.1);
modeCannyHiSpinner.set_range(0.0, 1.0);
modeCannyHiSpinner.set_value(0.65);
modeCannyBox.pack_end(modeCannyHiSpinner, false, false, MARGIN);
tips.set_tip(modeCannyHiSpinner,
_("Brightness cutoff for adjacent pixels (determines edge thickness)"));
modeCannyHiSpinnerLabel.set_label(_("Threshold:"));
modeCannyBox.pack_end(modeCannyHiSpinnerLabel, false, false, MARGIN);
modeBrightnessVBox.pack_start(modeCannyBox, false, false, MARGIN);
// quantization
// TRANSLATORS: Color Quantization: the process of reducing the number
// of colors in an image by selecting an optimized set of representative
// colors and then re-applying this reduced set to the original image.
modeQuantRadioButton.set_label(_("Color quantization"));
modeQuantRadioButton.set_group(modeGroup);
modeQuantBox.pack_start(modeQuantRadioButton, false, false, MARGIN);
tips.set_tip(modeQuantRadioButton,
_("Trace along the boundaries of reduced colors"));
modeQuantNrColorSpinner.set_digits(0);
modeQuantNrColorSpinner.set_increments(1.0, 4.0);
modeQuantNrColorSpinner.set_range(2.0, 64.0);
modeQuantNrColorSpinner.set_value(8.0);
modeQuantBox.pack_end(modeQuantNrColorSpinner, false, false, MARGIN);
tips.set_tip(modeQuantNrColorSpinner,
_("The number of reduced colors"));
modeQuantNrColorLabel.set_label(_("Colors:"));
modeQuantBox.pack_end(modeQuantNrColorLabel, false, false, MARGIN);
modeBrightnessVBox.pack_start(modeQuantBox, false, false, MARGIN);
// swap black and white
modeInvertButton.set_label(_("Invert image"));
modeInvertButton.set_active(false);
modeInvertBox.pack_start(modeInvertButton, false, false, MARGIN);
modeBrightnessVBox.pack_start(modeInvertBox, false, false, MARGIN);
tips.set_tip(modeInvertButton,
_("Invert black and white regions"));
modeBrightnessFrame.add(modeBrightnessVBox);
modePageBox.pack_start(modeBrightnessFrame, false, false, 0);
//# end single scan
//# begin multiple scan
modeMultiScanBrightnessRadioButton.set_label(_("Brightness steps"));
modeMultiScanBrightnessRadioButton.set_group(modeGroup);
modeMultiScanHBox1.pack_start(modeMultiScanBrightnessRadioButton, false, false, MARGIN);
tips.set_tip(modeMultiScanBrightnessRadioButton,
_("Trace the given number of brightness levels"));
modeMultiScanNrColorSpinner.set_digits(0);
modeMultiScanNrColorSpinner.set_increments(1.0, 4.0);
modeMultiScanNrColorSpinner.set_range(2.0, 256.0);
modeMultiScanNrColorSpinner.set_value(8.0);
modeMultiScanHBox1.pack_end(modeMultiScanNrColorSpinner, false, false, MARGIN);
modeMultiScanNrColorLabel.set_label(_("Scans:"));
modeMultiScanHBox1.pack_end(modeMultiScanNrColorLabel, false, false, MARGIN);
tips.set_tip(modeMultiScanNrColorSpinner,
_("The desired number of scans"));
modeMultiScanVBox.pack_start(modeMultiScanHBox1, false, false, MARGIN);
modeMultiScanColorRadioButton.set_label(_("Colors"));
modeMultiScanColorRadioButton.set_group(modeGroup);
modeMultiScanHBox2.pack_start(modeMultiScanColorRadioButton, false, false, MARGIN);
tips.set_tip(modeMultiScanColorRadioButton,
_("Trace the given number of reduced colors"));
modeMultiScanVBox.pack_start(modeMultiScanHBox2, false, false, MARGIN);
modeMultiScanMonoRadioButton.set_label(_("Grays"));
modeMultiScanMonoRadioButton.set_group(modeGroup);
modeMultiScanHBox3.pack_start(modeMultiScanMonoRadioButton, false, false, MARGIN);
tips.set_tip(modeMultiScanMonoRadioButton,
_("Same as Colors, but the result is converted to grayscale"));
modeMultiScanVBox.pack_start(modeMultiScanHBox3, false, false, MARGIN);
// TRANSLATORS: "Smooth" is a verb here
modeMultiScanSmoothButton.set_label(_("Smooth"));
modeMultiScanSmoothButton.set_active(true);
modeMultiScanHBox4.pack_start(modeMultiScanSmoothButton, false, false, MARGIN);
tips.set_tip(modeMultiScanSmoothButton,
_("Apply Gaussian blur to the bitmap before tracing"));
// TRANSLATORS: "Stack" is a verb here
modeMultiScanStackButton.set_label(_("Stack scans"));
modeMultiScanStackButton.set_active(true);
modeMultiScanHBox4.pack_start(modeMultiScanStackButton, false, false, MARGIN);
tips.set_tip(modeMultiScanStackButton, _("Stack scans on top of one another (no gaps) instead of tiling (usually with gaps)"));
modeMultiScanBackgroundButton.set_label(_("Remove background"));
modeMultiScanBackgroundButton.set_active(false);
modeMultiScanHBox4.pack_start(modeMultiScanBackgroundButton, false, false, MARGIN);
// TRANSLATORS: "Layer" refers to one of the stacked paths in the multiscan
tips.set_tip(modeMultiScanBackgroundButton,
_("Remove bottom (background) layer when done"));
modeMultiScanVBox.pack_start(modeMultiScanHBox4, false, false, MARGIN);
modeMultiScanFrame.set_label(_("Multiple scans: creates a group of paths"));
//modeQuantFrame.set_shadow_type(Gtk::SHADOW_NONE);
modeMultiScanFrame.add(modeMultiScanVBox);
modePageBox.pack_start(modeMultiScanFrame, false, false, 0);
//# end multiple scan
//## end mode page
notebook.append_page(modePageBox, _("Mode"));
//## begin option page
//# potrace parameters
optionsSpecklesButton.set_label(_("Suppress speckles"));
tips.set_tip(optionsSpecklesButton,
_("Ignore small spots (speckles) in the bitmap"));
optionsSpecklesButton.set_active(true);
optionsSpecklesBox.pack_start(optionsSpecklesButton, false, false, MARGIN);
optionsSpecklesSizeSpinner.set_digits(0);
optionsSpecklesSizeSpinner.set_increments(1, 10);
optionsSpecklesSizeSpinner.set_range(0, 1000);
optionsSpecklesSizeSpinner.set_value(2);
tips.set_tip(optionsSpecklesSizeSpinner,
_("Speckles of up to this many pixels will be suppressed"));
optionsSpecklesBox.pack_end(optionsSpecklesSizeSpinner, false, false, MARGIN);
optionsSpecklesSizeLabel.set_label(_("Size:"));
optionsSpecklesBox.pack_end(optionsSpecklesSizeLabel, false, false, MARGIN);
optionsCornersButton.set_label(_("Smooth corners"));
tips.set_tip(optionsCornersButton,
_("Smooth out sharp corners of the trace"));
optionsCornersButton.set_active(true);
optionsCornersBox.pack_start(optionsCornersButton, false, false, MARGIN);
optionsCornersThresholdSpinner.set_digits(2);
optionsCornersThresholdSpinner.set_increments(0.01, 0.1);
optionsCornersThresholdSpinner.set_range(0.0, 1.34);
optionsCornersThresholdSpinner.set_value(1.0);
optionsCornersBox.pack_end(optionsCornersThresholdSpinner, false, false, MARGIN);
tips.set_tip(optionsCornersThresholdSpinner,
_("Increase this to smooth corners more"));
optionsCornersThresholdLabel.set_label(_("Threshold:"));
optionsCornersBox.pack_end(optionsCornersThresholdLabel, false, false, MARGIN);
optionsOptimButton.set_label(_("Optimize paths"));
optionsOptimButton.set_active(true);
tips.set_tip(optionsOptimButton,
_("Try to optimize paths by joining adjacent Bezier curve segments"));
optionsOptimBox.pack_start(optionsOptimButton, false, false, MARGIN);
optionsOptimToleranceSpinner.set_digits(2);
optionsOptimToleranceSpinner.set_increments(0.05, 0.25);
optionsOptimToleranceSpinner.set_range(0.0, 5.0);
optionsOptimToleranceSpinner.set_value(0.2);
optionsOptimBox.pack_end(optionsOptimToleranceSpinner, false, false, MARGIN);
tips.set_tip(optionsOptimToleranceSpinner,
_("Increase this to reduce the number of nodes in the trace by more aggressive optimization"));
optionsOptimToleranceLabel.set_label(_("Tolerance:"));
optionsOptimBox.pack_end(optionsOptimToleranceLabel, false, false, MARGIN);
optionsVBox.pack_start(optionsSpecklesBox, false, false, MARGIN);
optionsVBox.pack_start(optionsCornersBox, false, false, MARGIN);
optionsVBox.pack_start(optionsOptimBox, false, false, MARGIN);
optionsFrame.set_label(_("Options"));
optionsFrame.add(optionsVBox);
optionsPageBox.pack_start(optionsFrame, false, false, 0);
//## end option page
notebook.append_page(optionsPageBox, _("Options"));
//### credits
potraceCreditsLabel.set_text(_("Inkscape bitmap tracing\nis based on Potrace,\ncreated by Peter Selinger\n\nhttp://potrace.sourceforge.net"));
potraceCreditsVBox.pack_start(potraceCreditsLabel, false, false, MARGIN);
notebook.append_page(potraceCreditsVBox, _("Credits"));
//### end notebook
leftVBox.pack_start(notebook, true, true, MARGIN);
//#### end left panel
mainHBox.pack_start(leftVBox);
//#### begin right panel
//## SIOX
sioxButton.set_label(_("SIOX foreground selection"));
sioxBox.pack_start(sioxButton, false, false, MARGIN);
tips.set_tip(sioxButton,
_("Cover the area you want to select as the foreground"));
rightVBox.pack_start(sioxBox, false, false, 0);
//## preview
previewButton.set_label(_("Update"));
previewButton.signal_clicked().connect(
sigc::mem_fun(*this, &TraceDialogImpl::previewCallback) );
previewVBox.pack_end(previewButton, false, false, 0);
// I guess it's correct to call the "intermediate bitmap" a preview of the trace
tips.set_tip(previewButton,
_("Preview the intermediate bitmap with the current settings, without actual tracing"));
previewImage.set_size_request(200,200);
//previewImage.set_alignment (Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER);
previewVBox.pack_start(previewImage, true, true, 0);
previewFrame.set_label(_("Preview"));
//previewFrame.set_shadow_type(Gtk::SHADOW_NONE);
previewFrame.add(previewVBox);
rightVBox.pack_start(previewFrame, true, true, MARGIN);
//#### end right panel
mainHBox.pack_start(rightVBox);
//#### Global stuff
contents->pack_start(mainHBox);
//## The OK button
mainCancelButton = addResponseButton(Gtk::Stock::STOP, GTK_RESPONSE_CANCEL);
if (mainCancelButton) {
tips.set_tip((*mainCancelButton), _("Abort a trace in progress"));
mainCancelButton->set_sensitive(false);
}
mainOkButton = addResponseButton(Gtk::Stock::OK, GTK_RESPONSE_OK);
tips.set_tip((*mainOkButton), _("Execute the trace"));
show_all_children();
//## Connect the signal
signalResponse().connect(
sigc::mem_fun(*this, &TraceDialogImpl::responseCallback));
}
/**
* Factory method. Use this to create a new TraceDialog
*/
TraceDialog &TraceDialog::getInstance()
{
TraceDialog *dialog = new TraceDialogImpl();
return *dialog;
}
/**
* Constructor
*/
TraceDialogImpl::~TraceDialogImpl()
{
}
} //namespace Dialog
} //namespace UI
} //namespace Inkscape
//#########################################################################
//## E N D O F F I L E
//#########################################################################