filters

conversion.cpp

00001 /* This file is part of the KOffice project
00002    Copyright (C) 2002 Werner Trobin <trobin@kde.org>
00003    Copyright (C) 2002 David Faure <faure@kde.org>
00004 
00005    This program is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU General Public
00007    License version 2 as published by the Free Software Foundation.
00008 
00009    This program is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012     General Public License for more details.
00013 
00014    You should have received a copy of the GNU General Public License
00015    along with this program; see the file COPYING.  If not, write to
00016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  * Boston, MA 02110-1301, USA.
00018 */
00019 
00020 #include "conversion.h"
00021 
00022 #include <wv2/word97_generated.h>
00023 #include <wv2/functordata.h>
00024 #include <wv2/fields.h>
00025 
00026 #include <kdebug.h>
00027 #include <qregexp.h>
00028 #include <qdom.h>
00029 #include <klocale.h>
00030 
00031 QColor Conversion::color(int number, int defaultcolor, bool defaultWhite)
00032 {
00033     switch(number)
00034     {
00035     case 0:
00036         if(defaultWhite)
00037         return Qt::white;
00038     case 1:
00039         return Qt::black;
00040     case 2:
00041         return Qt::blue;
00042     case 3:
00043         return Qt::cyan;
00044     case 4:
00045         return Qt::green;
00046     case 5:
00047         return Qt::magenta;
00048     case 6:
00049         return Qt::red;
00050     case 7:
00051         return Qt::yellow;
00052     case 8:
00053         return Qt::white;
00054     case 9:
00055         return Qt::darkBlue;
00056     case 10:
00057         return Qt::darkCyan;
00058     case 11:
00059         return Qt::darkGreen;
00060     case 12:
00061         return Qt::darkMagenta;
00062     case 13:
00063         return Qt::darkRed;
00064     case 14:
00065         return Qt::darkYellow;
00066     case 15:
00067         return Qt::darkGray;
00068     case 16:
00069         return Qt::lightGray;
00070 
00071     default:
00072             kdDebug(30513) << "Conversion::color: unknown color: " << number << endl;
00073         if(defaultcolor == -1)
00074         return QColor("black");
00075         else
00076         return color(defaultcolor, -1);
00077     }
00078 }
00079 
00080 int Conversion::fillPatternStyle( int ipat )
00081 {
00082     // See $QTDIR/doc/html/qbrush.html#setStyle
00083     switch( ipat )  {
00084     case 0: // Automatic (Apparently it means Solid from background color instead of foreground)
00085     case 1: // Solid
00086         return Qt::SolidPattern;
00087     case 2: // 5%
00088     case 35: // 2.5 Percent
00089     case 36: // 7.5 Percent
00090         return Qt::Dense7Pattern;
00091     case 3: // 10%
00092     case 37: // 12.5 Percent
00093     case 38: // 15 Percent
00094     case 39: // 17.5 Percent
00095     case 4: // 20%
00096         return Qt::Dense6Pattern;
00097     case 40: // 22.5 Percent
00098     case 5: // 25%
00099     case 41: // 27.5 Percent
00100     case 6: // 30%
00101     case 42: // 32.5 Percent
00102     case 43: // 35 Percent
00103     case 44: // 37.5 Percent
00104     case 7: // 40%
00105         return Qt::Dense5Pattern;
00106     case 45: // 42.5 Percent
00107     case 46: // 45 Percent
00108     case 47: // 47.5 Percent
00109     case 8: // 50%
00110     case 48: // 52.5 Percent
00111     case 49: // 55 Percent
00112         return Qt::Dense4Pattern;
00113     case 50: // 57.5 Percent
00114     case 9: // 60%
00115     case 51: // 62.5 Percent
00116     case 52: // 65 Percent
00117     case 53: // 67.5 Percent
00118     case 10: // 70%
00119     case 54: // 72.5 Percent
00120         return Qt::Dense3Pattern;
00121     case 11: // 75%
00122     case 55: // 77.5 Percent
00123     case 12: // 80%
00124     case 56: // 82.5 Percent
00125     case 57: // 85 Percent
00126     case 58: // 87.5 Percent
00127     case 13: // 90%
00128         return Qt::Dense2Pattern;
00129     case 59: // 92.5 Percent
00130     case 60: // 95 Percent
00131     case 61: // 97.5 Percent
00132     case 62: // 97 Percent
00133         return Qt::Dense1Pattern;
00134     case 14: // Dark Horizontal
00135     case 20: // Horizontal
00136         return Qt::HorPattern;
00137     case 15: // Dark Vertical
00138     case 21: // Vertical
00139         return Qt::VerPattern;
00140     case 16: // Dark Forward Diagonal
00141     case 22: // Forward Diagonal
00142         return Qt::FDiagPattern;
00143     case 17: // Dark Backward Diagonal
00144     case 23: // Backward Diagonal
00145         return Qt::BDiagPattern;
00146     case 18: // Dark Cross
00147     case 24: // Cross
00148         return Qt::CrossPattern;
00149     case 19: // Dark Diagonal Cross
00150     case 25: // Diagonal Cross
00151         return Qt::DiagCrossPattern;
00152     default:
00153         kdWarning(30513) << "Unhandled undocumented SHD ipat value: " << ipat << endl;
00154         return Qt::NoBrush;
00155     }
00156 }
00157 
00158 
00159 int Conversion::ditheringToGray( int ipat, bool* ok )
00160 {
00161     *ok = true; // optimistic ;)
00162     switch( ipat )  {
00163     case 2: // 5%
00164         return 255 - qRound(0.05 * 255);
00165     case 35: // 2.5 Percent
00166         return 255 - qRound(0.025 * 255);
00167     case 36: // 7.5 Percent
00168         return 255 - qRound(0.075 * 255);
00169     case 3: // 10%
00170         return 255 - qRound(0.1 * 255);
00171     case 37: // 12.5 Percent
00172         return 255 - qRound(0.125 * 255);
00173     case 38: // 15 Percent
00174         return 255 - qRound(0.15 * 255);
00175     case 39: // 17.5 Percent
00176         return 255 - qRound(0.175 * 255);
00177     case 4: // 20%
00178         return 255 - qRound(0.2 * 255);
00179     case 40: // 22.5 Percent
00180         return 255 - qRound(0.225 * 255);
00181     case 5: // 25%
00182         return 255 - qRound(0.25 * 255);
00183     case 41: // 27.5 Percent
00184         return 255 - qRound(0.275 * 255);
00185     case 6: // 30%
00186         return 255 - qRound(0.3 * 255);
00187     case 42: // 32.5 Percent
00188         return 255 - qRound(0.325 * 255);
00189     case 43: // 35 Percent
00190         return 255 - qRound(0.35 * 255);
00191     case 44: // 37.5 Percent
00192         return 255 - qRound(0.375 * 255);
00193     case 7: // 40%
00194         return 255 - qRound(0.4 * 255);
00195     case 45: // 42.5 Percent
00196         return 255 - qRound(0.425 * 255);
00197     case 46: // 45 Percent
00198         return 255 - qRound(0.45 * 255);
00199     case 47: // 47.5 Percent
00200         return 255 - qRound(0.475 * 255);
00201     case 8: // 50%
00202         return 255 - qRound(0.5 * 255);
00203     case 48: // 52.5 Percent
00204         return 255 - qRound(0.525 * 255);
00205     case 49: // 55 Percent
00206         return 255 - qRound(0.55 * 255);
00207     case 50: // 57.5 Percent
00208         return 255 - qRound(0.575 * 255);
00209     case 9: // 60%
00210         return 255 - qRound(0.6 * 255);
00211     case 51: // 62.5 Percent
00212         return 255 - qRound(0.625 * 255);
00213     case 52: // 65 Percent
00214         return 255 - qRound(0.65 * 255);
00215     case 53: // 67.5 Percent
00216         return 255 - qRound(0.675 * 255);
00217     case 10: // 70%
00218         return 255 - qRound(0.7 * 255);
00219     case 54: // 72.5 Percent
00220         return 255 - qRound(0.725 * 255);
00221     case 11: // 75%
00222         return 255 - qRound(0.75 * 255);
00223     case 55: // 77.5 Percent
00224         return 255 - qRound(0.775 * 255);
00225     case 12: // 80%
00226         return 255 - qRound(0.8 * 255);
00227     case 56: // 82.5 Percent
00228         return 255 - qRound(0.825 * 255);
00229     case 57: // 85 Percent
00230         return 255 - qRound(0.85 * 255);
00231     case 58: // 87.5 Percent
00232         return 255 - qRound(0.875 * 255);
00233     case 13: // 90%
00234         return 255 - qRound(0.9 * 255);
00235     case 59: // 92.5 Percent
00236         return 255 - qRound(0.925 * 255);
00237     case 60: // 95 Percent
00238         return 255 - qRound(0.95 * 255);
00239     case 61: // 97.5 Percent
00240         return 255 - qRound(0.975 * 255);
00241     case 62: // 97 Percent
00242         return 255 - qRound(0.97 * 255);
00243     default:
00244         *ok = false;
00245         return 0;
00246     }
00247 }
00248 
00249 QString Conversion::alignment( int jc ) {
00250     QString value( "left" );
00251     if ( jc == 1 )
00252         value = "center";
00253     else if ( jc == 2 )
00254         value = "right";
00255     else if ( jc == 3 )
00256         value = "justify";
00257     return value;
00258 }
00259 
00260 QString Conversion::lineSpacing( const wvWare::Word97::LSPD& lspd )
00261 {
00262     QString value( "0" );
00263     if ( lspd.fMultLinespace == 1 )
00264     {
00265         // This will be e.g. 1.5 for a 1.5 linespacing.
00266         float proportionalLineSpacing = (float)lspd.dyaLine / 240.0;
00267         if ( QABS(proportionalLineSpacing - 1.5) <= 0.25 ) // close to 1.5?
00268             value = "oneandhalf";
00269         else if ( proportionalLineSpacing > 1.75) // close to 2.0, or more?
00270             value = "double";
00271     }
00272     else if ( lspd.fMultLinespace == 0 )
00273     {
00274         // see sprmPDyaLine in generator_wword8.htm
00275         //float value = QABS((float)lspd.dyaLine / 20.0); // twip -> pt
00276         // lspd.dyaLine > 0 means "at least", < 0 means "exactly"
00277         // "at least" is now possible in kword, but here it's the size of the whole
00278         // line, not the spacing between the line (!)
00279         // To convert between the two, we'd need to find out the height of the
00280         // highest character in the line, and substract it from the value..... Ouch.
00281         // Better implement line-height-at-least like OOo has.
00282     }
00283     else
00284         kdWarning(30513) << "Unhandled LSPD::fMultLinespace value: " << lspd.fMultLinespace << endl;
00285     return value;
00286 }
00287 
00288 void Conversion::setColorAttributes( QDomElement& element, int ico, const QString& prefix, bool defaultWhite )
00289 {
00290     QColor color = Conversion::color( ico, -1, defaultWhite );
00291     element.setAttribute( prefix.isNull() ? "red" : prefix+"Red", color.red() );
00292     element.setAttribute( prefix.isNull() ? "blue" : prefix+"Blue", color.blue() );
00293     element.setAttribute( prefix.isNull() ? "green" : prefix+"Green", color.green() );
00294 }
00295 
00296 void Conversion::setBorderAttributes( QDomElement& borderElement, const wvWare::Word97::BRC& brc, const QString& prefix )
00297 {
00298     setColorAttributes( borderElement, brc.ico, prefix, false );
00299 
00300     borderElement.setAttribute( prefix.isNull() ? "width" : prefix+"Width",
00301                                 (double)brc.dptLineWidth / 8.0 );
00302 
00303     QString style = "0"; // KWord: solid
00304     switch ( brc.brcType ) {
00305     case 0: // none
00306         Q_ASSERT( brc.dptLineWidth == 0 ); // otherwise kword will show a border!
00307         break;
00308     case 7: // dash large gap
00309     case 22: // dash small gap
00310         style = "1"; // KWord: dashes
00311         break;
00312     case 6: // dot
00313         style = "2";
00314         break;
00315     case 8: // dot dash
00316         style = "3";
00317         break;
00318     case 9: // dot dot dash
00319         style = "4";
00320         break;
00321     case 3: // double
00322         style = "5";
00323         break;
00324     case 1: // single
00325     default:
00326         // if a fancy unsupported border is specified -> better a normal border than none
00327         // (so we keep the default value, "0", for "solid single line".
00328         break;
00329     }
00330     borderElement.setAttribute( prefix.isNull() ? "style" : prefix+"Style", style );
00331     // We ignore brc.dptSpace (spacing), brc.fShadow (shadow), and brc.fFrame (?)
00332 }
00333 
00334 int Conversion::numberFormatCode( int nfc )
00335 {
00336     switch ( nfc )
00337     {
00338     case 1: // upper case roman
00339         return 5;
00340     case 2: // lower case roman
00341         return 4;
00342     case 3: // upper case letter
00343         return 3;
00344     case 4: // lower case letter
00345         return 2;
00346     case 5: // arabic with a trailing dot (added by writeCounter)
00347     case 6: // numbered (one, two, three) - not supported by KWord
00348     case 7: // ordinal (first, second, third) - not supported by KWord
00349     case 22: // leading zero (01-09, 10-99, 100-...) - not supported by KWord
00350     case 0: // arabic
00351         return 1;
00352     }
00353     kdWarning(30513) << k_funcinfo << "Unknown NFC: " << nfc << endl;
00354     return 1;
00355 }
00356 
00357 int Conversion::headerTypeToFrameInfo( unsigned char type )
00358 {
00359     switch (type) {
00360     case wvWare::HeaderData::HeaderEven:
00361         return 2;
00362     case wvWare::HeaderData::HeaderOdd:
00363         return 3;
00364     case wvWare::HeaderData::FooterEven:
00365         return 5;
00366     case wvWare::HeaderData::FooterOdd:
00367         return 6;
00368     case wvWare::HeaderData::HeaderFirst:
00369         return 1;
00370     case wvWare::HeaderData::FooterFirst:
00371         return 4;
00372     }
00373     return 0;
00374 }
00375 
00376 QString Conversion::headerTypeToFramesetName( unsigned char type )
00377 {
00378     switch (type) {
00379     case wvWare::HeaderData::HeaderEven:
00380         return i18n("Even Pages Header");
00381     case wvWare::HeaderData::HeaderOdd:
00382         return i18n("Odd Pages Header");
00383     case wvWare::HeaderData::FooterEven:
00384         return i18n("Even Pages Footer");
00385     case wvWare::HeaderData::FooterOdd:
00386         return i18n("Odd Pages Footer");
00387     case wvWare::HeaderData::HeaderFirst:
00388         return i18n("First Page Header");
00389     case wvWare::HeaderData::FooterFirst:
00390         return i18n("First Page Footer");
00391     }
00392     return QString::null;
00393 }
00394 
00395 bool Conversion::isHeader( unsigned char type )
00396 {
00397     switch (type) {
00398     case wvWare::HeaderData::HeaderEven:
00399     case wvWare::HeaderData::HeaderOdd:
00400     case wvWare::HeaderData::HeaderFirst:
00401         return true;
00402     }
00403     return false;
00404 }
00405 
00406 int Conversion::headerMaskToHType( unsigned char mask )
00407 {
00408     bool hasFirst = ( mask & wvWare::HeaderData::HeaderFirst );
00409     // Odd is always there. We have even!=odd only if Even is there too.
00410     bool hasEvenOdd = ( mask & wvWare::HeaderData::HeaderEven );
00411     //kdDebug(30513) << k_funcinfo << " hasEvenOdd=" << hasEvenOdd << endl;
00412     if ( hasFirst )
00413         return hasEvenOdd ? 1 : 2;
00414     return hasEvenOdd ? 3 : 0;
00415 }
00416 
00417 int Conversion::headerMaskToFType( unsigned char mask )
00418 {
00419     bool hasFirst = ( mask & wvWare::HeaderData::FooterFirst );
00420     bool hasEvenOdd = ( mask & wvWare::HeaderData::FooterEven );
00421     // Odd is always there. We have even!=odd only if Even is there too.
00422     kdDebug(30513) << k_funcinfo << " hasEvenOdd=" << hasEvenOdd << endl;
00423     if ( hasFirst )
00424         return hasEvenOdd ? 1 : 2;
00425     return hasEvenOdd ? 3 : 0;
00426 }
00427 
00428 int Conversion::fldToFieldType( const wvWare::FLD* fld )
00429 {
00430     // assume unhandled
00431     int m_fieldType = -1;
00432 
00433     // sanity check
00434     if( !fld ) return -1;
00435 
00436     switch( fld->flt )
00437     {
00438     case 15:    m_fieldType = 10; break;  // title
00439     case 17:    m_fieldType =  2; break;  // author
00440     case 18:    m_fieldType = -1; break;  // keywords (unhandled)
00441     case 19:    m_fieldType = 11; break;  // comments (unhandled)
00442     case 21:    m_fieldType = -1; break;  // createdate (unhandled)
00443     case 22:    m_fieldType = -1; break;  // savedate (unhandled)
00444     case 23:    m_fieldType = -1; break;  // printdate (unhandled)
00445     case 25:    m_fieldType = -1; break;  // edittime (unhandled)
00446     case 29:    m_fieldType =  0; break;  // filename (unhandled)
00447     case 32:    m_fieldType = -1; break;  // time (unhandled)
00448     case 60:    m_fieldType =  2; break;  // username <-> KWord's author name
00449     case 61:    m_fieldType = 16; break;  // userinitials <-> KWord's author initial)
00450     case 62:    m_fieldType = -1; break;  // useraddress (unhandled)
00451     default:    m_fieldType = -1; break;
00452     }
00453 
00454     if( m_fieldType < 0 )
00455         kdDebug(30513) << "unhandled field: fld.ftl: " << (int)fld->flt << endl;
00456 
00457     return m_fieldType;
00458 }
KDE Home | KDE Accessibility Home | Description of Access Keys