|
|
|
// Copyright (C) 2003 Dominique Devriese <devriese@kde.org>
|
|
|
|
|
|
|
|
// 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 "exporter.h"
|
|
|
|
|
|
|
|
#include "imageexporteroptions.h"
|
|
|
|
#include "latexexporter.h"
|
|
|
|
#include "svgexporter.h"
|
|
|
|
|
|
|
|
#include "../kig/kig_document.h"
|
|
|
|
#include "../kig/kig_part.h"
|
|
|
|
#include "../kig/kig_view.h"
|
|
|
|
#include "../misc/common.h"
|
|
|
|
#include "../misc/kigfiledialog.h"
|
|
|
|
#include "../misc/kigpainter.h"
|
|
|
|
#include "../objects/circle_imp.h"
|
|
|
|
#include "../objects/line_imp.h"
|
|
|
|
#include "../objects/object_drawer.h"
|
|
|
|
#include "../objects/object_holder.h"
|
|
|
|
#include "../objects/object_imp.h"
|
|
|
|
#include "../objects/other_imp.h"
|
|
|
|
#include "../objects/point_imp.h"
|
|
|
|
#include "../objects/text_imp.h"
|
|
|
|
|
|
|
|
#include <tqcheckbox.h>
|
|
|
|
#include <tqcolor.h>
|
|
|
|
#include <tqfile.h>
|
|
|
|
#include <tqiconset.h>
|
|
|
|
#include <tqtextstream.h>
|
|
|
|
|
|
|
|
#include <tdeaction.h>
|
|
|
|
#include <kiconloader.h>
|
|
|
|
#include <kimageio.h>
|
|
|
|
#include <tdelocale.h>
|
|
|
|
#include <tdemessagebox.h>
|
|
|
|
#include <knuminput.h>
|
|
|
|
|
|
|
|
#include <map>
|
|
|
|
|
|
|
|
// we need this for storing colors in a std::map..
|
|
|
|
static bool operator<( const TQColor& a, const TQColor& b )
|
|
|
|
{
|
|
|
|
return a.rgb() < b.rgb();
|
|
|
|
}
|
|
|
|
|
|
|
|
class ExporterAction
|
|
|
|
: public TDEAction
|
|
|
|
{
|
|
|
|
KigExporter* mexp;
|
|
|
|
const KigPart* mdoc;
|
|
|
|
KigWidget* mw;
|
|
|
|
public:
|
|
|
|
ExporterAction( const KigPart* doc, KigWidget* w,
|
|
|
|
TDEActionCollection* parent, KigExporter* exp );
|
|
|
|
void slotActivated();
|
|
|
|
};
|
|
|
|
|
|
|
|
ExporterAction::ExporterAction( const KigPart* doc, KigWidget* w,
|
|
|
|
TDEActionCollection* parent, KigExporter* exp )
|
|
|
|
: TDEAction( exp->menuEntryName(), TDEShortcut(), 0, 0, parent ),
|
|
|
|
mexp( exp ), mdoc( doc ), mw( w )
|
|
|
|
{
|
|
|
|
TQString iconstr = exp->menuIcon();
|
|
|
|
if ( iconstr.isEmpty() )
|
|
|
|
return;
|
|
|
|
TDEIconLoader* l = doc->instance()->iconLoader();
|
|
|
|
TQPixmap icon = l->loadIcon( iconstr, TDEIcon::Small, 16, TDEIcon::DefaultState, 0L, true );
|
|
|
|
if ( !icon.isNull() )
|
|
|
|
setIconSet( TQIconSet( icon ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
void ExporterAction::slotActivated()
|
|
|
|
{
|
|
|
|
mexp->run( *mdoc, *mw );
|
|
|
|
}
|
|
|
|
|
|
|
|
KigExporter::~KigExporter()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
ImageExporter::~ImageExporter()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString ImageExporter::exportToStatement() const
|
|
|
|
{
|
|
|
|
return i18n( "&Export to image" );
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString ImageExporter::menuEntryName() const
|
|
|
|
{
|
|
|
|
return i18n( "&Image..." );
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString ImageExporter::menuIcon() const
|
|
|
|
{
|
|
|
|
return "image-x-generic";
|
|
|
|
}
|
|
|
|
|
|
|
|
void ImageExporter::run( const KigPart& doc, KigWidget& w )
|
|
|
|
{
|
|
|
|
static bool kimageioRegistered = false;
|
|
|
|
if ( ! kimageioRegistered )
|
|
|
|
{
|
|
|
|
KImageIO::registerFormats();
|
|
|
|
kimageioRegistered = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
KigFileDialog* kfd = new KigFileDialog(
|
|
|
|
TQString(), KImageIO::pattern( KImageIO::Writing ),
|
|
|
|
i18n( "Export as Image" ), &w );
|
|
|
|
kfd->setOptionCaption( i18n( "Image Options" ) );
|
|
|
|
ImageExporterOptions* opts = new ImageExporterOptions( 0L, w.size() );
|
|
|
|
kfd->setOptionsWidget( opts );
|
|
|
|
opts->WidthInput->setValue( w.size().width() );
|
|
|
|
opts->HeightInput->setValue( w.size().height() );
|
|
|
|
opts->showGridCheckBox->setChecked( doc.document().grid() );
|
|
|
|
opts->showAxesCheckBox->setChecked( doc.document().axes() );
|
|
|
|
if ( !kfd->exec() )
|
|
|
|
return;
|
|
|
|
|
|
|
|
TQString filename = kfd->selectedFile();
|
|
|
|
bool showgrid = opts->showGridCheckBox->isOn();
|
|
|
|
bool showaxes = opts->showAxesCheckBox->isOn();
|
|
|
|
int width = opts->WidthInput->value();
|
|
|
|
int height = opts->HeightInput->value();
|
|
|
|
|
|
|
|
delete opts;
|
|
|
|
delete kfd;
|
|
|
|
|
|
|
|
TQString type = KImageIO::type( filename );
|
|
|
|
if ( type.isNull() )
|
|
|
|
{
|
|
|
|
KMessageBox::sorry( &w, i18n( "Sorry, this file format is not supported." ) );
|
|
|
|
return;
|
|
|
|
};
|
|
|
|
|
|
|
|
kdDebug() << k_funcinfo << type << endl;
|
|
|
|
|
|
|
|
TQFile file( filename );
|
|
|
|
if ( ! file.open( IO_WriteOnly ) )
|
|
|
|
{
|
|
|
|
KMessageBox::sorry( &w,
|
|
|
|
i18n( "The file \"%1\" could not be opened. Please check if the file permissions are set correctly." )
|
|
|
|
.arg( filename ) );
|
|
|
|
return;
|
|
|
|
};
|
|
|
|
|
|
|
|
TQPixmap img( TQSize( width, height ) );
|
|
|
|
img.fill( TQt::white );
|
|
|
|
KigPainter p( ScreenInfo( w.screenInfo().shownRect(), img.rect() ), TQT_TQPAINTDEVICE(&img), doc.document() );
|
|
|
|
p.setWholeWinOverlay();
|
|
|
|
p.drawGrid( doc.document().coordinateSystem(), showgrid, showaxes );
|
|
|
|
// FIXME: show the selections ?
|
|
|
|
p.drawObjects( doc.document().objects(), false );
|
|
|
|
if ( ! img.save( filename, type.latin1() ) )
|
|
|
|
{
|
|
|
|
KMessageBox::error( &w, i18n( "Sorry, something went wrong while saving to image \"%1\"" ).arg( filename ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
KigExportManager::KigExportManager()
|
|
|
|
{
|
|
|
|
mexporters.push_back( new ImageExporter );
|
|
|
|
// working on this one ;)
|
|
|
|
mexporters.push_back( new XFigExporter );
|
|
|
|
mexporters.push_back( new LatexExporter );
|
|
|
|
mexporters.push_back( new SVGExporter );
|
|
|
|
}
|
|
|
|
|
|
|
|
KigExportManager::~KigExportManager()
|
|
|
|
{
|
|
|
|
for ( uint i = 0; i < mexporters.size(); ++i )
|
|
|
|
delete mexporters[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
void KigExportManager::addMenuAction( const KigPart* doc, KigWidget* w,
|
|
|
|
TDEActionCollection* coll )
|
|
|
|
{
|
|
|
|
TDEActionMenu* m =
|
|
|
|
new TDEActionMenu( i18n( "&Export To" ), coll, "file_export" );
|
|
|
|
for ( uint i = 0; i < mexporters.size(); ++i )
|
|
|
|
m->insert( new ExporterAction( doc, w, coll, mexporters[i] ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
KigExportManager* KigExportManager::instance()
|
|
|
|
{
|
|
|
|
static KigExportManager m;
|
|
|
|
return &m;
|
|
|
|
}
|
|
|
|
|
|
|
|
XFigExporter::~XFigExporter()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString XFigExporter::exportToStatement() const
|
|
|
|
{
|
|
|
|
return i18n( "Export to &XFig file" );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TQString XFigExporter::menuEntryName() const
|
|
|
|
{
|
|
|
|
return i18n( "&XFig File..." );
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString XFigExporter::menuIcon() const
|
|
|
|
{
|
|
|
|
return "kig_xfig";
|
|
|
|
}
|
|
|
|
|
|
|
|
class XFigExportImpVisitor
|
|
|
|
: public ObjectImpVisitor
|
|
|
|
{
|
|
|
|
TQTextStream& mstream;
|
|
|
|
ObjectHolder* mcurobj;
|
|
|
|
const KigWidget& mw;
|
|
|
|
Rect msr;
|
|
|
|
std::map<TQColor, int> mcolormap;
|
|
|
|
int mnextcolorid;
|
|
|
|
int mcurcolorid;
|
|
|
|
|
|
|
|
TQPoint convertCoord( const Coordinate& c )
|
|
|
|
{
|
|
|
|
Coordinate ret = ( c - msr.bottomLeft() );
|
|
|
|
ret.y = msr.height() - ret.y;
|
|
|
|
// kdDebug() << "msr: " << msr << endl
|
|
|
|
// << "ret: " << ret << endl
|
|
|
|
// << "c: " << c << endl;
|
|
|
|
ret *= 9450;
|
|
|
|
ret /= msr.width();
|
|
|
|
return ret.toTQPoint();
|
|
|
|
}
|
|
|
|
|
|
|
|
void emitLine( const Coordinate& a, const Coordinate& b, int width, bool vector = false );
|
|
|
|
public:
|
|
|
|
void visit( ObjectHolder* obj );
|
|
|
|
void mapColor( const ObjectDrawer* obj );
|
|
|
|
|
|
|
|
XFigExportImpVisitor( TQTextStream& s, const KigWidget& w )
|
|
|
|
: mstream( s ), mw( w ), msr( mw.showingRect() ),
|
|
|
|
mnextcolorid( 32 )
|
|
|
|
{
|
|
|
|
// predefined colors in XFig..
|
|
|
|
mcolormap[TQt::black] = 0;
|
|
|
|
mcolormap[TQt::blue] = 1;
|
|
|
|
mcolormap[TQt::green] = 2;
|
|
|
|
mcolormap[TQt::cyan] = 3;
|
|
|
|
mcolormap[TQt::red] = 4;
|
|
|
|
mcolormap[TQt::magenta] = 5;
|
|
|
|
mcolormap[TQt::yellow] = 6;
|
|
|
|
mcolormap[TQt::white] = 7;
|
|
|
|
}
|
|
|
|
void visit( const LineImp* imp );
|
|
|
|
void visit( const PointImp* imp );
|
|
|
|
void visit( const TextImp* imp );
|
|
|
|
void visit( const AngleImp* imp );
|
|
|
|
void visit( const VectorImp* imp );
|
|
|
|
void visit( const LocusImp* imp );
|
|
|
|
void visit( const CircleImp* imp );
|
|
|
|
void visit( const ConicImp* imp );
|
|
|
|
void visit( const CubicImp* imp );
|
|
|
|
void visit( const SegmentImp* imp );
|
|
|
|
void visit( const RayImp* imp );
|
|
|
|
void visit( const ArcImp* imp );
|
|
|
|
};
|
|
|
|
|
|
|
|
void XFigExportImpVisitor::mapColor( const ObjectDrawer* obj )
|
|
|
|
{
|
|
|
|
if ( ! obj->shown() ) return;
|
|
|
|
TQColor color = obj->color();
|
|
|
|
if ( mcolormap.find( color ) == mcolormap.end() )
|
|
|
|
{
|
|
|
|
int newcolorid = mnextcolorid++;
|
|
|
|
mstream << "0 "
|
|
|
|
<< newcolorid << " "
|
|
|
|
<< color.name() << "\n";
|
|
|
|
mcolormap[color] = newcolorid;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void XFigExportImpVisitor::visit( ObjectHolder* obj )
|
|
|
|
{
|
|
|
|
if ( ! obj->drawer()->shown() ) return;
|
|
|
|
assert( mcolormap.find( obj->drawer()->color() ) != mcolormap.end() );
|
|
|
|
mcurcolorid = mcolormap[ obj->drawer()->color() ];
|
|
|
|
mcurobj = obj;
|
|
|
|
obj->imp()->visit( this );
|
|
|
|
}
|
|
|
|
|
|
|
|
void XFigExportImpVisitor::visit( const LineImp* imp )
|
|
|
|
{
|
|
|
|
Coordinate a = imp->data().a;
|
|
|
|
Coordinate b = imp->data().b;
|
|
|
|
calcBorderPoints( a, b, msr );
|
|
|
|
int width = mcurobj->drawer()->width();
|
|
|
|
if ( width == -1 ) width = 1;
|
|
|
|
|
|
|
|
if ( a != b )
|
|
|
|
emitLine( a, b, width );
|
|
|
|
}
|
|
|
|
|
|
|
|
void XFigExportImpVisitor::emitLine( const Coordinate& a, const Coordinate& b, int width, bool vector )
|
|
|
|
{
|
|
|
|
mstream << "2 "; // polyline type;
|
|
|
|
mstream << "1 "; // polyline subtype;
|
|
|
|
mstream << "0 "; // line_style: Solid
|
|
|
|
mstream << width << " "; // thickness: *1/80 inch
|
|
|
|
mstream << mcurcolorid << " "; // pen_color: default
|
|
|
|
mstream << "7 "; // fill_color: white
|
|
|
|
mstream << "50 "; // depth: 50
|
|
|
|
mstream << "-1 "; // pen_style: unused by XFig
|
|
|
|
mstream << "-1 "; // area_fill: no fill
|
|
|
|
mstream << "0.000 "; // style_val: the distance between dots and
|
|
|
|
// dashes in case of dotted or dashed lines..
|
|
|
|
mstream << "0 "; // join_style: Miter
|
|
|
|
mstream << "0 "; // cap_style: Butt
|
|
|
|
mstream << "-1 "; // radius in case of an arc-box, but we're a
|
|
|
|
// polyline, so nothing here..
|
|
|
|
if ( ! vector )
|
|
|
|
mstream << "0 "; // forward arrow: no
|
|
|
|
else
|
|
|
|
mstream << "1 "; // forward arrow: yes
|
|
|
|
mstream << "0 "; // backward arrow: no
|
|
|
|
mstream << "2"; // a two points polyline..
|
|
|
|
|
|
|
|
mstream << "\n\t ";
|
|
|
|
|
|
|
|
if ( vector )
|
|
|
|
{
|
|
|
|
// first the arrow line in case of a vector..
|
|
|
|
mstream << "1 " // arrow_type: closed triangle
|
|
|
|
<< "1 " // arrow_style: filled with pen color..
|
|
|
|
<< "1.00 " // arrow_thickness: 1
|
|
|
|
<< "195.00 " // arrow_width
|
|
|
|
<< "165.00 " // arrow_height
|
|
|
|
<< "\n\t";
|
|
|
|
}
|
|
|
|
TQPoint ca = convertCoord( a );
|
|
|
|
TQPoint cb = convertCoord( b );
|
|
|
|
|
|
|
|
mstream << ca.x() << " " << ca.y() << " " << cb.x() << " " << cb.y() << "\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
void XFigExportImpVisitor::visit( const PointImp* imp )
|
|
|
|
{
|
|
|
|
const TQPoint center = convertCoord( imp->coordinate() );
|
|
|
|
int width = mcurobj->drawer()->width();
|
|
|
|
if ( width == -1 ) width = 5;
|
|
|
|
width *= 10;
|
|
|
|
|
|
|
|
mstream << "1 " // Ellipse type
|
|
|
|
<< "3 " // circle defined by radius subtype
|
|
|
|
<< "0 "; // line_style: Solid
|
|
|
|
mstream << "1 " << " " // thickness: *1/80 inch
|
|
|
|
<< mcurcolorid << " " // pen_color: default
|
|
|
|
<< mcurcolorid << " " // fill_color: black
|
|
|
|
<< "50 " // depth: 50
|
|
|
|
<< "-1 " // pen_style: unused by XFig
|
|
|
|
<< "20 " // area_fill: full saturation of the fill color
|
|
|
|
<< "0.000 " // style_val: the distance between dots and
|
|
|
|
// dashes in case of dotted or dashed lines..
|
|
|
|
<< "1 " // direction: always 1
|
|
|
|
<< "0.0000 " // angle: the radius of the x-axis: 0
|
|
|
|
<< center.x() << " " << center.y() << " " // the center..
|
|
|
|
<< width << " " << width << " " // radius_x and radius_y
|
|
|
|
<< center.x() << " " // start_x and start_y, appear
|
|
|
|
<< center.y() << " " // unused..
|
|
|
|
<< center.x() + width << " " // end_x and end_y,
|
|
|
|
<< center.y() << "\n"; // appear unused too...
|
|
|
|
}
|
|
|
|
|
|
|
|
void XFigExportImpVisitor::visit( const TextImp* imp )
|
|
|
|
{
|
|
|
|
TQString text = imp->text();
|
|
|
|
TQPoint coord = convertCoord( imp->surroundingRect().bottomLeft() );
|
|
|
|
|
|
|
|
mstream << "4 " // text type
|
|
|
|
<< "0 " // subtype: left justfied
|
|
|
|
<< mcurcolorid << " " // color: black
|
|
|
|
<< "50 " // depth: 50
|
|
|
|
<< "-1 " // pen style: unused
|
|
|
|
<< "0 " // font: default
|
|
|
|
<< "11 " // font-size: 11
|
|
|
|
<< "0 " // angle
|
|
|
|
<< "0 " // font-flags: all the defaults..
|
|
|
|
<< "500 500 " // height, width: large enough..
|
|
|
|
<< coord.x() << " " // x, y
|
|
|
|
<< coord.y() << " "
|
|
|
|
<< text.ascii() << "\\001" // text, terminated by \001
|
|
|
|
<< "\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
void XFigExportImpVisitor::visit( const AngleImp* )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void XFigExportImpVisitor::visit( const VectorImp* imp )
|
|
|
|
{
|
|
|
|
int width = mcurobj->drawer()->width();
|
|
|
|
if ( width == -1 ) width = 1;
|
|
|
|
emitLine( imp->a(), imp->b(), width, true );
|
|
|
|
}
|
|
|
|
|
|
|
|
void XFigExportImpVisitor::visit( const LocusImp* )
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void XFigExportImpVisitor::visit( const CircleImp* imp )
|
|
|
|
{
|
|
|
|
const TQPoint center = convertCoord( imp->center() );
|
|
|
|
const int radius =
|
|
|
|
( convertCoord( imp->center() + Coordinate( imp->radius(), 0 ) ) - center ).x();
|
|
|
|
|
|
|
|
mstream << "1 " // Ellipse type
|
|
|
|
<< "3 " // circle defined by radius subtype
|
|
|
|
<< "0 "; // line_style: Solid
|
|
|
|
int width = mcurobj->drawer()->width();
|
|
|
|
if ( width == -1 ) width = 1;
|
|
|
|
mstream << width << " " // thickness: *1/80 inch
|
|
|
|
<< mcurcolorid << " " // pen_color: default
|
|
|
|
<< "7 " // fill_color: white
|
|
|
|
<< "50 " // depth: 50
|
|
|
|
<< "-1 " // pen_style: unused by XFig
|
|
|
|
<< "-1 " // area_fill: no fill
|
|
|
|
<< "0.000 " // style_val: the distance between dots and
|
|
|
|
// dashes in case of dotted or dashed lines..
|
|
|
|
<< "1 " // direction: always 1
|
|
|
|
<< "0.0000 " // angle: the radius of the x-axis: 0
|
|
|
|
<< center.x() << " " << center.y() << " " // the center..
|
|
|
|
<< radius << " " << radius << " " // radius_x and radius_y
|
|
|
|
<< center.x() << " " // start_x and start_y, appear
|
|
|
|
<< center.y() << " " // unused..
|
|
|
|
<< center.x() + radius << " " // end_x and end_y,
|
|
|
|
<< center.y() << "\n"; // appear unused too...
|
|
|
|
}
|
|
|
|
|
|
|
|
void XFigExportImpVisitor::visit( const ConicImp* imp )
|
|
|
|
{
|
|
|
|
int width = mcurobj->drawer()->width();
|
|
|
|
if ( width == -1 ) width = 1;
|
|
|
|
if ( imp->conicType() == 1 )
|
|
|
|
{
|
|
|
|
// an ellipse, this is good, cause this allows us to export to a
|
|
|
|
// real ellipse type..
|
|
|
|
const ConicPolarData data = imp->polarData();
|
|
|
|
|
|
|
|
// gather some necessary data..
|
|
|
|
// the angle of the x axis..
|
|
|
|
double anglex = atan2( data.esintheta0, data.ecostheta0 );
|
|
|
|
// the exentricity
|
|
|
|
double e = hypot( data.esintheta0, data.ecostheta0 );
|
|
|
|
// the x radius is easy to find..
|
|
|
|
double radiusx = data.pdimen / ( 1 - e * e );
|
|
|
|
// the y radius is a bit harder: we first find the distance from
|
|
|
|
// the focus point to the mid point of the two focuses, this is:
|
|
|
|
double d = -e * data.pdimen / ( 1 - e * e );
|
|
|
|
// the distance from the first focus to the intersection of the
|
|
|
|
// second axis with the conic equals radiusx:
|
|
|
|
double r = radiusx;
|
|
|
|
double radiusy = sqrt( r*r - d*d );
|
|
|
|
|
|
|
|
Coordinate center = data.focus1 - Coordinate( cos( anglex ), sin( anglex ) ).normalize( d );
|
|
|
|
const TQPoint qcenter = convertCoord( center );
|
|
|
|
const int radius_x = ( convertCoord( center + Coordinate( radiusx, 0 ) ) -
|
|
|
|
convertCoord( center ) ).x();
|
|
|
|
const int radius_y = ( convertCoord( center + Coordinate( radiusy, 0 ) ) -
|
|
|
|
convertCoord( center ) ).x();
|
|
|
|
const TQPoint qpoint2 = convertCoord( center + Coordinate( -sin( anglex ), cos( anglex ) ) * radiusy );
|
|
|
|
|
|
|
|
mstream << "1 " // ellipse type
|
|
|
|
<< "1 " // subtype: ellipse defined by readii
|
|
|
|
<< "0 " // line_style: Solid
|
|
|
|
<< width << " " // thickness
|
|
|
|
<< mcurcolorid << " " // pen_color: black
|
|
|
|
<< "7 " // fill_color: white
|
|
|
|
<< "50 " // depth: 50
|
|
|
|
<< "-1 " // pan_style: not used
|
|
|
|
<< "-1 " // area_fill: no fill
|
|
|
|
<< "0.000 " // style_val: not used
|
|
|
|
<< "1 " // direction: always 1
|
|
|
|
<< anglex << " " // angle of the main axis
|
|
|
|
<< qcenter.x() << " " // center
|
|
|
|
<< qcenter.y() << " "
|
|
|
|
<< radius_x << " " // radiuses
|
|
|
|
<< radius_y << " "
|
|
|
|
<< qcenter.x() << " " // start point
|
|
|
|
<< qcenter.y() << " "
|
|
|
|
<< qpoint2.x() << " " // end point
|
|
|
|
<< qpoint2.y() << " ";
|
|
|
|
}
|
|
|
|
else return;
|
|
|
|
}
|
|
|
|
|
|
|
|
void XFigExportImpVisitor::visit( const CubicImp* )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void XFigExportImpVisitor::visit( const SegmentImp* imp )
|
|
|
|
{
|
|
|
|
Coordinate a = imp->data().a;
|
|
|
|
Coordinate b = imp->data().b;
|
|
|
|
int width = mcurobj->drawer()->width();
|
|
|
|
if ( width == -1 ) width = 1;
|
|
|
|
|
|
|
|
emitLine( a, b, width );
|
|
|
|
}
|
|
|
|
|
|
|
|
void XFigExportImpVisitor::visit( const RayImp* imp )
|
|
|
|
{
|
|
|
|
Coordinate a = imp->data().a;
|
|
|
|
Coordinate b = imp->data().b;
|
|
|
|
calcRayBorderPoints( a, b, msr );
|
|
|
|
|
|
|
|
int width = mcurobj->drawer()->width();
|
|
|
|
if ( width == -1 ) width = 1;
|
|
|
|
|
|
|
|
emitLine( a, b, width );
|
|
|
|
}
|
|
|
|
|
|
|
|
void XFigExportImpVisitor::visit( const ArcImp* imp )
|
|
|
|
{
|
|
|
|
const Coordinate center = imp->center();
|
|
|
|
const double radius = imp->radius();
|
|
|
|
const double startangle = imp->startAngle();
|
|
|
|
const double endangle = startangle + imp->angle();
|
|
|
|
const double middleangle = ( startangle + endangle ) / 2;
|
|
|
|
const Coordinate ad = Coordinate( cos( startangle ), sin( startangle ) ).normalize( radius );
|
|
|
|
const Coordinate bd = Coordinate( cos( middleangle ), sin( middleangle ) ).normalize( radius );
|
|
|
|
const Coordinate cd = Coordinate( cos( endangle ), sin( endangle ) ).normalize( radius );
|
|
|
|
const TQPoint a = convertCoord( center + ad );
|
|
|
|
const TQPoint b = convertCoord( center + bd );
|
|
|
|
const TQPoint c = convertCoord( center + cd );
|
|
|
|
const TQPoint cent = convertCoord( center );
|
|
|
|
|
|
|
|
mstream << "5 " // Ellipse type
|
|
|
|
<< "1 " // subtype: open ended arc
|
|
|
|
<< "0 "; // line_style: Solid
|
|
|
|
int width = mcurobj->drawer()->width();
|
|
|
|
if ( width == -1 ) width = 1;
|
|
|
|
mstream << width << " " // thickness: *1/80 inch
|
|
|
|
<< mcurcolorid << " " // pen_color: default
|
|
|
|
<< "7 " // fill_color: white
|
|
|
|
<< "50 " // depth: 50
|
|
|
|
<< "-1 " // pen_style: unused by XFig
|
|
|
|
<< "-1 " // area_fill: no fill
|
|
|
|
<< "0.000 " // style_val: the distance between dots and
|
|
|
|
// dashes in case of dotted or dashed lines..
|
|
|
|
<< "0 "; // cap_style: Butt..
|
|
|
|
// 0 is clockwise, 1 is counterclockwise .
|
|
|
|
int direction = imp->angle() > 0 ? 1 : 0;
|
|
|
|
// direction next
|
|
|
|
mstream << direction << " " // direction..
|
|
|
|
<< "0 " // forward_arrow: no
|
|
|
|
<< "0 " // backward_arrow: no
|
|
|
|
<< cent.x() << " " << cent.y() << " " // the center..
|
|
|
|
<< a.x() << " " << a.y() << " " // x1, y1
|
|
|
|
<< b.x() << " " << b.y() << " " // x2, y2
|
|
|
|
<< c.x() << " " << c.y() << " " // x3, y3
|
|
|
|
<< "\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
void XFigExporter::run( const KigPart& doc, KigWidget& w )
|
|
|
|
{
|
|
|
|
KigFileDialog* kfd = new KigFileDialog(
|
|
|
|
":document", i18n( "*.fig|XFig Documents (*.fig)" ),
|
|
|
|
i18n( "Export as XFig File" ), &w );
|
|
|
|
if ( !kfd->exec() )
|
|
|
|
return;
|
|
|
|
|
|
|
|
TQString file_name = kfd->selectedFile();
|
|
|
|
|
|
|
|
delete kfd;
|
|
|
|
|
|
|
|
TQFile file( file_name );
|
|
|
|
if ( ! file.open( IO_WriteOnly ) )
|
|
|
|
{
|
|
|
|
KMessageBox::sorry( &w, i18n( "The file \"%1\" could not be opened. Please "
|
|
|
|
"check if the file permissions are set correctly." )
|
|
|
|
.arg( file_name ) );
|
|
|
|
return;
|
|
|
|
};
|
|
|
|
TQTextStream stream( &file );
|
|
|
|
stream << "#FIG 3.2\n";
|
|
|
|
stream << "Landscape\n";
|
|
|
|
stream << "Center\n";
|
|
|
|
stream << "Metric\n";
|
|
|
|
stream << "A4\n";
|
|
|
|
stream << "100.00\n";
|
|
|
|
stream << "Single\n";
|
|
|
|
stream << "-2\n";
|
|
|
|
stream << "1200 2\n";
|
|
|
|
|
|
|
|
std::vector<ObjectHolder*> os = doc.document().objects();
|
|
|
|
XFigExportImpVisitor visitor( stream, w );
|
|
|
|
|
|
|
|
for ( std::vector<ObjectHolder*>::const_iterator i = os.begin();
|
|
|
|
i != os.end(); ++i )
|
|
|
|
{
|
|
|
|
visitor.mapColor( ( *i )->drawer() );
|
|
|
|
};
|
|
|
|
|
|
|
|
for ( std::vector<ObjectHolder*>::const_iterator i = os.begin();
|
|
|
|
i != os.end(); ++i )
|
|
|
|
{
|
|
|
|
visitor.visit( *i );
|
|
|
|
};
|
|
|
|
}
|