1 /*
2 For general Scribus (>=1.3.2) copyright and licensing information please refer
3 to the COPYING file provided with the program. Following this notice may exist
4 a copyright and/or license notice that predates the release of Scribus 1.3.2
5 for which a new license (GPL+exception) is in place.
6 */
7 #ifndef SCRIBUS_LOADSAVEPLUGIN_H
8 #define SCRIBUS_LOADSAVEPLUGIN_H
9 
10 #include "scplugin.h"
11 
12 #include <QString>
13 #include <QRegExp>
14 #include <QIODevice>
15 #include <QProgressBar>
16 #include <QStringList>
17 #include <QList>
18 
19 class FileFormat;
20 //TODO REmove includes one day
21 class ScribusView;
22 #include "scfonts.h"
23 #include "scribusdoc.h"
24 #include "undomanager.h"
25 
26 /*!
27  * @brief Superclass for all file import/export/load/save plugins
28  *
29  * This class provides the interface common to all file load/save/import/export
30  * plugins. It provides the facilities for discovering what format(s) a plugin
31  * supports, how they should be identified, etc.
32  */
33 class SCRIBUS_API LoadSavePlugin : public ScPlugin
34 {
35 	Q_OBJECT
36 
37 	public:
38 		// Construct a plugin instance.
39 		LoadSavePlugin();
40 		~LoadSavePlugin();
41 
42 		enum loadFlags
43 		{
44 			lfCreateDoc       =   1,
45 			lfUseCurrentPage  =   2,
46 			lfInsertPage      =   4,
47 			lfInteractive     =   8,
48 			lfScripted        =  16,
49 			lfKeepColors      =  32,
50 			lfKeepGradients   =  64,
51 			lfKeepPatterns    = 128,
52 			lfCreateThumbnail = 256,
53 			lfLoadAsPattern   = 512,
54 			lfNoDialogs       = 1024
55 		};
56 
57 		// Static functions:
58 
59 		// Return a list of file extensions
60 		static QStringList getExtensionsForColors(const int id = 47);
61 		// Return a list of file extensions
62 		static QStringList getExtensionsForImport(const int id = 47);
63 		// Return a list of file extensions
64 		static QStringList getExtensionsForPreview(const int id = 47);
65 
66 		// Return a list of format descriptions suitable for use with
67 		// QFileDialog.  You can convert it to QString form with
68 		// fileDialogSaveFilter().join(";;")
69 		static QStringList fileDialogLoadFilter();
70 
71 		// Same deal but for save
72 		static QStringList fileDialogSaveFilter();
73 
74 		// Get the highest priority format of a given id, or 0 if
75 		// not found / not available.
76 		static const FileFormat * getFormatById(const int id);
77 		static FileFormat * getFormatByID(int id);
78 		static FileFormat* getFormatByExt(const QString& ext);
79 
80 		virtual bool loadElements(const QString& data, const QString&, int, double, double, bool);
81 		// Non-static members implemented by plugins:
82 		//
83 		// Load the requested format from the specified path.
84 		// Default implementation always reports failure.
85 		virtual bool loadFile(const QString & fileName, const FileFormat & fmt, int flags, int index = 0);
86 		virtual bool loadPalette(const QString & fileName);
87 
88 		// Save the requested format to the requested path.
89 		virtual bool saveFile(const QString & fileName, const FileFormat & fmt);
90 		virtual bool savePalette(const QString & fileName);
91 		virtual QString saveElements(double, double, double, double, Selection*, QByteArray &prevData);
92 
93 		// Save requested item story
94 		virtual bool loadStory(const QByteArray& data, StoryText& story, PageItem* item);
95 		virtual bool saveStory(StoryText& story, PageItem* item, QByteArray& data);
96 
97 		// Return last file saved, this may be the last fileName argument passed to saveFile(),
98 		// a temporary file name or an empty string if last call to saveFile() could not create
99 		// a valid file
100 		virtual const QString& lastSavedFile(void);
101 
102 		// Examine the passed file and test to see whether it appears to be
103 		// loadable with this plugin. This test must be quick and simple.
104 		// It need not verify a file, just confirm that it looks like a supported
105 		// file type (eg "XML doc with root element SCRIBUSXML and version 1.3.1").
106 		// All plugins must implement this method.
107 		virtual bool fileSupported(QIODevice* file, const QString & fileName=QString()) const = 0;
108 
109 		// Examine if the passed palette data to see whether it appears to be loadable with this plugin
110 		virtual bool paletteSupported(QIODevice* file, const QString & fileName=QString()) const { return false; }
111 
112 		// Examine if the passed story data to see whether it appears to be loadable with this plugin
storySupported(const QByteArray & storyData)113 		virtual bool storySupported(const QByteArray& storyData) const { return false; }
114 
115 		// Return a list of all formats supported by all currently loaded and
116 		// active plugins. This list is sorted in a very specific order:
117 		// First, by descending order of `id', then descending order of priority.
118 		static const QList<FileFormat> & supportedFormats();
119 
120 		virtual void setupTargets(ScribusDoc *targetDoc, ScribusView* targetView, ScribusMainWindow* targetMW, QProgressBar* targetMWPRogressBar, SCFonts* targetAvailableFonts);
121 		virtual void getReplacedFontData(bool & getNewReplacement, QMap<QString,QString> &getReplacedFonts, QList<ScFace> &getDummyScFaces);
122 		virtual bool loadPage(const QString & fileName, int pageNumber, bool Mpage, const QString& renamedPageName=QString());
123 		virtual bool readStyles(const QString& fileName, ScribusDoc* doc, StyleSet<ParagraphStyle> &docParagraphStyles);
124 		virtual bool readCharStyles(const QString& fileName, ScribusDoc* doc, StyleSet<CharStyle> &docCharStyles);
125 		virtual bool readLineStyles(const QString& fileName, QHash<QString, multiLine> *Sty);
126 		virtual bool readColors(const QString& fileName, ColorList & colors);
127 		virtual bool readPageCount(const QString& fileName, int *num1, int *num2, QStringList & masterPageNames);
128 		virtual QImage readThumbnail(const QString& fileName);
129 
130 	protected:
131 
132 		/// Check a loadFlags combination
133 		virtual bool checkFlags(int flags);
134 
135 		/// Register the passed format so it can be used by the app
136 		void registerFormat(FileFormat & fmt);
137 
138 		/// Unregister the format with format ID `id' that references by the calling plugin.
139 		void unregisterFormat(unsigned int id);
140 
141 		/// Unregister all formats owned by the calling plugin
142 		void unregisterAll();
143 
144 		// Set standard message for file read errors
145 		virtual void setFileReadError();
146 
147 		// Set standard message for dom style errors with line and column
148 		virtual void setDomParsingError(const QString& msg, int line, int column);
149 
150 		ScribusDoc*        m_Doc { nullptr };
151 		ScribusView*       m_View { nullptr }; //For 1.2.x loader at the moment
152 		ScribusMainWindow* m_ScMW { nullptr }; //For plugins when required
153 		QProgressBar*      m_mwProgressBar { nullptr };
154 		SCFonts*           m_AvailableFonts { nullptr };
155 		QString            m_lastSavedFile;
156 		UndoManager * const undoManager { nullptr };
157 
158 	private:
159 		// A list of all supported formats. This is maintained by plugins
160 		// using the protected `registerFormat(...)', `unregisterFormat(...)'
161 		// and `unregisterAll(...)' methods. This is sorted in a very specific
162 		// order - ascending ID, then descending priority.
163 		static QList<FileFormat> formats;
164 
165 		// Return an iterator referencing the first format structure named `name'.
166 		// If specified, only return formats implmented by `plug'.
167 		// If `start' is specified, start searching at this iterator rather than the
168 		// start of the list.
169 		// The end iterator is returned if no match was found.
170 		// Note that due to the sort order maintained in `formats', the first
171 		// iterator returned by this method will always be to the highest
172 		// priority format of the required ID, and each subsequent call will
173 		// return the next lowest priority format.
174 		static QList<FileFormat>::iterator findFormat(unsigned int id,
175 				LoadSavePlugin* plug = 0,
176 				QList<FileFormat>::iterator it = formats.begin());
177 
178 		static QList<FileFormat>::iterator findFormat(const QString& extension,
179 				LoadSavePlugin* plug = 0,
180 				QList<FileFormat>::iterator it = formats.begin());
181 
182 		// Print out a format list for debugging purposes
183 		static void printFormatList();
184 
185 		// Base implementation for fileDialogLoadFilter and fileDialogSaveFilter
186 		static const QStringList getDialogFilter(bool forLoad);
187 };
188 
189 
190 
191 // Info on each supported format. A plugin must register a
192 // FileFormat structure for every format it knows how to load or
193 // save. If it both loads and saves a given format, one structure must
194 // be registered for load and one for save.
195 // Plugins must unregister formats when being unloaded to ensure that
196 // no attempt is made to load a file using a plugin that's no longer
197 // available.
198 //
199 // This class also provides methods to ask the implementation to load / save a
200 // file in this format.
201 class SCRIBUS_API FileFormat
202 {
203 	public:
204 		// Default ctor to make QValueList happy
205 		FileFormat();
206 		// Standard ctor that sets up a valid FileFormat
207 		FileFormat(LoadSavePlugin * plug);
208 
209 		bool loadElements(const QString & data, const QString& fileDir, int toLayer, double Xp_in, double Yp_in, bool loc) const;
210 
211 		// Load a file with this format
212 		bool loadFile(const QString & fileName, int flags, int index = 0) const;
213 		bool loadPalette(const QString & fileName) const;
214 
215 		// Save a file with this format
216 		bool saveFile(const QString & fileName) const;
217 		bool savePalette(const QString & fileName) const;
218 		QString saveElements(double xp, double yp, double wp, double hp, Selection* selection, QByteArray &prevData) const;
219 
220 		// Save item story with this format
221 		bool loadStory(const QByteArray& data, StoryText& story, PageItem* item) const;
222 		bool saveStory(StoryText& story, PageItem* item, QByteArray& data) const;
223 
224 		// Get last saved file
225 		QString lastSavedFile() const;
226 
227 		void setupTargets(ScribusDoc *targetDoc, ScribusView* targetView, ScribusMainWindow* targetMW, QProgressBar* targetMWPRogressBar, SCFonts* targetAvailableFonts) const;
228 		void getReplacedFontData(bool & getNewReplacement, QMap<QString,QString> &getReplacedFonts, QList<ScFace> &getDummyScFaces) const;
229 		bool loadPage(const QString & fileName, int pageNumber, bool Mpage, const QString& renamedPageName=QString()) const;
230 		bool readStyles(const QString& fileName, ScribusDoc* doc, StyleSet<ParagraphStyle> &docParagraphStyles) const;
231 		bool readCharStyles(const QString& fileName, ScribusDoc* doc, StyleSet<CharStyle> &docCharStyles) const;
232 		bool readLineStyles(const QString& fileName, QHash<QString,multiLine> *Sty) const;
233 		bool readColors(const QString& fileName, ColorList & colors) const;
234 		bool readPageCount(const QString& fileName, int *num1, int *num2, QStringList & masterPageNames) const;
235 		QImage readThumbnail(const QString& fileName) const;
236 
237 		//
238 		// Data members
239 		//
240 		// An integer ID code used to idenfify formats. Should be unique
241 		// across all FileFormat structures except where they implement
242 		// support for the same file format, eg sla 1.2.x, sla 1.3.x and
243 		// "new format" SLA should all have equal IDs (with different
244 		// priorities to control what order they're tried in when a user
245 		// tries to open a file).
246 		// Note that dialog box options are sorted in descending `id' order.
247 		uint formatId { 0 };
248 		// The human-readable, translated name of this file format.
249 		QString trName;
250 		// A filter in the format used by QFileDialog that should be used to
251 		// select for this format.
252 		QString filter;
253 		// Regexp to match filenames for this format
254 	//	QRegExp nameMatch;
255 		// MIME type(s) that should be matched by this format.
256 		QStringList mimeTypes;
257 		// Extension list supported by format
258 		QStringList fileExtensions;
259 		// Can we load it?
260 		bool load { false };
261 		// Can we save it?
262 		bool save { false };
263 		// Do we support thumbnails
264 		bool thumb { false };
265 		// Can we load colors?
266 		bool colorReading { false };
267 		//Native Scribus format (for putting at the top of the file loader lists)
268 		bool nativeScribus { false };
269 		// Priority of this format from 0 (lowest, tried last) to
270 		// 255 (highest, tried first). 64-128 recommended in general.
271 		// Priority controls the order options are displayed in when a file
272 		// of a given type is selected in a dialog, and controls the order
273 		// loaders are tried in when multiple plugins support the same file
274 		// type.
275 		unsigned short int priority { 0 };
276 		// For convenience, a pointer back to the plugin to use to open
277 		// this format.
278 		LoadSavePlugin * plug { nullptr };
279 };
280 
281 
282 
283 #endif
284