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