You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
potracegui/src/mainwidget.cpp

1056 lines
34 KiB

/***************************************************************************
* 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 <qcheckbox.h>
#include <qradiobutton.h>
#include <qbuffer.h>
#include <qbuttongroup.h>
#include <qtabwidget.h>
#include <qcursor.h>
#include <qapplication.h>
#include <qwidgetstack.h>
#include <qglobal.h>
#include <kurldrag.h>
#include <kfiledialog.h>
#include <kimageio.h>
#include <kio/netaccess.h>
#include <klocale.h>
#include <knuminput.h>
#include <kcombobox.h>
#include <kcolorbutton.h>
#include <kpushbutton.h>
#include <kmessagebox.h>
#include <cstdlib>
#include <fstream>
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"