1 /* 2 * Copyright (C) 2015 Dan Leinir Turthra Jensen <admin@leinir.dk> 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) version 3, or any 8 * later version accepted by the membership of KDE e.V. (or its 9 * successor approved by the membership of KDE e.V.), which shall 10 * act as a proxy defined in Section 6 of version 3 of the license. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 19 * 20 */ 21 22 #ifndef ACBFPAGE_H 23 #define ACBFPAGE_H 24 25 #include "AcbfDocument.h" 26 /** 27 * \brief Class to handle page objects. 28 * 29 * A proper ACBF document should have entries for all pages 30 * and said entries should point at the images that make up 31 * the comic. 32 * 33 * However, ACBF also has room from frame definitions, transcriptions, 34 * translations, table of contents, jumps and more. 35 * 36 * The frame definitions are used to navigate a page and zoom efficiently on a 37 * small screen. Similarly, transscriptions and translations can be used to show 38 * text when the image itself is too blurry. 39 * 40 * Title is used to generate a table of contents. 41 * 42 * Transition is to indicate extra information about how the page should be entered. 43 * 44 * bgcolor is used by the reading software to determine what background color to give. 45 * 46 * Jumps can be used to move around in the comic. 47 * 48 * TODO: Frame and Jump seem to be missing classes despite being used here? 49 */ 50 class QXmlStreamWriter; 51 class QXmlStreamReader; 52 namespace AdvancedComicBookFormat 53 { 54 class Textlayer; 55 class Frame; 56 class Jump; 57 class ACBF_EXPORT Page : public QObject 58 { 59 Q_OBJECT 60 Q_PROPERTY(QString bgcolor READ bgcolor WRITE setBgcolor NOTIFY bgcolorChanged) 61 Q_PROPERTY(QString transition READ transition WRITE setTransition NOTIFY transitionChanged) 62 Q_PROPERTY(QString imageHref READ imageHref WRITE setImageHref NOTIFY imageHrefChanged) 63 Q_PROPERTY(QStringList textLayerLanguages READ textLayerLanguages NOTIFY textLayerLanguagesChanged) 64 Q_PROPERTY(QStringList framePointStrings READ framePointStrings NOTIFY framePointStringsChanged) 65 Q_PROPERTY(QObjectList jumps READ jumps NOTIFY jumpsChanged) 66 public: 67 // Pages can also be cover pages, which means they can also be children of BookInfo 68 explicit Page(Document* parent = nullptr); 69 ~Page() override; 70 71 /** 72 * \brief Write the page into the xml writer. 73 */ 74 void toXml(QXmlStreamWriter* writer); 75 /** 76 * \brief load a page element into this object. 77 * @return True if the xmlReader encountered no errors. 78 */ 79 bool fromXml(QXmlStreamReader *xmlReader); 80 81 /** 82 * @return the background color as a QString. 83 * 84 * It should be an 8bit per channel rgb hexcode. 85 */ 86 QString bgcolor() const; 87 /** 88 * \brief set the background color. 89 * 90 * @param newColor - a String with an 8bit per channel rgb hexcode (#ff00ff, or the like) 91 */ 92 void setBgcolor(const QString& newColor = QString()); 93 /** 94 * @brief fires when the background color changes. 95 */ 96 Q_SIGNAL void bgcolorChanged(); 97 /** 98 * @return transition type as a string. 99 */ 100 QString transition() const; 101 /** 102 * \brief set the transition type. 103 * @param transition - the transition type, possible entries are in the availableTransitions() stringlist. 104 */ 105 void setTransition(const QString& transition); 106 /** 107 * @brief fires when the transition type changes. 108 */ 109 Q_SIGNAL void transitionChanged(); 110 /** 111 * @returns a list of strings that can be used for the transition. 112 */ 113 Q_INVOKABLE static QStringList availableTransitions(); 114 115 /** 116 * @return all titles for this page in all languages. 117 */ 118 Q_INVOKABLE QStringList titleForAllLanguages() const; 119 /** 120 * @param language - the language of the entry in language code, country 121 * code format joined by a dash (not an underscore). 122 * @return the title for this language. 123 */ 124 Q_INVOKABLE QString title(const QString& language = QString()) const; 125 /** 126 * \brief set the title for this language. 127 * @param language - the language of the entry in language code, country 128 * code format joined by a dash (not an underscore). 129 */ 130 Q_INVOKABLE void setTitle(const QString& title, const QString& language = QString()); 131 /** 132 * @brief titlesChanged 133 */ 134 Q_SIGNAL void titlesChanged(); 135 136 /** 137 * @returns the URI for the image of this page as a QString 138 */ 139 QString imageHref() const; 140 /** 141 * \brief set the URI for the image of this page. 142 * @param imageHref - the URI to an image. 143 * 144 * - A Binary representation will use the ID of that representation. 145 * - A reference to a file on the internet will start with "http://" or "https://" 146 * - A reference to a file in a zip will be prefixed with "zip:" 147 * - Everything else is presumed to be a file on disk. 148 */ 149 void setImageHref(const QString& imageHref); 150 /** 151 * @brief fires when the image url changes. 152 */ 153 Q_SIGNAL void imageHrefChanged(); 154 155 /** 156 * @returns all the textlayers objects. 157 */ 158 QList<Textlayer*> textLayersForAllLanguages() const; 159 /** 160 * @param language - the language of the entry in language code, country 161 * code format joined by a dash (not an underscore). 162 * @returns the TextLayer object for that language. 163 */ 164 Q_INVOKABLE Textlayer* textLayer(const QString& language = QString()) const; 165 /** 166 * 167 * @param language - the language of the entry in language code, country 168 * code format joined by a dash (not an underscore). Setting the textlayer 169 * for a language to null removes that language (as with other translated 170 * entries, though this one not being text warranted a comment) 171 */ 172 void setTextLayer(Textlayer* textlayer, const QString& language = QString()); 173 /** 174 * @brief add a textlayer for language. 175 * @param language code to add a textlayer for. 176 */ 177 Q_INVOKABLE void addTextLayer(const QString& language = QString()); 178 /** 179 * @brief remove a text layer by language. 180 * @param language code to remove the textlayer for. 181 */ 182 Q_INVOKABLE void removeTextLayer(const QString& language = QString()); 183 /** 184 * @brief duplicate a text layer to a different language, if languageFrom doesn't 185 * exist this makes a new text layer. 186 * @param languageFrom the language from which to duplicate. 187 * @param languageTo the language to make the new text layer at. 188 */ 189 Q_INVOKABLE void duplicateTextLayer(const QString&languageFrom, const QString& languageTo = QString()); 190 /** 191 * @brief get the possible translations. 192 * @return a stringlist with all the languages available. 193 */ 194 QStringList textLayerLanguages() const; 195 /** 196 * @brief fires when the textlayer languages list changes 197 * 198 * this can happen when text layers are added or removed. 199 */ 200 Q_SIGNAL void textLayerLanguagesChanged(); 201 202 /** 203 * @returns a list of frames in this page. 204 */ 205 QList<Frame*> frames() const; 206 /** 207 * @param index - index of the frame. 208 * @return the frame of that index. 209 */ 210 Q_INVOKABLE Frame* frame(int index) const; 211 /** 212 * @param frame - the frame you want to index of. 213 * @returns the index of the given frame. 214 */ 215 int frameIndex(Frame* frame) const; 216 217 /** 218 * \brief add a frame to the list of frames. 219 * @param frame - the frame to add. 220 * @param index - the index to add it at. If afterIndex is larger than 221 * zero, the insertion will happen at that index 222 */ 223 void addFrame(Frame* frame, int index = -1); 224 /** 225 * \brief remove the given frame from the framelist. 226 * @param frame - the frame to remove. 227 */ 228 void removeFrame(Frame* frame); 229 /** 230 * @brief remove frame by index. 231 * @param index index of the frame to remove. 232 */ 233 Q_INVOKABLE void removeFrame(int index); 234 /** 235 * @brief add a frame at index.. 236 * @param index - the index to add it at. If afterIndex is larger than 237 * zero, the insertion will happen at that index 238 */ 239 Q_INVOKABLE void addFrame(int index = -1); 240 /** 241 * \brief Swap two frames in the list. 242 * @param swapThis - the first index to swap. 243 * @param withThis - the second index to swap. 244 */ 245 Q_INVOKABLE bool swapFrames(int swapThis, int withThis); 246 /** 247 * @brief returns the amount of frames as a stringlist. 248 * This is a hack to ensure that qml repeaters may update properly. 249 * @return a string list containing strings with the point counts of said frames. 250 */ 251 QStringList framePointStrings(); 252 /** 253 * @brief fires when the frame point strings change. 254 */ 255 Q_SIGNAL void framePointStringsChanged(); 256 257 /** 258 * @return the list of jump objects for this page. 259 */ 260 QObjectList jumps() const; 261 /** 262 * @param index - the index for which you want the jump object. 263 * @return a jump object for the given frame. 264 */ 265 Q_INVOKABLE Jump* jump(int index) const; 266 /** 267 * @param jump - the jump you want to index of. 268 * @returns the index of the given jump. 269 */ 270 int jumpIndex(Jump* jump) const; 271 272 /** 273 * \brief add a jump to the list of frames. 274 * @param jump - the jump to add. 275 * @param index - the index to add it at. If afterIndex is larger than 276 * zero, the insertion will happen at that index 277 */ 278 void addJump(Jump* jump, int index = -1); 279 /** 280 * @brief addJump 281 * @param index - the index to add it at. If afterIndex is larger than 282 * zero, the insertion will happen at that index 283 */ 284 Q_INVOKABLE void addJump(int pageIndex, int index = -1); 285 /** 286 * \brief remove the given jump from the list of jumps. 287 * @param jump - the jump to remove. 288 */ 289 void removeJump(Jump* jump); 290 /** 291 * @brief removeJump 292 * @param index to remove the jump at. 293 */ 294 Q_INVOKABLE void removeJump(int index); 295 /** 296 * \brief Swap two jumps in the list. 297 * @param swapThis - the first index to swap. 298 * @param withThis - the second index to swap. 299 */ 300 Q_INVOKABLE bool swapJumps(int swapThis, int withThis); 301 /** 302 * @brief Emitted when the list of jumps changes. 303 */ 304 Q_SIGNAL void jumpsChanged(); 305 306 /** 307 * @returns whether this is the cover page. 308 */ 309 bool isCoverPage() const; 310 /** 311 * \brief toggle whether this is the cover page. 312 * 313 */ 314 void setIsCoverPage(bool isCoverPage = false); 315 private: 316 class Private; 317 std::unique_ptr<Private> d; 318 }; 319 } 320 321 #endif//ACBFPAGE_H 322