1 // SPDX-FileCopyrightText: 2003 Dominique Devriese <devriese@kde.org>
2 
3 // SPDX-License-Identifier: GPL-2.0-or-later
4 
5 #include "exporter.h"
6 
7 #include "imageexporteroptions.h"
8 #include "latexexporter.h"
9 #include "asyexporter.h"
10 #include "svgexporter.h"
11 #include "xfigexporter.h"
12 
13 #include "../kig/kig_document.h"
14 #include "../kig/kig_part.h"
15 #include "../kig/kig_view.h"
16 #include "../misc/common.h"
17 #include "../misc/kigfiledialog.h"
18 #include "../misc/kigpainter.h"
19 
20 #include <QImageWriter>
21 #include <QMimeDatabase>
22 #include <QStandardPaths>
23 
24 #include <KIconEngine>
25 #include <KActionMenu>
26 #include <KActionCollection>
27 #include <KMessageBox>
28 
ExporterAction(const KigPart * doc,KigWidget * w,KActionCollection * parent,KigExporter * exp)29 ExporterAction::ExporterAction( const KigPart* doc, KigWidget* w,
30                                 KActionCollection* parent, KigExporter* exp )
31   : QAction( exp->menuEntryName(), parent),
32     mexp( exp ), mdoc( doc ), mw( w )
33 {
34   QString iconstr = exp->menuIcon();
35   if ( !iconstr.isEmpty() )
36     setIcon( QIcon( new KIconEngine( iconstr, const_cast<KigPart*>( doc )->iconLoader() ) ) );
37   connect( this, &QAction::triggered, this, &ExporterAction::slotActivated );
38   if(parent)
39     parent->addAction(QStringLiteral("action"), this );
40 }
41 
slotActivated()42 void ExporterAction::slotActivated()
43 {
44   mexp->run( *mdoc, *mw );
45 }
46 
~KigExporter()47 KigExporter::~KigExporter()
48 {
49 }
50 
~ImageExporter()51 ImageExporter::~ImageExporter()
52 {
53 }
54 
exportToStatement() const55 QString ImageExporter::exportToStatement() const
56 {
57   return i18n( "&Export to image" );
58 }
59 
menuEntryName() const60 QString ImageExporter::menuEntryName() const
61 {
62   return i18n( "&Image..." );
63 }
64 
menuIcon() const65 QString ImageExporter::menuIcon() const
66 {
67   return QStringLiteral("image-x-generic");
68 }
69 
run(const KigPart & doc,KigWidget & w)70 void ImageExporter::run( const KigPart& doc, KigWidget& w )
71 {
72   KigFileDialog* kfd = new KigFileDialog(
73       QStandardPaths::writableLocation( QStandardPaths::PicturesLocation ), QString(),
74       i18n( "Export as Image" ), &w );
75   const QList<QByteArray> mimeFilters = QImageWriter::supportedMimeTypes();
76   QStringList mimeFiltersConverted;
77   // Since someone didn't get the memo about what's the type of a mime name...
78   for (const auto &mimeFilter : mimeFilters) {
79       mimeFiltersConverted.append( QString::fromUtf8( mimeFilter ) );
80   }
81   kfd->setMimeTypeFilters( mimeFiltersConverted );
82   kfd->setOptionCaption( i18n( "Image Options" ) );
83   ImageExporterOptions* opts = new ImageExporterOptions( 0L );
84   kfd->setOptionsWidget( opts );
85   opts->setImageSize( w.size() );
86   opts->setGrid( doc.document().grid() );
87   opts->setAxes( doc.document().axes() );
88   if ( !kfd->exec() )
89     return;
90 
91   QString filename = kfd->selectedFile();
92   bool showgrid = opts->showGrid();
93   bool showaxes = opts->showAxes();
94   QSize imgsize = opts->imageSize();
95 
96   delete opts;
97   delete kfd;
98 
99   QMimeDatabase db;
100   QMimeType mimeType = db.mimeTypeForFile( filename );
101   qDebug() << "mimetype: " << mimeType.name();
102   if ( !QImageWriter::supportedMimeTypes().contains( mimeType.name().toUtf8() ) )
103   {
104     KMessageBox::sorry( &w, i18n( "Sorry, this file format is not supported." ) );
105     return;
106   };
107 
108   QFile file( filename );
109   if ( ! file.open( QIODevice::WriteOnly ) )
110   {
111     KMessageBox::sorry( &w,
112                         i18n( "The file \"%1\" could not be opened. Please check if the file permissions are set correctly." ,
113                           filename ) );
114     return;
115   };
116 
117   QPixmap img( imgsize );
118   img.fill( Qt::white );
119   KigPainter p( ScreenInfo( w.screenInfo().shownRect(), img.rect() ), &img, doc.document() );
120   p.setWholeWinOverlay();
121   p.drawGrid( doc.document().coordinateSystem(), showgrid, showaxes );
122   // FIXME: show the selections ?
123   p.drawObjects( doc.document().objects(), false );
124   const QStringList types = mimeType.suffixes();
125   if ( types.isEmpty() ) return; // TODO error dialog?
126   if ( !img.save( filename, types.at(0).toLatin1() ) )
127   {
128     KMessageBox::error( &w, i18n( "Sorry, something went wrong while saving to image \"%1\"", filename ) );
129   }
130 
131 }
132 
KigExportManager()133 KigExportManager::KigExportManager()
134 {
135   mexporters.push_back( new ImageExporter );
136   mexporters.push_back( new XFigExporter );
137   mexporters.push_back( new LatexExporter );
138   mexporters.push_back( new AsyExporter );
139   mexporters.push_back( new SVGExporter );
140 }
141 
~KigExportManager()142 KigExportManager::~KigExportManager()
143 {
144   for ( uint i = 0; i < mexporters.size(); ++i )
145     delete mexporters[i];
146 }
147 
addMenuAction(const KigPart * doc,KigWidget * w,KActionCollection * coll)148 void KigExportManager::addMenuAction( const KigPart* doc, KigWidget* w,
149                                       KActionCollection* coll )
150 {
151   KActionMenu* m = new KActionMenu( i18n( "&Export To" ), w );
152   m->setIcon( QIcon( new KIconEngine( "document-export", const_cast<KigPart*>( doc )->iconLoader() ) ) );
153   for ( uint i = 0; i < mexporters.size(); ++i )
154     m->addAction( new ExporterAction( doc, w, coll, mexporters[i] ) );
155   if(coll)
156     coll->addAction(QStringLiteral("file_export"), m );
157 }
158 
instance()159 KigExportManager* KigExportManager::instance()
160 {
161   static KigExportManager m;
162   return &m;
163 }
164