Warning, file /office/calligra/libs/odf/KoOdfNumberDefinition.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* This file is part of the KDE project 0002 0003 Copyright (C) 2010 Boudewijn Rempt 0004 Copyright (C) 2011 Mojtaba Shahi Senobari <mojtaba.shahi3000@gmail.com> 0005 0006 This library is free software; you can redistribute it and/or 0007 modify it under the terms of the GNU Library General Public 0008 License version 2 as published by the Free Software Foundation. 0009 0010 This library is distributed in the hope that it will be useful, 0011 but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0013 Library General Public License for more details. 0014 0015 You should have received a copy of the GNU Library General Public License 0016 along with this library; see the file COPYING.LIB. If not, write to 0017 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0018 Boston, MA 02110-1301, USA. 0019 */ 0020 #include "KoOdfNumberDefinition.h" 0021 0022 #include "KoXmlNS.h" 0023 #include "KoXmlWriter.h" 0024 0025 class Q_DECL_HIDDEN KoOdfNumberDefinition::Private 0026 { 0027 public: 0028 QString prefix; 0029 QString suffix; 0030 KoOdfNumberDefinition::FormatSpecification formatSpecification; 0031 bool letterSynchronization; 0032 }; 0033 0034 KoOdfNumberDefinition::KoOdfNumberDefinition() 0035 : d(new Private()) 0036 { 0037 d->formatSpecification = Numeric; 0038 d->letterSynchronization = false; 0039 } 0040 0041 KoOdfNumberDefinition::KoOdfNumberDefinition(const KoOdfNumberDefinition &other) 0042 : d(new Private()) 0043 { 0044 d->prefix = other.d->prefix; 0045 d->suffix = other.d->suffix; 0046 d->formatSpecification = other.d->formatSpecification; 0047 d->letterSynchronization = other.d->letterSynchronization; 0048 } 0049 0050 KoOdfNumberDefinition &KoOdfNumberDefinition::operator=(const KoOdfNumberDefinition &other) 0051 { 0052 d->prefix = other.d->prefix; 0053 d->suffix = other.d->suffix; 0054 d->formatSpecification = other.d->formatSpecification; 0055 d->letterSynchronization = other.d->letterSynchronization; 0056 0057 return *this; 0058 } 0059 0060 KoOdfNumberDefinition::~KoOdfNumberDefinition() 0061 { 0062 delete d; 0063 } 0064 0065 QStringList KoOdfNumberDefinition::userFormatDescriptions() 0066 { 0067 QStringList list; 0068 list << "1, 2, 3, ..." 0069 << "a, b, c, ..." 0070 << "A, B, C, ..." 0071 << "i, ii, iii, ..." 0072 << "I, II, III, ..." << "أ, ب, ت, ..." 0073 << "ก, ข, ค, ..." 0074 << "౧, ౨, ౩, ..." 0075 << "௧, ௨, ௪, ..." 0076 << "୧, ୨, ୩, ..." 0077 << "൧, ൨, ൩, ..." 0078 << "೧, ೨, ೩, ..." 0079 << "੧, ੨, ੩, ..." 0080 << "૧, ૨, ૩, ..." 0081 << "১, ২, ৩, ..."; 0082 0083 return list; 0084 } 0085 0086 void KoOdfNumberDefinition::loadOdf(const KoXmlElement &element) 0087 { 0088 const QString format = element.attributeNS(KoXmlNS::style, "num-format", QString()); 0089 if (format.isEmpty()) { 0090 //do nothing fall back to what we had. 0091 } 0092 else if (format[0] == '1') { 0093 d->formatSpecification = Numeric; 0094 } 0095 else if (format[0] == 'a') { 0096 d->formatSpecification = AlphabeticLowerCase; 0097 } 0098 else if (format[0] == 'A') { 0099 d->formatSpecification = AlphabeticUpperCase; 0100 } 0101 else if (format[0] == 'i') { 0102 d->formatSpecification = RomanLowerCase; 0103 } 0104 else if (format[0] == 'I') { 0105 d->formatSpecification = RomanUpperCase; 0106 } 0107 else if (format == QString::fromUtf8("أ, ب, ت, ...")){ 0108 d->formatSpecification = ArabicAlphabet; 0109 } 0110 else if (format == QString::fromUtf8("ก, ข, ค, ...")){ 0111 d->formatSpecification = Thai; 0112 } 0113 else if (format == QString::fromUtf8("أ, ب, ج, ...")) { 0114 d->formatSpecification = Abjad; 0115 } 0116 else if (format == QString::fromUtf8("ﺃ,ﺏ, ﺝ, ... ")) { 0117 d->formatSpecification = AbjadMinor; 0118 } 0119 else if (format == QString::fromUtf8("౧, ౨, ౩, ...")) { 0120 d->formatSpecification = Telugu; 0121 } 0122 else if (format == QString::fromUtf8("௧, ௨, ௪, ...")) { 0123 d->formatSpecification = Tamil; 0124 } 0125 else if (format == QString::fromUtf8("୧, ୨, ୩, ...")) { 0126 d->formatSpecification = Oriya; 0127 } 0128 else if (format == QString::fromUtf8("൧, ൨, ൩, ...")) { 0129 d->formatSpecification = Malayalam; 0130 } 0131 else if (format == QString::fromUtf8("೧, ೨, ೩, ...")) { 0132 d->formatSpecification = Kannada; 0133 } 0134 else if (format == QString::fromUtf8("੧, ੨, ੩, ...")) { 0135 d->formatSpecification = Gurumukhi; 0136 } 0137 else if (format == QString::fromUtf8("૧, ૨, ૩, ...")) { 0138 d->formatSpecification = Gujarati; 0139 } 0140 else if (format == QString::fromUtf8("১, ২, ৩, ...")) { 0141 d->formatSpecification = Bengali; 0142 } 0143 else { 0144 d->formatSpecification = Numeric; 0145 } 0146 0147 //The style:num-prefix and style:num-suffix attributes specify what to display before and after the number. 0148 d->prefix = element.attributeNS(KoXmlNS::style, "num-prefix", d->prefix); 0149 d->suffix = element.attributeNS(KoXmlNS::style, "num-suffix", d->suffix); 0150 0151 d->letterSynchronization = (element.attributeNS(KoXmlNS::style, "num-letter-sync", d->letterSynchronization ? "true" : "false") == "true"); 0152 } 0153 0154 void KoOdfNumberDefinition::saveOdf(KoXmlWriter *writer) const 0155 { 0156 if (!d->prefix.isNull()) { 0157 writer->addAttribute("style:num-prefix", d->prefix); 0158 } 0159 0160 if (!d->suffix.isNull()) { 0161 writer->addAttribute("style:num-suffix", d->suffix); 0162 } 0163 QByteArray format; 0164 switch(d->formatSpecification) { 0165 case Numeric: 0166 format = "1"; 0167 break; 0168 case AlphabeticLowerCase: 0169 format = "a"; 0170 break; 0171 case AlphabeticUpperCase: 0172 format = "A"; 0173 break; 0174 case RomanLowerCase: 0175 format = "i"; 0176 break; 0177 case RomanUpperCase: 0178 format = "I"; 0179 break; 0180 case ArabicAlphabet: 0181 format = "أ, ب, ت, ..."; 0182 break; 0183 case Thai: 0184 format = "ก, ข, ค, ..."; 0185 break; 0186 case Telugu: 0187 format = "౧, ౨, ౩, ..."; 0188 break; 0189 case Tamil: 0190 format = "௧, ௨, ௪, ..."; 0191 break; 0192 case Oriya: 0193 format = "୧, ୨, ୩, ..."; 0194 break; 0195 case Malayalam: 0196 format = "൧, ൨, ൩, ..."; 0197 break; 0198 case Kannada: 0199 format = "೧, ೨, ೩, ..."; 0200 break; 0201 case Gurumukhi: 0202 format = "੧, ੨, ੩, ..."; 0203 break; 0204 case Gujarati: 0205 format = "૧, ૨, ૩, ..."; 0206 break; 0207 case Bengali: 0208 format = "১, ২, ৩, ..."; 0209 break; 0210 case Empty: 0211 default: 0212 ; 0213 }; 0214 if (!format.isNull()) { 0215 writer->addAttribute("style:num-format", format); 0216 } 0217 0218 if (d->letterSynchronization) { 0219 writer->addAttribute("style:num-letter-sync", "true"); 0220 } 0221 } 0222 0223 static QString intToRoman(int n) 0224 { 0225 static const QString RNUnits[] = {"", "i", "ii", "iii", "iv", "v", "vi", "vii", "viii", "ix"}; 0226 static const QString RNTens[] = {"", "x", "xx", "xxx", "xl", "l", "lx", "lxx", "lxxx", "xc"}; 0227 static const QString RNHundreds[] = {"", "c", "cc", "ccc", "cd", "d", "dc", "dcc", "dccc", "cm"}; 0228 static const QString RNThousands[] = {"", "m", "mm", "mmm", "mmmm", "mmmmm", "mmmmmm", "mmmmmmm", "mmmmmmmm", "mmmmmmmmm"}; 0229 0230 if (n <= 0) { 0231 return QString::number(n); 0232 } 0233 0234 return RNThousands[(n / 1000)] + 0235 RNHundreds[(n / 100) % 10 ] + 0236 RNTens[(n / 10) % 10 ] + 0237 RNUnits[(n) % 10 ]; 0238 } 0239 0240 static QString intToAlpha(int n, bool letterSynchronization) 0241 { 0242 QString answer; 0243 if (letterSynchronization) { 0244 int digits = 1; 0245 for (; n > 26; n -= 26) 0246 digits += 1; 0247 for (int i = 0; i < digits; i++) 0248 answer.prepend(QChar('a' + n - 1)); 0249 return answer; 0250 } else { 0251 char bottomDigit; 0252 while (n > 26) { 0253 bottomDigit = (n - 1) % 26; 0254 n = (n - 1) / 26; 0255 answer.prepend(QChar('a' + bottomDigit)); 0256 } 0257 } 0258 answer.prepend(QChar('a' + n - 1)); 0259 return answer; 0260 } 0261 0262 static QString intToScript(int n, int offset) 0263 { 0264 // 10-base 0265 QString answer; 0266 while (n > 0) { 0267 answer.prepend(QChar(offset + n % 10)); 0268 n = n / 10; 0269 } 0270 return answer; 0271 } 0272 0273 static QString intToScriptList(int n, KoOdfNumberDefinition::FormatSpecification formatSpecification) 0274 { 0275 // 1 time Sequences 0276 // note; the leading X is to make these 1 based. 0277 static const char* const Abjad[] = { "أ", "ب", "ج", "د", "ﻫ", "و", "ز", "ح", "ط", "ي", "ك", "ل", "م", 0278 "ن", "س", "ع", "ف", "ص", "ق", "ر", "ش", "ت", "ث", "خ", "ذ", "ض", "ظ", "غ" 0279 }; 0280 static const char* const Abjad2[] = { "ﺃ", "ﺏ", "ﺝ", "ﺩ", "ﻫ", "ﻭ", "ﺯ", "ﺡ", "ﻁ", "ﻱ", "ﻙ", "ﻝ", "ﻡ", 0281 "ﻥ", "ﺹ", "ﻉ", "ﻑ", "ﺽ", "ﻕ", "ﺭ", "ﺱ", "ﺕ", "ﺙ", "ﺥ", "ﺫ", "ﻅ", "ﻍ", "ﺵ" 0282 }; 0283 static const char* const ArabicAlphabet[] = {"ا", "ب", "ت", "ث", "ج", "ح", "خ", "د", "ذ", "ر", "ز", 0284 "س", "ش", "ص", "ض", "ط", "ظ", "ع", "غ", "ف", "ق", "ك", "ل", "م", "ن", "ه", "و", "ي" 0285 }; 0286 0287 /* 0288 // see this page for the 10, 100, 1000 etc http://en.wikipedia.org/wiki/Chinese_numerals 0289 static const char* const chinese1[] = { '零','壹','貳','叄','肆','伍','陸','柒','捌','玖' }; 0290 static const char* const chinese2[] = { '〇','一','二','三','四','五','六','七','八','九' }; 0291 0292 TODO: http://en.wikipedia.org/wiki/Korean_numerals 0293 http://en.wikipedia.org/wiki/Japanese_numerals 0294 'http://en.wikipedia.org/wiki/Hebrew_numerals' 0295 'http://en.wikipedia.org/wiki/Armenian_numerals' 0296 'http://en.wikipedia.org/wiki/Greek_numerals' 0297 'http://en.wikipedia.org/wiki/Cyrillic_numerals' 0298 'http://en.wikipedia.org/wiki/Sanskrit_numerals' 0299 'http://en.wikipedia.org/wiki/Ge%27ez_alphabet#Numerals' 0300 'http://en.wikipedia.org/wiki/Abjad_numerals' 0301 */ 0302 0303 switch (formatSpecification) { 0304 case KoOdfNumberDefinition::Abjad: 0305 if (n > 22) return "*"; 0306 return QString::fromUtf8(Abjad[n-1]); 0307 case KoOdfNumberDefinition::AbjadMinor: 0308 if (n > 22) return "*"; 0309 return QString::fromUtf8(Abjad2[n-1]); 0310 case KoOdfNumberDefinition::ArabicAlphabet: 0311 if (n > 28) return "*"; 0312 return QString::fromUtf8(ArabicAlphabet[n-1]); 0313 default: 0314 return QString::number(n); 0315 } 0316 } 0317 0318 QString KoOdfNumberDefinition::formattedNumber(int number, KoOdfNumberDefinition *defaultDefinition) const 0319 { 0320 switch(d->formatSpecification) { 0321 case Numeric: 0322 return QString::number(number); 0323 break; 0324 0325 case AlphabeticLowerCase: 0326 return intToAlpha(number, d->letterSynchronization); 0327 case AlphabeticUpperCase: 0328 return intToAlpha(number, d->letterSynchronization).toUpper(); 0329 0330 case RomanLowerCase: 0331 return intToRoman(number); 0332 case RomanUpperCase: 0333 return intToRoman(number).toUpper(); 0334 0335 case Thai: 0336 return intToScript(number, 0xe50); 0337 case Tibetan: 0338 return intToScript(number, 0xf20); 0339 case Telugu: 0340 return intToScript(number, 0xc66); 0341 case Tamil: 0342 return intToScript(number, 0x0be6); 0343 case Oriya: 0344 return intToScript(number, 0xb66); 0345 case Malayalam: 0346 return intToScript(number, 0xd66); 0347 case Kannada: 0348 return intToScript(number, 0xce6); 0349 case Gurumukhi: 0350 return intToScript(number, 0xa66); 0351 case Gujarati: 0352 return intToScript(number, 0xae6); 0353 case Bengali: 0354 return intToScript(number, 0x9e6); 0355 0356 case Abjad: 0357 case AbjadMinor: 0358 case ArabicAlphabet: 0359 return intToScriptList(number, d->formatSpecification); 0360 0361 case Empty: 0362 if (defaultDefinition) { 0363 return defaultDefinition->formattedNumber(number); 0364 } 0365 0366 break; 0367 default: 0368 ; 0369 }; 0370 0371 return ""; 0372 } 0373 0374 0375 QString KoOdfNumberDefinition::prefix() const 0376 { 0377 return d->prefix; 0378 } 0379 0380 void KoOdfNumberDefinition::setPrefix(const QString &prefix) 0381 { 0382 d->prefix = prefix; 0383 } 0384 0385 QString KoOdfNumberDefinition::suffix() const 0386 { 0387 return d->suffix; 0388 } 0389 0390 void KoOdfNumberDefinition::setSuffix(const QString &suffix) 0391 { 0392 d->suffix = suffix; 0393 } 0394 0395 KoOdfNumberDefinition::FormatSpecification KoOdfNumberDefinition::formatSpecification() const 0396 { 0397 return d->formatSpecification; 0398 } 0399 0400 void KoOdfNumberDefinition::setFormatSpecification(FormatSpecification formatSpecification) 0401 { 0402 d->formatSpecification = formatSpecification; 0403 } 0404 0405 bool KoOdfNumberDefinition::letterSynchronization() const 0406 { 0407 return d->letterSynchronization; 0408 } 0409 0410 void KoOdfNumberDefinition::setLetterSynchronization(bool letterSynchronization) 0411 { 0412 d->letterSynchronization = letterSynchronization; 0413 }