1 /*************************************************************************** 2 * file klflib.h 3 * This file is part of the KLatexFormula Project. 4 * Copyright (C) 2011 by Philippe Faist 5 * philippe.faist at bluewin.ch 6 * * 7 * This program is free software; you can redistribute it and/or modify * 8 * it under the terms of the GNU General Public License as published by * 9 * the Free Software Foundation; either version 2 of the License, or * 10 * (at your option) any later version. * 11 * * 12 * This program 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 * 15 * GNU General Public License for more details. * 16 * * 17 * You should have received a copy of the GNU General Public License * 18 * along with this program; if not, write to the * 19 * Free Software Foundation, Inc., * 20 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 21 ***************************************************************************/ 22 /* $Id: klflib.h 881 2014-06-15 21:23:43Z phfaist $ */ 23 24 #ifndef KLFLIB_H 25 #define KLFLIB_H 26 27 #include <QImage> 28 #include <QMap> 29 #include <QUrl> 30 #include <QDataStream> 31 #include <QDateTime> 32 #include <QFileInfo> 33 34 #include <klfdefs.h> 35 #include <klfbackend.h> 36 37 #include <klfpobj.h> 38 #include <klffactory.h> 39 #include <klfstyle.h> 40 41 42 43 class KLFProgressReporter; 44 45 46 47 /** \brief An entry (single formula) in the library 48 * 49 * Stores Latex code, Date/Time of evaluation, A preview image, A Category String, 50 * A Tags String, and a Style in a KLFPropertizedObject-based object. 51 * 52 * This object can be used as a normal value (ie. it has copy constructor, assignment 53 * operator and default constructor). 54 */ 55 class KLF_EXPORT KLFLibEntry : public KLFPropertizedObject { 56 public: 57 /** \note The numeric IDs don't have to be preserved from one version of KLF to 58 * another, since they are nowhere stored. Properties are always stored by name 59 * when dealing in scopes larger than the running application (saved files, etc.). 60 */ 61 enum PropertyId { 62 Latex = 0, //!< The Latex Code of the equation 63 DateTime, //!< The Date/Time at which the equation was evaluated 64 Preview, //!< An Image Preview of equation (scaled down QImage) 65 PreviewSize, //!< A cached value of the size of value in \c Preview 66 Category, //!< The Category to which eq. belongs (path-style string) 67 Tags, //!< Tags about the equation (string) 68 Style //!< KLFStyle style used 69 }; 70 71 KLFLibEntry(const QString& latex = QString(), const QDateTime& dt = QDateTime(), 72 const QImage& preview = QImage(), const QSize& previewsize = QSize(), 73 const QString& category = QString(), const QString& tags = QString(), 74 const KLFStyle& style = KLFStyle()); 75 /** This constructor extracts the legacy-style category and tags from latex, and 76 * stores latex with those tags stripped. */ 77 KLFLibEntry(const QString& latex, const QDateTime& dt, const QImage& preview, 78 const KLFStyle& style); 79 KLFLibEntry(const KLFLibEntry& copy); 80 virtual ~KLFLibEntry(); 81 latex()82 inline QString latex() const { return property(Latex).toString(); } dateTime()83 inline QDateTime dateTime() const { return property(DateTime).toDateTime(); } preview()84 inline QImage preview() const { return property(Preview).value<QImage>(); } previewSize()85 inline QSize previewSize() const { return property(PreviewSize).value<QSize>(); } category()86 inline QString category() const { return property(Category).toString(); } tags()87 inline QString tags() const { return property(Tags).toString(); } style()88 inline KLFStyle style() const { return property(Style).value<KLFStyle>(); } 89 latexWithCategoryTagsComments()90 inline QString latexWithCategoryTagsComments() const 91 { return latexAddCategoryTagsComment(latex(), category(), tags()); } 92 setLatex(const QString & latex)93 inline void setLatex(const QString& latex) { setProperty(Latex, latex); } setDateTime(const QDateTime & dt)94 inline void setDateTime(const QDateTime& dt) { setProperty(DateTime, dt); } setPreview(const QImage & img)95 inline void setPreview(const QImage& img) { setProperty(Preview, img); } setPreviewSize(const QSize & sz)96 inline void setPreviewSize(const QSize& sz) { setProperty(PreviewSize, sz); } 97 /** \note this function normalizes category to remove any double-'/' to avoid empty sections. 98 * Equality between categories can be compared stringwise. 99 * 100 * See also \ref normalizeCategoryPath(). */ setCategory(const QString & s)101 inline void setCategory(const QString& s) { setProperty(Category, normalizeCategoryPath(s)); } setTags(const QString & s)102 inline void setTags(const QString& s) { setProperty(Tags, s); } setStyle(const KLFStyle & style)103 inline void setStyle(const KLFStyle& style) { setProperty(Style, QVariant::fromValue(style)); } 104 105 /** Set the property named \c name to value \c value. If the property does not 106 * yet exist in the registered properties, it is registered. 107 * 108 * \returns -1 for error, or the property ID that was successfully (maybe registered 109 * and) set. 110 */ 111 int setEntryProperty(const QString& propName, const QVariant& value); 112 113 114 /** Parses and returns legacy-style category comment string from latex string 115 * in the form <pre>%: Category</pre> */ 116 static QString categoryFromLatex(const QString& latex); 117 /** Parses and returns legacy-style tags comment string from latex string */ 118 static QString tagsFromLatex(const QString& latex); 119 /** Removes legacy-style category and tags comment from latex string */ 120 static QString stripCategoryTagsFromLatex(const QString& latex); 121 /** Creates a latex with category and tags comments */ 122 static QString latexAddCategoryTagsComment(const QString& latex, const QString& category, 123 const QString& tags); 124 /** Renders a category-path "pretty" by removing any double-slashes to single slashes. 125 * Trailing slashes are removed. The root category is an empty string. 126 * 127 * When a category is set to a lib-entry with \c setCategory(), it is automatically 128 * normalized. 129 * 130 * Returned paths may be compared string-wise for equality. 131 */ 132 static QString normalizeCategoryPath(const QString& categoryPath); 133 134 private: 135 136 void initRegisteredProperties(); 137 }; 138 139 Q_DECLARE_METATYPE(KLFLibEntry) 140 ; 141 142 typedef QList<KLFLibEntry> KLFLibEntryList; 143 144 145 //! Contains general definitions to be used anywhere in the KLFLib* framework 146 namespace KLFLib { 147 //! An entry ID 148 /** The type of the ID of an entry in a library resource (see \ref KLFLibResourceEngine) 149 * 150 * \note This type is signed, and may be assigned a negative value. Negative values 151 * should only indicate invalid IDs. Valid IDs are always positive. 152 * 153 * \note \ref KLFLibResourceEngine::entryId is a typedef of \ref KLFLib::entryId. 154 * 155 * */ 156 typedef qint32 entryId; 157 158 159 /** Describes a matching criterion for a string 160 * 161 * Note: The Qt::MatchWrap and Qt::MatchRecursive flags are ignored. 162 */ 163 struct StringMatch { 164 StringMatch(const QVariant& value = QVariant(), Qt::MatchFlags flags = Qt::MatchExactly) mFlagsStringMatch165 : mFlags(flags), mValue(value), mValueString(value.toString()) { } StringMatchStringMatch166 StringMatch(const StringMatch& m) : mFlags(m.mFlags), mValue(m.mValue), mValueString(m.mValueString) { } 167 168 /** How the match should be tested (exact match, regex, contains, etc.), this is 169 * a binary-OR'ed value of Qt::MatchFlag enum values. 170 * 171 * the Qt::MatchCaseSensitive may be set to match case sensitive. 172 */ matchFlagsStringMatch173 inline const Qt::MatchFlags matchFlags() const { return mFlags; } 174 /** The value that will be matched to. */ matchValueStringMatch175 inline const QVariant matchValue() const { return mValue; } 176 /** equivalent to <tt>matchValue().toString()</tt>, however the conversion is 177 * performed once and cached. */ matchValueStringStringMatch178 inline const QString matchValueString() const { return mValueString; } 179 180 protected: 181 Qt::MatchFlags mFlags; 182 QVariant mValue; 183 QString mValueString; 184 }; 185 186 /** Discribes a matching criterion for the value of a property ID. Although not assumed 187 * in this definition, property IDs will eventually refer to KLFPropertizedObject property 188 * IDs, more specifically \ref KLFLibEntry property IDs. 189 */ 190 struct PropertyMatch : public StringMatch { 191 /** propId is the ID of the property which will have to match as given by \c match */ 192 PropertyMatch(int propId = -1, const StringMatch& match = StringMatch()) StringMatchPropertyMatch193 : StringMatch(match), mPropertyId(propId) { } 194 /** copy constructor */ PropertyMatchPropertyMatch195 PropertyMatch(const PropertyMatch& other) : StringMatch(other), mPropertyId(other.mPropertyId) { } 196 197 /** Returns the propery ID set in the constructor. */ propertyIdPropertyMatch198 inline int propertyId() const { return mPropertyId; } 199 200 protected: 201 int mPropertyId; 202 }; 203 204 /** This is a generalized condition. It can be one of several types. 205 * 206 * In the future, more match condition types may be added. For now, the following 207 * matching condition types are supported. 208 * - property string matching (see \ref PropertyMatch) 209 * - AND of N conditions 210 * - OR of N conditions 211 * 212 * This class is meant for use with findEntries(). 213 */ 214 struct EntryMatchCondition 215 { 216 enum Type { 217 MatchAllType = 0, //!< Matches all entries 218 PropertyMatchType, //!< Matches a property ID with a string (with a \ref StringMatch) 219 NegateMatchType, //!< Matches entries that don't match a condition 220 OrMatchType, //!< entries have to match with one of a list of conditions 221 AndMatchType //!< entries have to match with all given conditions 222 }; 223 224 //! Get which type of condition this is typeEntryMatchCondition225 inline Type type() const { return mType; } 226 //! Relevant for type PropertyMatchType propertyMatchEntryMatchCondition227 inline PropertyMatch propertyMatch() const { return mPropertyMatch; } 228 //! Relevant for types OrMatchType and AndMatchType conditionListEntryMatchCondition229 inline QList<EntryMatchCondition> conditionList() const { return mConditionList; } 230 231 static EntryMatchCondition mkMatchAll(); 232 static EntryMatchCondition mkPropertyMatch(PropertyMatch pmatch); 233 /** Stores \c condition in first element of conditionList(). */ 234 static EntryMatchCondition mkNegateMatch(const EntryMatchCondition& condition); 235 static EntryMatchCondition mkOrMatch(QList<EntryMatchCondition> conditions); 236 static EntryMatchCondition mkAndMatch(QList<EntryMatchCondition> conditions); 237 238 protected: EntryMatchConditionEntryMatchCondition239 EntryMatchCondition(Type type) : mType(type) { } 240 241 Type mType; 242 243 PropertyMatch mPropertyMatch; 244 QList<EntryMatchCondition> mConditionList; 245 }; 246 247 } 248 249 //! Utility class for sorting library entry items 250 /** 251 * This class can be used as a sorter to sort entry items. 252 * 253 * This class functions as follows: 254 * - operator()() calls compareLessThan() with the stored propId() and order(). 255 * - \ref compareLessThan() in turns calls entryValue() to get string representations of the 256 * values of the property to compare for each entry, and compares the strings with 257 * \ref QString::localeAwareCompare(). 258 * - \ref entryValue() provides sensible string representations for the given property in the 259 * given entry. 260 * 261 * \note The column number may be set to be equal \c -1, to indicate an invalid sorter (maybe 262 * to indicate that a list should not be sorted). However, the functions \ref entryValue(), 263 * \ref compareLessThan() and operator()() are NOT meant to be used with an invalid \c propId. 264 * In other words, if isValid() is false (or equivalently, if \ref propId() is negative), don't 265 * attempt any sorting or comparisions. 266 * 267 * To customize the behaviour of this class, you may subclass it and reimplement any level 268 * of its behavior, eg. you may want to just reimplement entryValue() to alter the string 269 * representation of the values of some properties, or you could reimplement compareLessThan() 270 * to do more sophisticated comparisions. 271 * 272 * \note There is no copy constructor. If there was, there would be no way of customizing the sort 273 * behavior. To use the entry sorter in contexts where you need to copy an object, use the 274 * clone mechanism with the clone constructor. (Although this should scarcely be needed ...). 275 */ 276 class KLF_EXPORT KLFLibEntrySorter 277 { 278 public: 279 KLFLibEntrySorter(int propId = -1, Qt::SortOrder order = Qt::AscendingOrder); 280 /** Used to "circumvent" the copy-constructor issues of reimplemented functions. 281 * If an object is constructed using this constructor all calls to entryValue(), 282 * compareLessThan(), and operator()() are redirected to clone's. 283 * 284 * Calls to setPropId() and setOrder() will fail and emit a warning. 285 * 286 * In particular, never pass 'this' nor 'NULL' as clone! 287 */ 288 KLFLibEntrySorter(const KLFLibEntrySorter *clone); 289 virtual ~KLFLibEntrySorter(); 290 isValid()291 inline bool isValid() const { return (pPropId >= 0); } 292 293 //! The currently set property that will be queried in the items we're sorting propId()294 inline int propId() const { return pPropId; } 295 //! The currently set sorting order order()296 inline Qt::SortOrder order() const { return pOrder; } 297 298 //! Set the KLFLibEntry property id the sort will take into account 299 virtual void setPropId(int propId); 300 //! Set the sort order 301 virtual void setOrder(Qt::SortOrder order); 302 303 //! Returns a string representation of the given property in the given entry 304 virtual QString entryValue(const KLFLibEntry& entry, int propId) const; 305 306 //! Compares entries two entries according to the given property and order 307 /** Compares the given property of entries \c a and \c b. 308 * 309 * When \c order is \c Qt::Ascending, if \c a is found to be less than (and not equal) to 310 * \c b, then TRUE is returned, otherwise FALSE is returned. 311 * 312 * If the \c order is \c Qt::Descending, if \c b is found to be less than (and not equal) to 313 * \c a, then TRUE is returned, otherwise FALSE is returned. 314 */ 315 virtual bool compareLessThan(const KLFLibEntry& a, const KLFLibEntry& b, 316 int propId, Qt::SortOrder order) const; 317 318 /** This is a wrapper that calls \ref compareLessThan() with the previously set 319 * propId() and order(). 320 */ 321 virtual bool operator()(const KLFLibEntry& a, const KLFLibEntry& b) const; 322 323 324 private: 325 const KLFLibEntrySorter * pCloneOf; 326 327 int pPropId; 328 Qt::SortOrder pOrder; 329 }; 330 331 332 333 /** \brief An abstract resource engine 334 * 335 * This class is the base of all resource types. Subclasses (e.g. KLFLibDBEngine) implement 336 * the actual access to the data, while this class defines the base API that will be used 337 * by e.g. the library browser (through a KLFAbstractLibView subclass) to access the data. 338 * 339 * Subclasses may choose to implement various features specified by the \ref ResourceFeature 340 * enum. The supported features must be passed (binary OR-ed) to the constructor. 341 * 342 * Library resources provide entries without any particular order. 343 * 344 * Library entries are communicated with KLFLibEntry objects. Each entry in the resource must 345 * be attributed a numerical ID, which is unique within the resource, in particular not 346 * necessarily globally unique among all open resources. For engines implementing the 347 * \ref FeatureSubResources feature, the attributed IDs have only to be unique within the 348 * sub-resource the entry lives in. 349 * 350 * Entries are queried by calling for example the functions: \ref allEntries(), \ref entries(), 351 * \ref entry(). See the individual function documentation for more details. 352 * 353 * The API in this class for accessing data is pretty elaborate. You may consider to subclass 354 * \ref KLFLibResourceSimpleEngine, which requires you to implement a simpler API, but at the 355 * price of not being able to take profit of the optimization opportunities given by the 356 * more complicated API. 357 * 358 * <b>Resource Properties</b>. Resources have properties (stored in a 359 * KLFPropertizedObject structure, NOT in regular QObject 360 * properties) that ARE STORED IN THE RESOURCE DATA ITSELF. Built-in properties are listed 361 * in the \ref ResourceProperty enum. Some properties may be implemented read-only 362 * (eg. \ref PropAccessShared) in which case saveResourceProperty() should return FALSE. 363 * 364 * The view used to display this resource is stored in the "ViewType" resource property (and 365 * thus should be stored in the backend data like other properties). 366 * 367 * <b>Note on URL</b>. The URL is not a resource property as it is not stored in the resource 368 * itself. However the resource engine instance knows about the url it is manipulating 369 * (because subclasses pass the relevant url as parameter in the constructor). However, the 370 * URL itself blindly stored and reprovided when requested; it is not used by 371 * KLFLibResourceEngine itself. Small exception: in the constructor, some query items are 372 * recognized and stripped from the URL. See below. 373 * 374 * <b>Read-Only Mode</b>. The read-only mode differs from the locked property in that the 375 * mode is activated by the accessor only and is NOT stored in the resource data eg. on disk 376 * (in contrast to the locked property). It is up to SUBCLASSES to enforce this flag and 377 * prevent data from being modified if isReadOnly() is TRUE.<br> 378 * Subclasses may prevent read-only mode by not specifying 379 * the FeatureReadOnly in the constructor. In this case the default implementation of 380 * \ref setReadOnly() will return FALSE without doing anything. Also in this case, any 381 * occurrence of the query item "klfReadOnly" in the URL is stripped and ignored. 382 * 383 * <b>Sub-Resources</b>. Sub-resources are a way of logically separating the contents of 384 * a resource into separate so-called "sub-resources", like for example a library could 385 * contain a sub-resource "History", "Archive" etc. Derived subclasses don't have to 386 * implement subresources, they can specify if subresources are available using the 387 * FeatureSubResources flag in the constructor. In classes implementing sub-resources, 388 * the <i>default sub-resource</i> (queried by \ref defaultSubResource() and set by 389 * \ref setDefaultSubResource()) is the resource that the \ref insertEntry(), 390 * \ref changeEntries(), etc. 391 * family functions will access when the variant of the function without sub-resource 392 * argument is called. 393 * 394 * <b>Sub-Resource Properties</b>. Sub-resources, when implemented by the subclass, may 395 * each have properties (the API would suggest subclasses to store these property values 396 * into \ref KLFPropertizedObject's). The properties (structure+values) are NOT stored 397 * by KLFLibResourceEngine itself, all the work must be done by the subclass, in particular 398 * reimplementing \ref subResourceProperty() and \ref setSubResourceProperty(). Again this 399 * feature is implemented by the subclass if and only if the subclass specified 400 * \ref FeatureSubResourceProps in the constructor argument. In this case note also that views 401 * may for example expect the resource to provide values for the sub-resource properties defined 402 * by \ref SubResourceProperty. 403 * 404 * <b>query Items in URL</b>. The URL may contain query items e.g. 405 * <tt>scheme://klf.server.dom/path/to/location<b>?klfReadOnly=true</b></tt>. Here is a 406 * list of recognized (universal) query items. Subclasses may choose to recognize more query 407 * items, but these listed here are detected in the KLFLibResourceEngine constructor and 408 * the appropriate flags are set (eg. \ref isReadOnly()): 409 * - <tt>klfReadOnly=</tt>{<tt>true</tt>|<tt>false</tt>} If provided, sets the read-only 410 * flag to the given value. If not provided, the flag defaults to false (flag is directly 411 * set, bypassing the setReadOnly() function). 412 * - <tt>klfDefaultSubResource=<i>sub-resource name</i></tt> If provided, specifies which 413 * sub-resource (which has to be present in the given location) should be opened by default. 414 * See \ref setDefaultSubResource(). 415 * . 416 * Note that recognized query items (and <i>only</i> the query items recognized at the 417 * KLFLibResourceEngine level) are stripped from the \ref url() as they are parsed. Subclasses 418 * may choose to (independently) recognize and strip other query items from URL if it is relevant 419 * to do so. 420 * 421 * <b>NOTES FOR SUBCLASSES</b><br> 422 * - Subclasses must deal with the properties and implement them as they are meant to, and 423 * as they have been documented in their respective functions (see \ref locked(), \ref title()). 424 * For example, if a resource is \ref locked(), then \ref canModifyData() and \ref canModifyProp() 425 * must return FALSE and any attempt to modify the resource must fail. 426 * - Subclasses must reimplement \ref saveResourceProperty() to save the new property value 427 * to the backend data, or return FALSE to cancel the resource change. Calls to 428 * \ref setLocked(), \ref setTitle() or setViewType() all call in turn \ref setResourceProperty(), 429 * the default implementation of which is usually sufficient, which calls in turn 430 * \ref saveResourceProperty(). 431 * - See also docs for \ref setResourceProperty() and \ref saveResourceProperty(). 432 * - The \ref resourcePropertyChanged() is emitted in the default implementation of 433 * \ref setResourceProperty(). 434 * - lengthy operations should emit the signal \ref operationStartReportingProgress() with a suitable 435 * KLFProgressReporter as necessary to inform callers of progress of operations that can take some 436 * time. This is recommended, but subclasses aren't forced to comply (for laziness' sake for ex...). 437 * However, subclasses should test ONCE per operation whether \ref thisOperationProgressBlocked() and 438 * should not emit progress in that case. 439 */ 440 class KLF_EXPORT KLFLibResourceEngine : public QObject, public KLFPropertizedObject 441 { 442 Q_OBJECT 443 public: 444 typedef KLFLib::entryId entryId; 445 446 //! A KLFLibEntry in combination with a KLFLib::entryId 447 struct KLFLibEntryWithId { 448 KLFLibEntryWithId(entryId i = -1, const KLFLibEntry& e = KLFLibEntry()) idKLFLibEntryWithId449 : id(i), entry(e) { } 450 entryId id; 451 KLFLibEntry entry; 452 }; 453 454 /** List of built-in KLFPropertizedObject-properties. See 455 * \ref KLFLibResourceEngine "class documentation" and \ref setResourceProperty(). */ 456 enum ResourceProperty { 457 PropTitle = 0, 458 PropLocked, 459 PropViewType, 460 PropAccessShared 461 }; 462 463 /** List of pre-defined properties that can be applied to sub-resources when the features 464 * \ref FeatureSubResources and \ref FeatureSubResourceProps are implemented. See also 465 * \ref setSubResourceProperty(). 466 * 467 * \note These properties, by contrast to resource properties, have fixed numerical IDs, since 468 * sub-resource properties are not backed by a KLFPropertizedObject object. */ 469 enum SubResourceProperty { 470 SubResPropTitle = 0, 471 SubResPropLocked = 1, 472 SubResPropViewType = 2 473 }; 474 475 //! Features that may or may not be implemented by subclasses 476 /** These binary codes specify features that a subclass may or may not implement. 477 * 478 * The subclass provides the binary combination of the exact features it supports in the 479 * constructor argument in \ref KLFLibResourceEngine(). 480 * 481 * The flags can be accessed with a call to \ref supportedFeatureFlags(). They cannot be 482 * modified after the constructor call. 483 * 484 * See this \ref KLFLibResourceEngine "class documentation" for more details. 485 */ 486 enum ResourceFeature { 487 //! Open in Read-Only mode 488 /** Flag indicating that this resource engine supports opening a location in read-only mode. 489 * This resource explicitely checks that we're not \ref isReadOnly() before modifying the 490 * resource contents. */ 491 FeatureReadOnly = 0x0001, 492 //! Lock the resource 493 /** Flag indicating that this resource engine supports the resource property \ref PropLocked, 494 * can modify that property and checks that we're not \ref locked() before modifying the 495 * resource contents. 496 * 497 * Resources supporting feature \ref FeatureSubResourceProps, in combination with this feature 498 * (FeatureLocked) are also expected to treat properly locked sub-resources (ie. sub-resource 499 * property \ref SubResPropLocked). */ 500 FeatureLocked = 0x0002, 501 //! Implements the \ref saveTo() function 502 /** Flag indicating that this resource engine implements the saveTo() function, ie. that 503 * calling it has a chance that it will not fail */ 504 FeatureSaveTo = 0x0004, 505 //! Data can be stored in separate sub-resources 506 /** Flag indicating that this resource engine supports saving and reading data into different 507 * "sub-resources". See \ref KLFLibResourceEngine "class documentation" for details. */ 508 FeatureSubResources = 0x0008, 509 //! Sub-Resources may be assigned properties and values 510 /** Flag indicating that this resource engine supports saving and reading sub-resource 511 * property values. This flag makes sense only in combination with \c FeatureSubResources. 512 * Note that views may assume that implementing sub-resource properties means also providing 513 * sensible values and/or loaded/stored values for the built-in sub-resource properties 514 * described in the \ref SubResourceProperty enum. */ 515 FeatureSubResourceProps = 0x0010 516 }; 517 518 /** 519 * 520 * \note If the URL \c url needs to be normalized in some way (eg. convert some query item 521 * values to lower case, ...), then you need to implement a static function, eg. 522 * \code 523 * static KLFMyEngine * openURL(const QUrl& url) { 524 * QUrl normalized = url; 525 * // ... normalize URL ... 526 * return new KLFMyEngine(normalized, ...); 527 * } 528 * KLFMyEngine::KLFMyEngine(const QUrl& url, ...) : KLFLibResourceEngine(url,...) 529 * { 530 * // ... 531 * } 532 * \endcode 533 * which will pass the normalized URL here. You cannot change the URL once it has been 534 * passed to the constructor. Note however that the stored URL has some elements stripped, 535 * as described in the class documentation \ref KLFLibResourceEngine, which you can 536 * change via the API (eg. setDefaultSubResource()). 537 */ 538 KLFLibResourceEngine(const QUrl& url, uint supportedfeatureflags, QObject *parent = NULL); 539 540 virtual ~KLFLibResourceEngine(); 541 542 //! List of features supported by this resource engine 543 /** Use this function to probe whether this resource instance supports a specific 544 * feature. For example a property editor widget might want to know if this resource 545 * supportes the \ref FeatureLocked feature, to enable or disable the corresponding 546 * check box. 547 * 548 * Do not reimplement in subclasses, simply pass the feature flags to the constructor. 549 * */ supportedFeatureFlags()550 virtual uint supportedFeatureFlags() const { return pFeatureFlags; } 551 552 //! Format options one can give to \ref url() 553 enum WantUrlFormatFlag { 554 //! Add a query item for default sub-res. as \c "klfDefaultSubResource" 555 WantUrlDefaultSubResource = 0x01, 556 //! Add a query item for read-only status, as \c "klfReadOnly" 557 WantUrlReadOnly = 0x02 558 }; 559 //! query URL 560 /** Returns the identifying URL of this resource. 561 * 562 * \note This is not quite the URL passed to the constructor. Some query items are recognized 563 * and stripped. See the \ref KLFLibResourceEngine "Class Documentation" for more information. 564 * 565 * Flags may be specified as to which query items we would like to add to URL (eg. default 566 * sub-resource, read-only status). see \ref WantUrlFormatFlag. 567 * 568 * See also \ref KLFAbstractLibView::url(). That function gives also information on what part 569 * of the resource it displays. 570 */ 571 virtual QUrl url(uint flags = 0x0) const; 572 573 //! Compare this resource's URL with another's 574 /** Compares the URL of this resource with \c other, and returns a binary OR'ed value of 575 * KlfUrlCompareFlag enum values of tests that have proved true (see KlfUrlCompareFlag 576 * for a list of URL-comparision tests in klfutil.h in klftools). 577 * 578 * This function should return the following flag, if its corresponding tests turn out 579 * to be true. This function should NOT return any other flag that is not listed here. 580 * - \c KLFUrlComapreBaseEqual should be set if this resource shares its data with the resource 581 * given by URL \c other. Default sub-resources are to be ignored. 582 * 583 * The \c interestFlags is a binary OR'ed value of KlfUrlCompareFlag values of tests 584 * to be performed. Any flag that is set in \c interestFlags indicates that the return 585 * value of this function, when binary-AND'ed with that flag, is the result (T or F) 586 * of the test the flag stands for. However, if a flag is not set in \c interestFlags, 587 * its state in the return value by this function is undefined. 588 * 589 * See also klfUrlCompare(). 590 */ 591 virtual uint compareUrlTo(const QUrl& other, uint interestFlags = 0xfffffff) const = 0; 592 593 //! query read-only state 594 /** See \ref KLFLibResourceEngine "Class Documentation" for more details. */ isReadOnly()595 virtual bool isReadOnly() const { return pReadOnly; } 596 597 //! The human-set title of this resource 598 /** See \ref setTitle(). */ title()599 virtual QString title() const { return KLFPropertizedObject::property(PropTitle).toString(); } 600 601 //! Is this resource is locked? 602 /** If the resource is locked (property \ref PropLocked), no changes can be in principle made, 603 * except <tt>setLocked(false)</tt> (of course...). 604 * 605 * Note: the subclass is responsible to check in functions such as insertEntry(), that the 606 * resource is not locked and not read-only etc. (checked all-in-one with \ref canModifyData()). 607 * 608 * The default implementation has some limited support for the locked property: see 609 * \ref setLocked(). */ locked()610 virtual bool locked() const { return KLFPropertizedObject::property(PropLocked).toBool(); } 611 612 //! The (last) View Type used to display this resource viewType()613 virtual QString viewType() const 614 { return KLFPropertizedObject::property(PropViewType).toString(); } 615 616 //! If the resource is accessed by many clients 617 /** Whether the resource is meant to be shared by many clients (eg. a remote database access) 618 * or if it is local and we're the only one to use it (eg. a local sqlite file). 619 * 620 * This property may be used by views to decide if they can store meta-information about the 621 * view state in the resource itself (icon positions in icon view mode for example). */ accessShared()622 virtual bool accessShared() const 623 { return KLFPropertizedObject::property(PropAccessShared).toBool(); } 624 625 //! Get the value of a resource property 626 /** Returns the value of the given resource property. If the property is not registered, 627 * returns an invalid QVariant with a warning. 628 * 629 * For built-in resource properties, consider using the simpler \ref locked(), \ref title() 630 * and \ref viewType() methods (for example). */ 631 virtual QVariant resourceProperty(const QString& name) const; 632 633 enum ModifyType { 634 AllActionsData = 0, 635 UnknownModification = 0, 636 InsertData, 637 ChangeData, 638 DeleteData 639 }; 640 641 /** Returns TRUE here if it is possible to modify the resource's data in the way described 642 * by \c modifytype (see \ref ModifyType enum). 643 * 644 * Engines supporting feature \ref FeatureSubResources should return TRUE or FALSE whether 645 * it is possible to perform the requested action in the given sub-resource \c subResource. 646 * Other engines should ignore the \c subResource parameter. 647 * 648 * For engines supporting all of \ref FeatureSubResources, \ref FeatureSubResourceProps, and 649 * \ref FeatureLocked the default implementation checks whether the sub-resource is locked 650 * by querying \ref subResourceProperty(\ref SubResPropLocked). 651 * 652 * \c modifytype must be one of AllActionsData, InsertData, ChangeData, DeleteData. 653 * 654 * The base implementation returns TRUE only if the current resource is not read-only (see 655 * \ref isReadOnly()) and is not locked (see \ref locked()). Subclasses should reimplement 656 * this function to add more sophisticated behaviour, eg. checking that an open file is not 657 * read-only, or that a DB user was granted the correct rights, etc. 658 * 659 * \warning subclasses should call the base implementation to e.g. take into account 660 * eg. the \ref locked() property. If the base implementation returns FALSE, then the 661 * subclasses should also return FALSE. */ 662 virtual bool canModifyData(const QString& subResource, ModifyType modifytype) const; 663 664 /** This function is provided for convenience for resource not implementing 665 * \ref FeatureSubResources, or Views relying on the default sub-resource. 666 * 667 * \warning Subclasses should normally not reimplement this function, but rather the 668 * canModifyData(const QString&, ModifyType) function, even if they do not support 669 * sub-resources! 670 * 671 * The default implementation of this function (which should be sufficient in a vast majority 672 * of cases) calls 673 * \code 674 * canModifyData(defaultSubResource(), modifytype) 675 * \endcode 676 * as one would expect. 677 */ 678 virtual bool canModifyData(ModifyType modifytype) const; 679 680 /** Subclasses should return TRUE here if it is possible to modify the resource's property 681 * identified by \c propId. Return for ex. false when opening a read-only file. 682 * 683 * \warning subclasses should call the base implementation to e.g. take into account 684 * the \ref locked() property and \ref isReadOnly() state. If the base implementation 685 * returns FALSE, then the subclasses should also return FALSE. 686 * 687 * If \c propId is negative, then a more general "Can we generally speaking modify properties 688 * right now?" is returned. 689 * 690 * \note The base implementation returns TRUE if the resource is locked but if \c propId is 691 * \ref PropLocked (to be able to un-lock the resource!) */ 692 virtual bool canModifyProp(int propId) const; 693 694 /** Subclasses should return TRUE if they can handle a new resource property that they 695 * (maybe) haven't yet heard of, and if they can handle saving and loading the property 696 * as a \ref QVariant to and from the backend data. 697 * 698 * Call \ref loadResourceProperty() to actually register the property and save a value 699 * to it. */ 700 virtual bool canRegisterProperty(const QString& propName) const; 701 702 /** Suggested library view widget to view this resource with optimal user experience :-) . 703 * Return QString() for default view. */ suggestedViewTypeIdentifier()704 virtual QString suggestedViewTypeIdentifier() const { return QString(); } 705 706 /** Returns TRUE if this resource supports sub-resources and contains a sub-resource 707 * named \c subResource. 708 * 709 * The default implementation checks that the \ref FeatureSubResources is supported, and 710 * that \ref subResourceList() contains \c subResource (with exact string match). 711 * 712 * If subclasses have a more optimized method to check this, they may (but need not 713 * necessarily) reimplement this function to optimize it. 714 * 715 * Engines that have case-insensitive resource names (eg. SQL tables) must reimplement 716 * this function to do a case-insensitive test. 717 */ 718 virtual bool hasSubResource(const QString& subResource) const; 719 720 /** Returns a list of sub-resources in this resource. This function is relevant only 721 * if the \ref FeatureSubResources is implemented. */ subResourceList()722 virtual QStringList subResourceList() const { return QStringList(); } 723 724 /** Returns the default sub-resource, ie. the sub-resource to access if eg. the variant 725 * of insertEntry() without the sub-resource argument is called. 726 * 727 * This is relevant only if the engine supports feature \ref FeatureSubResources. 728 */ 729 virtual QString defaultSubResource() const; 730 731 /** \brief Compare our sub-resource name to another 732 * 733 * Returns TRUE if our default sub-resource name equals \c subResource, FALSE otherwise. 734 * 735 * The default implementation tests for string equality (case sensitive). If sub-resources 736 * in the reimplemented engine are case-insensitive, then reimplement this function to 737 * compare string case-insensitive. 738 */ 739 virtual bool compareDefaultSubResourceEquals(const QString& subResourceName) const; 740 741 /** Returns TRUE if we can create a new sub-resource in this resource. 742 * 743 * This function can be reimplemented if the resource supports feature \ref FeatureSubResources. 744 * 745 * The default implementation returns FALSE. 746 */ 747 virtual bool canCreateSubResource() const; 748 749 /** Returns TRUE if we can give the sub-resource \c subResource a new name. More specifically, 750 * returns TRUE if \ref renameSubResource() on that sub-resource has chances to succeed. 751 * 752 * This function can be reimplemented if the resource supports feature \ref FeatureSubResources. 753 * 754 * The default implementation returns FALSE. 755 */ 756 virtual bool canRenameSubResource(const QString& subResource) const; 757 758 /** Returns TRUE if we can completely delete sub-resource \c subResource from the resource. 759 * 760 * If this function returns FALSE, a subsequent call to deleteSubResoruce() is certain 761 * to fail. 762 * 763 * The default implementation returns FALSE. 764 */ 765 virtual bool canDeleteSubResource(const QString& subResource) const; 766 767 /** Queries properties of sub-resources. The default implementation returns an empty 768 * QVariant(). Test the \ref supportedFeatureFlags() for \ref FeatureSubResourceProps to 769 * see if this feature is implemented. In particular, subclasses should specify whether 770 * they implement this feature by passing the correct feature flags. */ 771 virtual QVariant subResourceProperty(const QString& subResource, int propId) const; 772 773 /** Returns a list of sub-resource properties that are supported by this resource. 774 * 775 * This function makes sense to be reimplemented and called only if this resource supports 776 * features \ref FeatureSubResources and \ref FeatureSubResourceProps. 777 * 778 * The default implementation returns an empty list. 779 */ subResourcePropertyIdList()780 virtual QList<int> subResourcePropertyIdList() const { return QList<int>(); } 781 782 /** Returns a property name for the sub-resource property \c propId. 783 * 784 * The name should be significant but machine-compatible (in particular, NOT translated) as 785 * it could be used to identify the property for example to save it possibly... 786 * 787 * the default implementation returns reasonable names for \c SubResPropTitle, 788 * \c SubResPropLocked, and \c SubResPropViewType, and returns the \c propId in a string 789 * for other IDs (\ref QString::number()). 790 * 791 * This function makes sense to be called only for engines supporting 792 * \ref FeatureSubResourceProps. 793 */ 794 virtual QString subResourcePropertyName(int propId) const; 795 796 /** Returns TRUE if the property \c propId in sub-resource \c subResource can be modified. 797 * 798 * This function should not be called or reimplemented for classes not supporting feature 799 * \ref FeatureSubResourceProps. 800 * 801 * The default implementation provides a basic functionality based on \ref baseCanModifyStatus(). 802 * If the modifiable status of the sub-resource \c subResource is \ref MS_CanModify, or if the 803 * status is \ref MS_IsLocked but the \c propId we want to modify is \ref SubResPropLocked, this 804 * function returns TRUE. In other cases it returns FALSE. 805 * 806 * In short, it behaves as you would expect it to: protect against modifications but allow 807 * un-locking of a locked sub-resource. 808 */ 809 virtual bool canModifySubResourceProperty(const QString& subResource, int propId) const; 810 811 //! query an entry in this resource 812 /** Returns the entry (in the sub-resource \c subResource) corresponding to ID \c id, or an 813 * empty KLFLibEntry() if the \c id is not valid. 814 * 815 * \note Subclasses must reimplement this function to behave as described here. 816 * 817 * For resources implementing \ref FeatureSubResources, the \c subResource argument specifies 818 * the sub-resource in which the entry should be fetched. Classes not implementing this feature 819 * should ignore this parameter. 820 * */ 821 virtual KLFLibEntry entry(const QString& subResource, entryId id) = 0; 822 823 //! query an entry in this resource 824 /** Returns the entry (for classes implementing the \ref FeatureSubResources, queries the default 825 * sub-resource) corresponding to ID \c id, or an empty KLFLibEntry() if the \c id is not valid. 826 * 827 * The default implementation calls \ref entry(const QString& subResource, entryId id) with 828 * the default subresource as argument. See \ref setDefaultSubResource(). 829 */ 830 virtual KLFLibEntry entry(entryId id); 831 832 //! query the existence of an entry in this resource 833 /** Returns TRUE if an entry with entry ID \c id exists in this resource, in the sub-resource 834 * \c subResource, or FALSE otherwise. 835 * 836 * \note Subclasses must reimplement this function to behave as described here. 837 */ 838 virtual bool hasEntry(const QString& subResource, entryId id) = 0; 839 840 //! query the existence of an entry in this resource 841 /** Returns TRUE if an entry with entry ID \c id exists in this resource or FALSE otherwise. 842 * Classes implementing the \ref FeatureSubResources will query the default sub-resource, see 843 * \ref setDefaultSubResource(). 844 * 845 * The default implementation calls \ref hasEntry(const QString& subResource, entryId id) with 846 * the default subresource as argument. See \ref setDefaultSubResource(). 847 */ 848 virtual bool hasEntry(entryId id); 849 850 //! query multiple entries in this resource 851 /** Returns a list of \ref KLFLibResourceEngine::KLFLibEntryWithId "KLFLibEntryWithId" s, that 852 * is a list of KLFLibEntry-ies with their corresponding IDs, exactly corresponding to the 853 * requested entries given in idList. The same order of entries in the returned list as in the 854 * specified \c idList is garanteed. For classes implementing sub-resources 855 * (\ref FeatureSubResources), the sub-resource \c subResource is queried. 856 * 857 * The KLFLibEntry objects are populated only of the required \c wantedEntryProperties, which is 858 * a list of IDs of KLFLibEntry properties (the KLFPropertizedObject-kind properties) that are 859 * set in the KLFLibEntry object. The other fields are left undefined. If the property 860 * list is empty (by default), then all properties are fetched and set. 861 * 862 * If in the list an ID is given which does not exist in the resource, a corresponding 863 * KLFLibEntryWithId entry is returned in which the \c entry is set to an empty \c KLFLibEntry() 864 * and the \c id is set to \c -1. 865 * 866 * If \c idList is empty, then this function returns an empty list. 867 * 868 * \note Subclasses must reimplement this function to behave as described here. 869 * */ 870 virtual QList<KLFLibEntryWithId> entries(const QString& subResource, 871 const QList<KLFLib::entryId>& idList, 872 const QList<int>& wantedEntryProperties = QList<int>()) = 0; 873 874 //! query multiple entries in this resource 875 /** Returns a list of \ref KLFLibEntryWithId's, that is a list of KLFLibEntry-ies with their 876 * corresponding IDs, exactly corresponding to the requested entries given in idList. The same 877 * order of entries in the returned list as in the specified \c idList is garanteed. For classes 878 * implementing sub-resources (\ref FeatureSubResources), the default sub-resource is 879 * queried, see \ref setDefaultSubResource(). 880 * 881 * The KLFLibEntry objects are populated only of the required \c wantedEntryProperties, which is 882 * a list of IDs of KLFLibEntry properties (the KLFPropertizedObject-kind properties) that are 883 * set in the KLFLibEntry object. The other fields are left undefined. If the property 884 * list is empty (by default), then all properties are fetched and set. 885 * 886 * If in the list an ID is given which does not exist in the resource, a corresponding 887 * KLFLibEntryWithId entry is returned in which the \c entry is set to an empty \c KLFLibEntry() 888 * and the \c id is set to \c -1. 889 * 890 * If \c idList is empty, then this function returns an empty list. 891 * 892 * The default implementation calls 893 * \ref entries(const QString& subResource, const QList<KLFLib::entryId>& idList, const QList<int>&) 894 * with the default subresource as argument. See \ref setDefaultSubResource(). 895 */ 896 virtual QList<KLFLibEntryWithId> entries(const QList<KLFLib::entryId>& idList, 897 const QList<int>& wantedEntryProperties = QList<int>()); 898 899 900 /** \brief A structure that describes a query for query() 901 * 902 * The following properties should be adjusted (by direct access) before calling query(). 903 * 904 * \c matchcondition is an \ref KLFLib::EntryMatchCondition struct that tells which properties have to be 905 * matched, how, and to what value. Only entries that match the match condition set in \c query will 906 * be returned by query(). Note that the match condition itself may be a complex condition, like an OR 907 * and AND tree of property matching conditions with strings or regexps. See \ref KLFLib::EntryMatchCondition, 908 * and \ref KLFLib::PropertyMatch for more info. The idea is that engines can translate such conditions into, 909 * eg. a SQL WHERE condition for optimized entry queries. 910 * 911 * The default match condition (set automatically in constructor) matches all entries. 912 * 913 * The first \c skip results will be ignored, and the first returned result will be the <tt>skip</tt>'th 914 * entry (that is counting from 0; or the <tt>skip+1</tt>'th, counting more intuitively from 1). By default, 915 * \c skip is zero, so no entries are skipped. The entries must be skipped \a after they have been sorted. 916 * The query() function's return value (entry count) does not include the skipped entries. 917 * 918 * A \c limit may be set to limit the number of returned results (default is \c -1, meaning no limit). 919 * 920 * \c orderPropId specifies along which KLFLibEntry property ID the items should be ordered. This 921 * can be \c -1 to specify that elements should not be ordered; their order will then be undefined. 922 * Default value: \c -1. 923 * 924 * \c orderDirection specifies in which direction the elements should be ordered. This can be 925 * Qt::AscendingOrder or Qt::DescendingOrder (lesser value first or greater value first). 926 * 927 * \c wantedEntryProperties is a list of properties the lists should be filled with. Elements in the 928 * entryWithIdList and rawEntryList lists will only have those properties listed in 929 * \c wantedEntryProperties set. The other properties are undefined (some implementations may decide 930 * to ignore this optimization). An empty list (which is the default) indicates that all entry 931 * properties have to be set. 932 */ 933 struct Query 934 { 935 /** Default constructor. sets reasonable default values as documented in class doc. */ QueryQuery936 Query() 937 : matchCondition(KLFLib::EntryMatchCondition::mkMatchAll()), 938 skip(0), 939 limit(-1), 940 orderPropId(-1), 941 orderDirection(Qt::AscendingOrder), 942 wantedEntryProperties(QList<int>()) 943 { 944 } 945 946 KLFLib::EntryMatchCondition matchCondition; 947 int skip; 948 int limit; 949 int orderPropId; 950 Qt::SortOrder orderDirection; 951 QList<int> wantedEntryProperties; 952 }; 953 954 /** \brief A structure that will hold the result of a query() query. 955 * 956 * This class will contain the entry ID list, the raw entry list and the entry-with-id 957 * list of the entries that matched the query() query this object was given to. 958 * 959 * \c fillFlags may specify which of the aforementioned lists are to be filled (those that are 960 * not needed by the caller don't have to be filled, this saves time). You may pass those flags 961 * to the constructor. 962 * 963 * Once the \c fillFlags adjusted, pass a pointer to this object to the query() function to 964 * retrieve results. 965 * 966 * \warning The lists in this object are not garanteed to be cleared at the beginning of 967 * query(). If you recycle this object to call query() a second time, be sure to clean this 968 * object first. 969 */ 970 struct QueryResult 971 { 972 enum Flags { FillEntryIdList = 0x01, FillRawEntryList = 0x02, FillEntryWithIdList = 0x04 }; 973 974 /** Constructor. Sets \c fillFlags as given, and sets reasonable default values for the other 975 * members. */ fillFlagsQueryResult976 QueryResult(uint fill_flags = 0x00) : fillFlags(fill_flags) { } 977 uint fillFlags; 978 979 QList<KLFLib::entryId> entryIdList; 980 KLFLibEntryList rawEntryList; 981 QList<KLFLibEntryWithId> entryWithIdList; 982 }; 983 984 985 //! query entries in this resource with specified property values 986 /** Returns a list of all entries in this resource (and in sub-resource \c subResource 987 * for the engines supporting this feature) that match all the required matches specifed 988 * in \c matchcondition. 989 * 990 * \note the subclass is responsible for providing a functional implementation of this function. 991 * Subclasses that don't want to pass much time to implement this feature can resort to calling 992 * the static method \ref KLFLibResourceSimpleEngine::queryImpl() that provides a functional 993 * (but not very optimized) default implementation; the 994 * KLFLibResourceSimpleEngine::testMatchConditionImpl() function may prove useful for testing match 995 * conditions; and the utilities KLFLibEntrySorter and KLFLibResourceSimpleEngine::QueryResultListSorter 996 * might prove useful for sorting entries in conjuction with qLowerBound(). 997 * 998 * \c query is a \ref Query object that describes the query. See \ref Query for details. 999 * 1000 * \c result is a \ref QueryResult structure that will be filled with the queried data. See 1001 * \ref QueryResult for details. 1002 * 1003 * The matches are returned in the following way into the \c result structure: 1004 * - if the appropriate flag in \c result is set, then <tt>result.entryIdList</tt> is set to a list 1005 * of all entry IDs that matched 1006 * - if the appropriate flag in \c result is set, then <tt>result.rawEntryList</tt> is set to a list 1007 * of all entries that matched, stored as KLFLibEntry objects. Only the requested properties 1008 * are populated (specified by <tt>query.wantedEntryProperties</tt>) 1009 * - if the appropriate flag in \c result is set, then <tt>result.entryWithIdList</tt> is set 1010 * to a list of all entries, with their corresponding entry ID, that matched (similar to the 1011 * return value of allEntries()). Only the requested properties are populated (as specified 1012 * by <tt>result.wantedEntryProperties</tt>.) 1013 * 1014 * If the \c orderPropId member in \c query is not \c -1, then the returned results (in all 1015 * to-be-filled lists) are ordered according to the entry property ID \c orderPropId, in the order 1016 * specified by \c orderDirection. 1017 * 1018 * \returns the number of items in the resource that matched. If a \c limit was set in \c query, 1019 * then at most that many results are returned. \c 0 is returned if no match was found. \c -1 1020 * can be returned to signify an error (eg. invalid regexp, i/o error, etc.). 1021 * 1022 * The KLFLibEntry objects are populated only of the required \c wantedEntryProperties as set in 1023 * \c query (see \ref Query), which is a list of IDs of KLFLibEntry properties (the 1024 * KLFPropertizedObject-kind properties) that are set in the KLFLibEntry object. If the property 1025 * list is empty (by default), then all properties are fetched and set. Note that if this list 1026 * is not empty, then the properties not in the list are undefined: they may be uninitialized, 1027 * set to null/invalid, or filled eg. by an implementation that ignores \c wantedEntryProperties. 1028 * 1029 * \note it is possible to specify a property ID in the match condition that isn't given in 1030 * \c wantedEntryProperties, and reimplementations must handle this. <i>Reason: even if 1031 * this may seem inconsistent, it can be easily implemented in some examples of engines (SQL 1032 * condition, ...) and can easily be worked around in other engines by adding the requested 1033 * property to the wanted property list. Example: listing entries by date/time order, without 1034 * necessarily displaying the date/time.</i> 1035 */ 1036 virtual int query(const QString& subResource, const Query& query, QueryResult *result) = 0; 1037 1038 1039 /** \brief List all distinct values that a property takes in all entries 1040 * 1041 * \return A list of all (distinct) values that a given property in all the entries of sub-resource 1042 * \c subResource takes. 1043 * 1044 * For example, KLFLibModel uses this function in category tree mode to get the category tree, 1045 * by passing \ref KLFLibEntry::Category as \c entryPropId. 1046 * 1047 * The order of the elements within the returned list is not defined. 1048 * 1049 * In mathematical terms, if $f_{pid}(entry)$ is the value of property ID \c pid of the entry \c entry, 1050 * then this function returns the \a range (=set of all reached values) of $f_{pid}$. 1051 * 1052 * KLFLibResourceSimpleEngine::queryValuesImpl() offers a very simple non-optimized implementation 1053 * of this function that you can use in your resource engine subclass if you don't want to do this 1054 * yourself. That function is automatically re-implemented if you subclass KLFLibResourceSimpleEngine. 1055 */ 1056 virtual QList<QVariant> queryValues(const QString& subResource, int entryPropId) = 0; 1057 1058 1059 //! Returns all IDs in this resource (and this sub-resource) 1060 /** Returns a list of the ID of each entry in this resource. 1061 * 1062 * If sub-resources are supported, then returns only IDs in the given \c subResource. 1063 * Otherwise, the \c subResource parameter should be ignored. 1064 */ 1065 virtual QList<KLFLib::entryId> allIds(const QString& subResource) = 0; 1066 1067 //! Returns all IDs in this resource (and the default sub-resource) 1068 /** Returns a list of the ID of each entry in this resource. 1069 * 1070 * If sub-resources are supported, then returns only IDs in the default sub-resource 1071 * given by \ref defaultSubResource(). 1072 * 1073 * The base implementation calls \ref allIds(const QString&) with the default sub-resource 1074 * as parameter. Subclasses need not reimplement this function, but rather 1075 * \ref allIds(const QString&) instead. 1076 */ 1077 virtual QList<KLFLib::entryId> allIds(); 1078 1079 //! query all entries in this resource 1080 /** Returns all the entries in this library resource (in sub-resource \c subResource if 1081 * \ref FeatureSubResources is supported) with their corresponding IDs. 1082 * 1083 * \note Subclasses must reimplement this function to behave as described here. 1084 */ 1085 virtual QList<KLFLibEntryWithId> allEntries(const QString& subResource, 1086 const QList<int>& wantedEntryProperties = QList<int>()) = 0; 1087 1088 //! query all entries in this resource 1089 /** Returns all the entries in this library resource (in default sub-resource if 1090 * \ref FeatureSubResources is supported) with their corresponding IDs. 1091 * 1092 * The default implementation calls 1093 * \ref allEntries(const QString& subResource, const QList<int>&) with the default subresource 1094 * as argument. See \ref setDefaultSubResource(). 1095 */ 1096 virtual QList<KLFLibEntryWithId> allEntries(const QList<int>& wantedEntryProperties = QList<int>()); 1097 1098 1099 //! Specifies that the next operation (only) should not report progress 1100 void blockProgressReportingForNextOperation(); 1101 1102 //! (Un)Blocks generally progress reporting 1103 void blockProgressReporting(bool block); 1104 1105 signals: 1106 //! Emitted when data has changed 1107 /** This signal is emitted whenever data changes in the model (eg. due to an \ref insertEntries() 1108 * function call). 1109 * 1110 * The parameter \c subResource is the sub-resource in which the change was observed. 1111 * 1112 * The parameter \c modificationType is the type of modification that occured. It is one 1113 * of \ref InsertData, \ref ChangeData, \ref DeleteData, or \ref UnknownModification. (In 1114 * particular, sub-classes should not emit other modification types). The \c int type is 1115 * used for compatibility in Qt's SIGNAL-SLOT mechanism. 1116 * 1117 * An \c UnknownModification change means either the library resource changed completely, 1118 * or simply the backend does not wish to privide any information on which entries changed. 1119 * In any case, the receiver should consider all previously read data from the resource as 1120 * out of date and refresh all. 1121 * 1122 * The entries that were changed are given in the argument \c entryIdList. 1123 */ 1124 void dataChanged(const QString& subResource, int modificationType, 1125 const QList<KLFLib::entryId>& entryIdList); 1126 1127 //! Emitted when the default sub-resource changes. 1128 void defaultSubResourceChanged(const QString& newDefaultSubResource); 1129 1130 //! Emitted when a resource property changes. 1131 /** \param propId the ID of the property that changed. */ 1132 void resourcePropertyChanged(int propId); 1133 1134 //! Emitted when a sub-resource property changes. 1135 /** This signal should only be emitted by engines supporting feature \ref FeatureSubResourceProps 1136 * as well as \ref FeatureSubResources. 1137 * 1138 * \param subResource the affected sub-resource name 1139 * \param propId the ID of the property that changed 1140 */ 1141 void subResourcePropertyChanged(const QString& subResource, int propId); 1142 1143 //! Emitted when a sub-resource is created 1144 /** This signal should be emitted by engines supporting feature \ref FeatureSubResources, at 1145 * the end of a (successful) \ref createSubResource() call.\ 1146 */ 1147 void subResourceCreated(const QString& newSubResource); 1148 1149 //! Emitted when a sub-resource is renamed 1150 /** This signal should be emitted by engines supporting feature \ref FeatureSubResources, at 1151 * the end of a (successful) \ref renameSubResource() call.\ 1152 */ 1153 void subResourceRenamed(const QString& oldSubResourceName, 1154 const QString& newSubResourceName); 1155 1156 //! Emitted when a sub-resource is deleted 1157 /** This signal should be emitted by engines supporting feature \ref FeatureSubResources, at 1158 * the end of a (successful) \ref deleteSubResource() call. 1159 */ 1160 void subResourceDeleted(const QString& subResource); 1161 1162 1163 /** Emitted at the beginning of a long operation during which progress will be reported 1164 * by emission of KLFProgressReporter::progress() of the given object \c progressReporter. 1165 * 1166 * \param progressReporter is the object that will emit its progress() at regular intervals 1167 * to inform caller of operation progress. 1168 * \param descriptiveText is some text describing the nature of the operation in progress 1169 * 1170 * Subclasses have to use KLFProgressReporter directly. It's very simple to use, example: 1171 * \code 1172 * int do_some_long_computations(...) { 1173 * int num_of_steps = ... ; 1174 * KLFProgressReporter progressReporter(0, num_of_steps, this); 1175 * // ... 1176 * int current_step = 0; 1177 * for ( ... many iterations ... ) { 1178 * progressReporter.doReportProgress(current_step++); 1179 * 1180 * .... // perform a long computation iteration 1181 * 1182 * } 1183 * // finally emit the last progress value 1184 * progressReporter.doReportProgress(num_of_steps); 1185 * ... 1186 * return some_result; 1187 * } 1188 * \endcode 1189 * 1190 * The signal operationStartReportingProgress() is suitable to use in conjunction with 1191 * a KLFProgressDialog. 1192 */ 1193 void operationStartReportingProgress(KLFProgressReporter *progressReporter, 1194 const QString& descriptiveText); 1195 1196 1197 1198 public slots: 1199 1200 //! set a new resource title for this library resource 1201 /** Stores the new resource title. The title is a human string to display eg. in the 1202 * tabs of the KLFLibBrowser library browser. [KLFLibBrowser: see klfapp library] 1203 * 1204 * This function calls directly \ref setResourceProperty(). 1205 * 1206 * The default implementation should suffice; subclass \ref saveResourceProperty() 1207 * for actually saving the new value into the resource backend data, and for more control 1208 * over setting properties, or possibly subclass \ref setResourceProperty() for even more 1209 * control. 1210 * */ 1211 virtual bool setTitle(const QString& title); 1212 1213 //! Set the resource to be locked 1214 /** See \ref locked() for more doc. 1215 * 1216 * If the feature flags do not contain \ref FeatureLocked, then this function returns 1217 * immediately FALSE. Otherwise, this function calls \ref setResourceProperty() with 1218 * arguments \ref PropLocked and the new value. 1219 * 1220 * 1221 * The default implementation should suffice; subclass \ref saveResourceProperty() 1222 * for actually saving the new value into the resource backend data, and for more control 1223 * over setting properties, or possibly subclass \ref setResourceProperty() for even more 1224 * control. 1225 */ 1226 virtual bool setLocked(bool locked); 1227 1228 /** Store the given view type in the ViewType property. 1229 * 1230 * Calls directly \ref setResourceProperty(). 1231 * 1232 * The default implementation should suffice; subclass \ref saveResourceProperty() 1233 * for actually saving the new value into the resource backend data, and for more control 1234 * over setting properties, or possibly subclass \ref setResourceProperty() for even more 1235 * control. 1236 * */ 1237 virtual bool setViewType(const QString& viewType); 1238 1239 //! Set the resource to be read-only or not 1240 /** If the \ref FeatureReadOnly was given to the constructor, The base implementation sets 1241 * the read-only flag to \c readonly (this is then returned by \ref isReadOnly()). The 1242 * base implementation does nothing and returns FALSE if the feature \ref FeatureReadOnly is 1243 * not supported. 1244 */ 1245 virtual bool setReadOnly(bool readonly); 1246 1247 //! Set the default sub-resource 1248 /** When calling the variants of insertEntry(), changeEntry(), etc. that do not take a 1249 * sub-resource argument, and when this resource implements \ref FeatureSubResources, then 1250 * calls to those functions will access the <i>default sub-resource</i>, which can be 1251 * set with this function. 1252 * 1253 * This function should be used only with subclasses implementing \ref FeatureSubResources. 1254 * 1255 * The default implementation remembers \c subResource to be the new \ref defaultSubResource() and 1256 * emits \ref defaultSubResourceChanged(). It does nothing if \c subResource is already the default 1257 * sub-resource. 1258 * 1259 * \warning Reimplementing this function has a drawback: it will not be called with the argument 1260 * given in the constructor (impossible to call reimplemented virtual methods in base constructor). 1261 * Instead, the sub-class has to explicitely call its own implementation in its own constructor 1262 * to ensure full proper initialization. 1263 */ 1264 virtual void setDefaultSubResource(const QString& subResource); 1265 1266 //! Create a new sub-resource 1267 /** If they implement the feature \ref FeatureSubResources, subclasses may reimplement this 1268 * function to create a new sub-resource named \c subResource, with human title \c subResourceTitle. 1269 * 1270 * \c subResourceTitle should be ignored for resources not implementing the \ref FeatureSubResourceProps 1271 * feature. 1272 * 1273 * \returns TRUE for success or FALSE for failure. 1274 * 1275 * Subclasses should reimplement this function to provide functionality if they wish. The default 1276 * implementation does nothing and returns FALSE. 1277 * 1278 * \note engines not implementing sub-resource properties should also subclass this function and 1279 * not the other one, without the \c subResourceTitle parameter. This is because internally this 1280 * function is ultimately called in all cases. 1281 */ 1282 virtual bool createSubResource(const QString& subResource, const QString& subResourceTitle); 1283 1284 //! Create a new sub-resource 1285 /** This function is provided for convenience. It calls 1286 * \code 1287 * createSubResource(subResource, QString()); 1288 * \endcode 1289 * and returns the same result. 1290 * 1291 * In other words, call this function if you don't want to provide a resource title, but subclasses 1292 * should re-implement the _other_ function to make sure full functionality is achieved (in particular 1293 * also engines not implementing sub-resource properties, which will then simply ignore the title 1294 * argument). This is because internally the other function is ultimately called in all cases. 1295 * 1296 * Again, the default implementation of this function sould be largely sufficient in most cases 1297 * and thus in principle needs not be reimplemented. 1298 */ 1299 virtual bool createSubResource(const QString& subResource); 1300 1301 /** Rename the sub-resource \c oldSubResourceName to \c newSubResourceName. 1302 * 1303 * \note we are talking about the resource <i>name</i> (eg. the table name in the database), 1304 * not the <i>title</i> (stored as a sub-resource property, for engines supporting 1305 * \ref FeatureSubResourceProps). 1306 * 1307 * Returns TRUE for success and FALSE for failure. 1308 * 1309 * Subclasses may reimplement this function to provide functionality. The default implementation 1310 * does nothing and returns FALSE. 1311 * 1312 * Subclasses should not forget to emit \ref subResourceRenamed() after a successful sub-resource 1313 * rename. 1314 * 1315 * \note Subclasses should also adjust the current defaultSubResource() if that is the one that 1316 * was precisely renamed. Use a call to \ref setDefaultSubResource(). 1317 */ 1318 virtual bool renameSubResource(const QString& oldSubResourceName, const QString& newSubResourceName); 1319 1320 /** Delete the given sub-resource 1321 * 1322 * Returns TRUE for success and FALSE for failure. 1323 * 1324 * Subclasses may reimplement this function to provide functionality. The default implementation 1325 * does nothing and returns FALSE. 1326 * 1327 * Subclasses should not forget to emit \ref subResourceDeleted() after the sub-resource 1328 * has been deleted (ie. upon a successful execution). 1329 * 1330 * \note Subclasses should also change the current defaultSubResource() if that is the one that 1331 * was precisely deleted. Use a call to \ref setDefaultSubResource(). 1332 */ 1333 virtual bool deleteSubResource(const QString& subResource); 1334 1335 1336 /** Sets the given sub-resource property of sub-resource \c subResource to the value \c value, 1337 * if the operation is possible and legal. 1338 * 1339 * \returns TRUE for success, FALSE for failure. 1340 * 1341 * The default implementation does nothing and returns FALSE. 1342 */ 1343 virtual bool setSubResourceProperty(const QString& subResource, int propId, const QVariant& value); 1344 1345 1346 //! Insert an entry into this resource 1347 /** This function is provided for convenience. Inserts the entry \c entry into the 1348 * subresource \c subResource of this resource. Resources not implementing the sub-resources 1349 * feature (\ref FeatureSubResources) should ignore the subResource parameter. 1350 * 1351 * API users should use the version of \ref insertEntry(const KLFLibEntry& entry) when dealing 1352 * with resources that do not implement the \ref FeatureSubResources feature. 1353 * 1354 * This function is already implemented as shortcut for calling the list version. Subclasses 1355 * need in principle NOT reimplement this function. */ 1356 virtual entryId insertEntry(const QString& subResource, const KLFLibEntry& entry); 1357 1358 //! Insert an entry into this resource 1359 /** This function is provided for convenience. Inserts the entry \c entry into this resource. 1360 * 1361 * Use this function for resources not supporting sub-resources (but subclasses still need 1362 * to reimplement the other function, ignoring the sub-resources argument), or use this 1363 * function when you explicitely want to use the default sub-resource. 1364 * 1365 * A reasonable default implementation is provided. Subclasses are not required to reimplement 1366 * this function. 1367 */ 1368 virtual entryId insertEntry(const KLFLibEntry& entry); 1369 1370 //! Insert new entries in this resource 1371 /** Inserts the given library entries (given as a \ref KLFLibEntry list) into this resource 1372 * and returns a list of the IDs that were attributed to the new entries (in the same 1373 * order as the given list). An individual ID of -1 means failure for that specific entry; 1374 * an empty list returned means a general failure, except if \c entrylist is empty. 1375 * 1376 * The entries are inserted into sub-resource \c subResource, if sub-resources are supported 1377 * (\ref FeatureSubResources). Otherwise the \c subResource parameter should be ignored 1378 * by subclasses. 1379 * 1380 * This function should be reimplemented by subclasses to actually save the new entries. 1381 * The reimplementation should make sure that the operation is permitted (eg. by checking 1382 * that \ref canModifyData() "canModifyData(InsertData)" is true, and should behave as 1383 * described above. 1384 * 1385 * Subclasses should then emit the \ref dataChanged() signal, and return a success/failure 1386 * code. 1387 */ 1388 virtual QList<entryId> insertEntries(const QString& subResource, const KLFLibEntryList& entrylist) = 0; 1389 1390 //! Insert new entries in this resource 1391 /** This function is provided for convenience. Inserts the entries \c entrylist into this resource. 1392 * 1393 * Use this function for resources not supporting sub-resources (but subclasses still need 1394 * to reimplement the other function, ignoring the sub-resources argument), or use this 1395 * function when you explicitely want to use the default sub-resource. 1396 * 1397 * A reasonable default implementation is provided. Subclasses are not required to reimplement 1398 * this function. 1399 */ 1400 virtual QList<entryId> insertEntries(const KLFLibEntryList& entrylist); 1401 1402 //! Change some entries in this resource. 1403 /** The entries specified by the ids \c idlist are modified. The properties given 1404 * in \c properties (which should be KLFLibEntry property IDs) are to be set to the respective 1405 * value in \c values for all the given entries in \c idlist. \c properties and \c values must 1406 * obviously be of same size. 1407 * 1408 * This function affects entries in sub-resource \c subResource for engines supporting feature 1409 * \ref FeatureSubResources. 1410 * 1411 * A return value of TRUE indicates general success and FALSE indicates a failure. 1412 * 1413 * This function should be reimplemented by subclasses to actually save the modified entries. 1414 * The reimplementation should make sure that the operation is permitted (eg. by checking 1415 * that \ref canModifyData() "canModifyData(ChangeData)" is true, and should behave as described 1416 * above. 1417 * 1418 * Subclasses should then emit the \ref dataChanged() signal, and return a success/failure 1419 * code. 1420 */ 1421 virtual bool changeEntries(const QString& subResource, const QList<entryId>& idlist, 1422 const QList<int>& properties, const QList<QVariant>& values) = 0; 1423 1424 //! Change some entries in this resource 1425 /** This function is provided for convenience. The default implementation, which should largely 1426 * suffice in most cases, calls the other changeEntries() function, with the default sub-resource 1427 * \c defaultSubResource() as first argument. 1428 * 1429 * Use this function for resources not supporting sub-resources (but subclasses still need 1430 * to reimplement the other function, ignoring the sub-resources argument), or use this 1431 * function when you explicitely want to use the default sub-resource. 1432 */ 1433 virtual bool changeEntries(const QList<entryId>& idlist, const QList<int>& properties, 1434 const QList<QVariant>& values); 1435 1436 //! Delete some entries in this resource. 1437 /** The entries specified by the ids \c idlist are deleted. 1438 * 1439 * A return value of TRUE indicates general success and FALSE indicates a failure. 1440 * 1441 * This function affects entries in sub-resource \c subResource for engines supporting feature 1442 * \ref FeatureSubResources. 1443 * 1444 * This function should be reimplemented by subclasses to actually delete the entries. 1445 * The reimplementation should make sure that the operation is permitted (eg. by checking 1446 * that \ref canModifyData() "canModifyData(DeleteData)" is true, and should behave as described 1447 * above. 1448 * 1449 * Subclasses should then emit the \ref dataChanged() signal, and return a success/failure 1450 * code. 1451 */ 1452 virtual bool deleteEntries(const QString& subResource, const QList<entryId>& idlist) = 0; 1453 1454 //! Delete some entries in this resource 1455 /** This function is provided for convenience. The default implementation, which should largely 1456 * suffice in most cases, calls the other deleteEntries() function, with the default sub-resource 1457 * \c defaultSubResource() as first argument. 1458 * 1459 * Use this function for resources not supporting sub-resources (but subclasses still need 1460 * to reimplement the other function, ignoring the sub-resources argument), or use this 1461 * function when you explicitely want to use the default sub-resource. 1462 */ 1463 virtual bool deleteEntries(const QList<entryId>& idList); 1464 1465 /** If the \ref FeatureSaveTo is supported (passed to the constructor), reimplement this 1466 * function to save the resource data in the new path specified by \c newPath. 1467 * 1468 * The \c newPath must be garanteed to have same schema as the previous url. 1469 * 1470 * \bug ........ THIS FUNCTION IS NOT COMPLETELY SUPPORTED IN KLFLibBrowser. ....... It also 1471 * needs a "concept clarification", ie. what this is supposed to do exactly and how it is 1472 * supposed to be used. 1473 */ 1474 virtual bool saveTo(const QUrl& newPath); 1475 1476 //! Set a resource property to the given value 1477 /** This function calls in turn: 1478 * - \ref canModifyProp() to check whether the property can be modified 1479 * - \ref saveResourceProperty() to check whether the operation is permitted (the value 1480 * is acceptable, or any other check the subclass would want to perform) and to save 1481 * the given value to the backend data; 1482 * - \ref KLFPropertizedObject::setProperty() to save the property locally; 1483 * - emits \ref resourcePropertyChanged() to notify other classes of the property change. 1484 * 1485 * \note This function fails immediately if \c propId is not a valid registered 1486 * property ID, or if canModifyProp() returns FALSE. 1487 * */ 1488 virtual bool setResourceProperty(int propId, const QVariant& value); 1489 1490 //! Set the given property to the given value 1491 /** Very similar to calling \ref setResourceProperty() with the respective property 1492 * ID (see \ref KLFPropertizedObject::propertyIdForName()), except the property is 1493 * registered if it does't exist. 1494 * 1495 * The property is registered if it doesn't exist yet and the \ref canRegisterProperty() 1496 * returns TRUE. 1497 * 1498 * Once the property has been possibly registered, setResourceProperty() is called. 1499 */ 1500 virtual bool loadResourceProperty(const QString& propName, const QVariant& value); 1501 1502 1503 protected: 1504 1505 //! Save a resource property to the backend resource data. 1506 /** Subclasses should reimplement this function to save the value of the given resource 1507 * property to the knew given value. 1508 * 1509 * If the new value is inacceptable, or if the operation is not permitted, the subclass 1510 * should return FALSE, in which case the resource property will not be changed. 1511 * 1512 */ 1513 virtual bool saveResourceProperty(int propId, const QVariant& value) = 0; 1514 1515 /** Whether it's possible to modify \a something (data, property value, etc.) 1516 */ 1517 enum ModifyStatus { 1518 MS_CanModify = 0, //!< It's possible to modify that \a something 1519 MS_IsLocked = 1, //!< That \a something is resource-locked (ie., the only possible action is to unlock it) 1520 MS_SubResLocked = 2, //!< That \a something is sub-resource-locked 1521 MS_NotModifiable = 3 //!< That \a something is read-only or not modifiable for another reason 1522 }; 1523 1524 //! can modify data in resource (base common tests only) 1525 /** External classes: Don't call this function directly, use \ref canModifyData(), \ref canModifyProp(), 1526 * and \ref canModifySubResourceProperty() instead. 1527 * 1528 * Internal classes: this is useful for reimplementations of canModifyData(), canModifyProp(), etc. 1529 * 1530 * The latter and their reimplementations may call this function. 1531 * 1532 * This function can be reimplemented to take into account more factors (eg. a file being writable). 1533 * 1534 * \returns one value of the \ref ModifyStatus enum. See that documentation for more info. 1535 * 1536 * All supporting-feature checks are made correspondingly as needed. If nothing is supported 1537 * (read-only, locked, sub-resource properties) by default data is modifiable. 1538 */ 1539 virtual ModifyStatus baseCanModifyStatus(bool inSubResource, 1540 const QString& subResource = QString()) const; 1541 1542 bool thisOperationProgressBlocked() const; 1543 1544 private: 1545 void initRegisteredProperties(); 1546 1547 QUrl pUrl; 1548 uint pFeatureFlags; 1549 bool pReadOnly; 1550 1551 QString pDefaultSubResource; 1552 1553 mutable bool pProgressBlocked; 1554 bool pThisOperationProgressBlockedOnly; 1555 1556 KLF_DEBUG_DECLARE_REF_INSTANCE( QFileInfo(url().path()).fileName()+":"+defaultSubResource() ) ; 1557 }; 1558 1559 1560 Q_DECLARE_METATYPE(KLFLibResourceEngine::KLFLibEntryWithId) 1561 ; 1562 1563 1564 KLF_EXPORT QDataStream& operator<<(QDataStream& stream, 1565 const KLFLibResourceEngine::KLFLibEntryWithId& entrywid); 1566 KLF_EXPORT QDataStream& operator>>(QDataStream& stream, 1567 KLFLibResourceEngine::KLFLibEntryWithId& entrywid); 1568 1569 1570 /** \brief Provides a simple API for reading library resources. 1571 * 1572 * This class provides default implementations of some pure virtual methods of 1573 * \ref KLFLibResourceEngine, which call other member functions. The goal is to make life 1574 * simpler to create a resource engine, where access speed is not a major concern. 1575 * 1576 * For example, KLFLibResourceEngine::allIds() is pure virtual. Normally it can be implemented 1577 * to be faster than allEntries(), depending on the engine backend. However the functionality 1578 * can as well easily be achieved by calling KLFLibResourceEngine::allEntries() and returning 1579 * just a list with all the IDs, at the price of losing optimization. 1580 * 1581 * This class provides non-optimized default implementations for allIds() (as given above), 1582 * hasEntry(), entries(), and query(), based on the data returned by allEntries() and 1583 * entry() 1584 * 1585 * Bear in mind that optimizing one or more of those functions is still possible, by 1586 * reimplementing them (!) 1587 */ 1588 class KLF_EXPORT KLFLibResourceSimpleEngine : public KLFLibResourceEngine 1589 { 1590 Q_OBJECT 1591 public: 1592 KLFLibResourceSimpleEngine(const QUrl& url, uint supportedfeatureflags, QObject *parent = NULL) KLFLibResourceEngine(url,supportedfeatureflags,parent)1593 : KLFLibResourceEngine(url, supportedfeatureflags, parent) 1594 { 1595 } ~KLFLibResourceSimpleEngine()1596 virtual ~KLFLibResourceSimpleEngine() { } 1597 1598 // these functions are implemented using the other base functions. 1599 1600 virtual QList<KLFLib::entryId> allIds(const QString& subResource); 1601 virtual bool hasEntry(const QString&, entryId id); 1602 virtual QList<KLFLibEntryWithId> entries(const QString&, const QList<KLFLib::entryId>& idList, 1603 const QList<int>& wantedEntryProperties = QList<int>()); 1604 1605 /** \brief Helper class to sort entries into a \ref KLFLibResourceEngine::QueryResult. 1606 */ 1607 class QueryResultListSorter 1608 { 1609 KLFLibEntrySorter *mSorter; 1610 QueryResult *mResult; 1611 uint fillflags; 1612 bool reference_is_rawentrylist; 1613 public: 1614 /** Build an QueryResultListSorter object, that should sort entries according to 1615 * \c sorter. See also \ref KLFLibEntrySorter. 1616 * 1617 * \c sorter must not be NULL. 1618 */ 1619 QueryResultListSorter(KLFLibEntrySorter *sorter, QueryResult *result); 1620 1621 /* QueryResultListSorter(const QueryResultListSorter& other); */ 1622 1623 /** \brief Compares \ref KLFLibEntry'ies */ operator()1624 inline bool operator()(const KLFLibEntry& a, const KLFLibEntry& b) 1625 { return mSorter->operator()(a, b); } 1626 1627 /** \brief Compares \ref KLFLibResourceEngine::KLFLibEntryWithId's */ operator()1628 inline bool operator()(const KLFLibEntryWithId& a, const KLFLibEntryWithId& b) 1629 { return mSorter->operator()(a.entry, b.entry); } 1630 1631 /** Returns the number of entries there are in the lists (ignoring those lists left empty, of 1632 * course). */ 1633 int numberOfEntries(); 1634 1635 /** Inserts the entry-with-id \c entrywid, into the appropriate lists in the \c result that 1636 * was given to the constructor, such that the lists are ordered according to the sorter set 1637 * in the constructor. 1638 * 1639 * By \a appropriate we mean the lists for which the fill flags are set in the QueryResult object. 1640 * 1641 * If the set sorter's sorting property ID is \c -1, then the elements are simply 1642 * appended to the appropriate lists; sorting is disabled in this case. 1643 * 1644 * When sorting is enabled, this function assumes that the lists in \c result are sorted 1645 * appropriately. This is naturally the case if you only use this function to build the lists. 1646 * In other terms, don't call this function if you already added non-sorted items into the 1647 * list(s). 1648 * 1649 * \note if the fill flags include neither the raw entry list, nor the entry-with-id list, 1650 * then the raw entry list is also filled, as it is not possible to just compare bare entry 1651 * IDs (!) 1652 */ 1653 void insertIntoOrderedResult(const KLFLibEntryWithId& entry); 1654 }; 1655 1656 virtual int query(const QString& subResource, const Query& query, QueryResult *result); 1657 1658 virtual QList<QVariant> queryValues(const QString& subResource, int entryPropId); 1659 1660 1661 /** A basic implementation of query() based on matching the results of 1662 * <tt>resource->allEntries()</tt>. */ 1663 static int queryImpl(KLFLibResourceEngine *resource, const QString& subResource, 1664 const Query& query, QueryResult *result); 1665 1666 /** A basic implementation of queryValues() based on looking at the results of 1667 * <tt>resource->allEntries()</tt> */ 1668 static QList<QVariant> queryValuesImpl(KLFLibResourceEngine *resource, const QString& subResource, 1669 int entryPropId); 1670 1671 1672 /** A simple entry condition tester. */ 1673 static bool testEntryMatchConditionImpl(const KLFLib::EntryMatchCondition& condition, 1674 const KLFLibEntry& libentry); 1675 }; 1676 1677 1678 1679 /** An abstract factory class for opening resources identified by their URL, and creating 1680 * objects of the currect subclass of KLFLibResourceEngine. 1681 * 1682 * See also \ref KLFLibResourceEngine, \ref KLFLibDBEngine, \ref KLFLibLegacyEngine. 1683 * More about factory common functions in \ref KLFFactoryManager documentation. 1684 */ 1685 class KLF_EXPORT KLFLibEngineFactory : public QObject, public KLFFactoryBase 1686 { 1687 Q_OBJECT 1688 public: 1689 /** A generalized way of passing arbitrary parameters for creating 1690 * new resources or saving resources to new locations. 1691 * 1692 */ 1693 typedef QMap<QString,QVariant> Parameters; 1694 1695 enum SchemeFunctions { 1696 FuncOpen = 0x01, //!< Open Resources 1697 FuncCreate = 0x02, //!< Create New Resources 1698 FuncSaveTo = 0x04 //!< Save Resources to new locations 1699 }; 1700 1701 /** Constructs an engine factory and automatically regisers it. */ 1702 KLFLibEngineFactory(QObject *parent = NULL); 1703 /** Destroys this engine factory and unregisters it. */ 1704 virtual ~KLFLibEngineFactory(); 1705 1706 /** \brief A list of supported URL schemes this factory can open. 1707 * 1708 * If two factories provide a common scheme name, only the last instantiated is used; 1709 * the consequent ones will be ignored for that scheme name. See 1710 * \ref KLFFactoryBase::supportedTypes() and \ref KLFFactoryManager::findFactoryFor() */ 1711 virtual QStringList supportedTypes() const = 0; 1712 1713 /** \brief What this factory is capable of doing 1714 * 1715 * Informs the caller of what functionality this factory provides for the given \c scheme. 1716 * 1717 * The \c FuncOpen must be provided in every factory. 1718 * 1719 * \returns a bitwise-OR of flags defined in the \ref SchemeFunctions enum. 1720 * 1721 * The default implementation returns \c FuncOpen. */ 1722 virtual uint schemeFunctions(const QString& scheme) const; 1723 1724 /** Should return a human (short) description of the given scheme (which is one 1725 * returned by \ref supportedTypes()) */ 1726 virtual QString schemeTitle(const QString& scheme) const = 0; 1727 1728 /** Returns the widget type that should be used to present to user to "open" or "create" or 1729 * "save" a resource of the given \c scheme. 1730 * 1731 * For example, both \c "klf+sqlite" and \c "klf+legacy" schemes could return a "LocalFile" 1732 * widget that prompts to open/create/save-as a file. */ 1733 virtual QString correspondingWidgetType(const QString& scheme) const = 0; 1734 1735 /** Instantiate a library engine that opens resource stored at \c location. The resource 1736 * engine should be constructed as a child of object \c parent. 1737 */ 1738 virtual KLFLibResourceEngine *openResource(const QUrl& location, QObject *parent = NULL) = 0; 1739 1740 //! Create a new resource of given type and parameters 1741 /** Create the new resource, with the given settings. This function opens the resource and 1742 * returns the KLFLibResourceEngine object, which is instantiated as child of \c parent. 1743 * 1744 * The parameters' structure are defined for each widget type. That is, if the 1745 * \ref correspondingWidgetType() for a given scheme is eg. \c "LocalFile", then the 1746 * parameters are defined by whatever the \c "LocalFile" widget sets. For example 1747 * \c "LocalFile" documents its parameters in 1748 * \ref KLFLibBasicWidgetFactory::retrieveCreateParametersFromWidget(), eg. parameter 1749 * \c "Filename" contains a QString with the entered local file name. 1750 * 1751 * Additional parameters may also be set by KLFLibCreateResourceDlg itself (eg. 1752 * default sub-resource name/title, .........TODO............) 1753 * 1754 * The default implementation of this function does nothing and returns \c NULL. To enable 1755 * creating resources, reimplement \ref schemeFunctions() to return also \ref FuncCreate 1756 * and reimplement this function. 1757 */ 1758 virtual KLFLibResourceEngine *createResource(const QString& scheme, const Parameters& parameters, 1759 QObject *parent = NULL); 1760 1761 //! Save the given resource to a new location 1762 /** Save the resource \c resource to the new location given by \c newLocation. 1763 * 1764 * The caller should garantee that \c resource is a resource engine of a scheme supported by 1765 * this factory. 1766 * 1767 * \note The resource a the new location is not opened. \c resource will still continue pointing 1768 * to the previous location. 1769 * 1770 * For example, an \c "klf+sqlite" Sqlite database may choose to simply copy the database file 1771 * to the new location. This example is implemented in \ref KLFLibDBEngine::saveTo(). 1772 * 1773 * \returns TRUE for success or FALSE for failure. 1774 * 1775 * The default implementation of this function does nothing and returns false. To enable 1776 * creating resources, reimplement \ref schemeFunctions() to return also \ref FuncCreate 1777 * and reimplement this function. 1778 */ 1779 virtual bool saveResourceTo(KLFLibResourceEngine *resource, const QUrl& newLocation); 1780 1781 1782 1783 1784 /** Finds the last registered factory that should be able to open URL \c url (determined by 1785 * the URL's scheme) and returns a pointer to that factory. 1786 * 1787 * This function is provided for convenience; it is equivalent to 1788 * \code findFactoryFor(url.scheme()) \endcode 1789 */ 1790 static KLFLibEngineFactory *findFactoryFor(const QUrl& url); 1791 1792 /** Finds the last registered factory that should be able to open URLs with scheme \c urlScheme 1793 * and returns a pointer to that factory. */ 1794 static KLFLibEngineFactory *findFactoryFor(const QString& urlScheme); 1795 1796 /** Returns a concatenated list of all schemes that all registered factories support */ 1797 static QStringList allSupportedSchemes(); 1798 1799 /** Finds the good factory for URL \c location, and opens the resource using that factory. 1800 * The created resource will be a child of \c parent. */ 1801 static KLFLibResourceEngine *openURL(const QUrl& location, QObject *parent = NULL); 1802 1803 /** Opens resource designated by \c url, and then lists the subresources. An empty list 1804 * is returned if the resource cannot be opened, or if the resource does not support 1805 * sub-resources. 1806 * 1807 * The resource is immedately closed after reading the list of sub-resources. 1808 * 1809 * This function: 1810 * - Finds the relevant factory with \ref findFactoryFor() 1811 * - Opens the resource with \ref openResource() using that factory 1812 * - fails if the resource does not support \ref KLFLibResourceEngine::FeatureSubResources 1813 * - lists the sub-resources 1814 * - closes the resource 1815 */ 1816 static QStringList listSubResources(const QUrl& url); 1817 1818 /** Opens resource designated by \c url, and then lists the subresources with as key 1819 * the resource name and as value the sub-resource title (if sub-resource properties 1820 * are supported, or an empty string if not). An empty map is returned if the resource 1821 * cannot be opened, or if the resource does not support sub-resources. 1822 * 1823 * This function works in a very similar way to \ref listSubResources(). 1824 * 1825 * The resource is immedately closed after reading the list of sub-resources. 1826 */ 1827 static QMap<QString,QString> listSubResourcesWithTitles(const QUrl& url); 1828 1829 private: 1830 static KLFFactoryManager pFactoryManager; 1831 }; 1832 1833 1834 1835 // ------------------------- 1836 1837 1838 class QMimeData; 1839 1840 //! Helper class to encode an entry list as mime data (abstract interface) 1841 class KLF_EXPORT KLFAbstractLibEntryMimeEncoder 1842 { 1843 public: 1844 KLFAbstractLibEntryMimeEncoder(); 1845 virtual ~KLFAbstractLibEntryMimeEncoder(); 1846 1847 //! A list of mime types this class can encode 1848 virtual QStringList supportedEncodingMimeTypes() const = 0; 1849 //! A list of mime types this class can decode 1850 virtual QStringList supportedDecodingMimeTypes() const = 0; 1851 1852 virtual QByteArray encodeMime(const KLFLibEntryList& entryList, const QVariantMap& metaData, 1853 const QString& mimeType) const = 0; 1854 1855 virtual bool decodeMime(const QByteArray& data, const QString& mimeType, 1856 KLFLibEntryList *entryList, QVariantMap *metaData) const = 0; 1857 1858 1859 static QStringList allEncodingMimeTypes(); 1860 static QStringList allDecodingMimeTypes(); 1861 //! Creates a QMetaData with all known registered encoding mime types 1862 static QMimeData *createMimeData(const KLFLibEntryList& entryList, const QVariantMap& metaData); 1863 static bool canDecodeMimeData(const QMimeData *mimeData); 1864 static bool decodeMimeData(const QMimeData *mimeData, KLFLibEntryList *entryList, 1865 QVariantMap *metaData); 1866 1867 static KLFAbstractLibEntryMimeEncoder *findEncoderFor(const QString& mimeType, 1868 bool warnIfNotFound = true); 1869 static KLFAbstractLibEntryMimeEncoder *findDecoderFor(const QString& mimeType, 1870 bool warnIfNotFound = true); 1871 static QList<KLFAbstractLibEntryMimeEncoder*> encoderList(); 1872 private: 1873 1874 static void registerEncoder(KLFAbstractLibEntryMimeEncoder *encoder); 1875 1876 static QList<KLFAbstractLibEntryMimeEncoder*> staticEncoderList; 1877 }; 1878 1879 1880 1881 1882 1883 #ifdef KLF_DEBUG 1884 #include <QDebug> 1885 KLF_EXPORT QDebug& operator<<(QDebug& dbg, const KLFLib::StringMatch& smatch); 1886 KLF_EXPORT QDebug& operator<<(QDebug& dbg, const KLFLib::PropertyMatch& pmatch); 1887 KLF_EXPORT QDebug& operator<<(QDebug& dbg, const KLFLib::EntryMatchCondition& c); 1888 KLF_EXPORT QDebug& operator<<(QDebug& dbg, const KLFLibResourceEngine::Query& q); 1889 KLF_EXPORT QDebug& operator<<(QDebug& dbg, const KLFLibResourceEngine::KLFLibEntryWithId& ewid); 1890 #endif 1891 1892 1893 1894 1895 #endif 1896 1897