1 /* This file is (c) 2008-2012 Konstantin Isakov <ikm@goldendict.org> 2 * Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */ 3 4 #ifndef __ARTICLE_MAKER_HH_INCLUDED__ 5 #define __ARTICLE_MAKER_HH_INCLUDED__ 6 7 #include <QObject> 8 #include <QMap> 9 #include <set> 10 #include <list> 11 #include "dictionary.hh" 12 #include "instances.hh" 13 #include "wordfinder.hh" 14 15 /// This class generates the article's body for the given lookup request 16 class ArticleMaker: public QObject 17 { 18 Q_OBJECT // We make it QObject to use tr() conveniently 19 20 std::vector< sptr< Dictionary::Class > > const & dictionaries; 21 std::vector< Instances::Group > const & groups; 22 23 QString displayStyle, addonStyle; 24 25 bool needExpandOptionalParts; 26 bool collapseBigArticles; 27 int articleLimitSize; 28 29 public: 30 31 /// On construction, a reference to all dictionaries and a reference all 32 /// groups' instances are to be passed. Those references are kept stored as 33 /// references, and as such, any changes to them would reflect on the results 34 /// of the inquiries, although those changes are perfectly legal. 35 ArticleMaker( std::vector< sptr< Dictionary::Class > > const & dictionaries, 36 std::vector< Instances::Group > const & groups, 37 QString const & displayStyle, 38 QString const & addonStyle); 39 40 /// Sets the display style to use for any new requests. This affects the 41 /// choice of the stylesheet file. 42 void setDisplayStyle( QString const &, QString const & addonStyle ); 43 44 /// Looks up the given word within the given group, and creates a full html 45 /// page text containing its definition. 46 /// The result is returned as Dictionary::DataRequest just like dictionaries 47 /// themselves do. The difference is that the result is a complete html page 48 /// with all definitions from all the relevant dictionaries. 49 /// Contexts is a map of context values to be passed to each dictionary, where 50 /// the keys are dictionary ids. 51 /// If mutedDicts is not empty, the search would be limited only to those 52 /// dictionaries in group which aren't listed there. 53 sptr< Dictionary::DataRequest > makeDefinitionFor( QString const & word, unsigned groupId, 54 QMap< QString, QString > const & contexts, 55 QSet< QString > const & mutedDicts = 56 QSet< QString >(), 57 QStringList const & dictIDs = QStringList(), 58 bool ignoreDiacritics = false ) const; 59 60 /// Makes up a text which states that no translation for the given word 61 /// was found. Sometimes it's better to call this directly when it's already 62 /// known that there's no translation. 63 sptr< Dictionary::DataRequest > makeNotFoundTextFor( QString const & word, QString const & group ) const; 64 65 /// Creates an 'untitled' page. The result is guaranteed to be instant. 66 sptr< Dictionary::DataRequest > makeEmptyPage() const; 67 68 /// Create page with one picture 69 sptr< Dictionary::DataRequest > makePicturePage( std::string const & url ) const; 70 71 /// Set auto expanding optional parts of articles 72 void setExpandOptionalParts( bool expand ); 73 74 /// Add base path to file path if it's relative and file not found 75 /// Return true if path successfully adjusted 76 static bool adjustFilePath( QString & fileName ); 77 78 /// Set collapse articles parameters 79 void setCollapseParameters( bool autoCollapse, int articleSize ); 80 81 private: 82 83 /// Makes everything up to and including the opening body tag. 84 std::string makeHtmlHeader( QString const & word, QString const & icon, 85 bool expandOptionalParts ) const; 86 87 /// Makes the html body for makeNotFoundTextFor() 88 static std::string makeNotFoundBody( QString const & word, QString const & group ); 89 90 friend class ArticleRequest; // Allow it calling makeNotFoundBody() 91 }; 92 93 /// The request specific to article maker. This should really be private, 94 /// but we need it to be handled by moc. 95 class ArticleRequest: public Dictionary::DataRequest 96 { 97 Q_OBJECT 98 99 QString word, group; 100 QMap< QString, QString > contexts; 101 std::vector< sptr< Dictionary::Class > > activeDicts; 102 103 std::set< gd::wstring > alts; // Accumulated main forms 104 std::list< sptr< Dictionary::WordSearchRequest > > altSearches; 105 bool altsDone, bodyDone; 106 std::list< sptr< Dictionary::DataRequest > > bodyRequests; 107 bool foundAnyDefinitions; 108 bool closePrevSpan; // Indicates whether the last opened article span is to 109 // be closed after the article ends. 110 sptr< WordFinder > stemmedWordFinder; // Used when there're no results 111 112 /// A sequence of words and spacings between them, including the initial 113 /// spacing before the first word and the final spacing after the last word. 114 typedef QList< QString > Words; 115 typedef QList< QString > Spacings; 116 117 /// Splits the given string into words and spacings between them. 118 QPair< Words, Spacings > splitIntoWords( QString const & ); 119 120 QPair< Words, Spacings > splittedWords; 121 int currentSplittedWordStart; 122 int currentSplittedWordEnd; 123 QString currentSplittedWordCompound; 124 QString lastGoodCompoundResult; 125 bool firstCompoundWasFound; 126 int articleSizeLimit; 127 bool needExpandOptionalParts; 128 bool ignoreDiacritics; 129 130 public: 131 132 ArticleRequest( QString const & word, QString const & group, 133 QMap< QString, QString > const & contexts, 134 std::vector< sptr< Dictionary::Class > > const & activeDicts, 135 std::string const & header, 136 int sizeLimit, bool needExpandOptionalParts_, 137 bool ignoreDiacritics = false ); 138 139 virtual void cancel(); 140 // { finish(); } // Add our own requests cancellation here 141 142 private slots: 143 144 void altSearchFinished(); 145 void bodyFinished(); 146 void stemmedSearchFinished(); 147 void individualWordFinished(); 148 149 private: 150 151 /// Appends the given string to 'data', with locking its mutex. 152 void appendToData( std::string const & ); 153 154 /// Uses stemmedWordFinder to perform the next step of looking up word 155 /// combinations. 156 void compoundSearchNextStep( bool lastSearchSucceeded ); 157 158 /// Creates a single word out of the [currentSplittedWordStart..End] range. 159 QString makeSplittedWordCompound(); 160 161 /// Makes an html link to the given word. 162 std::string linkWord( QString const & ); 163 164 /// Escapes the spacing between the words to include in html. 165 std::string escapeSpacing( QString const & ); 166 167 /// Find end of corresponding </div> tag 168 int findEndOfCloseDiv( QString const &, int pos ); 169 }; 170 171 172 #endif 173