You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
459 lines
14 KiB
459 lines
14 KiB
/* This file is part of the KOffice project
|
|
Copyright (C) 2002 Werner Trobin <trobin@kde.org>
|
|
Copyright (C) 2002 David Faure <faure@kde.org>
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public
|
|
License version 2 as published by the Free Software Foundation.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; see the file COPYING. If not, write to
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
* Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#include "conversion.h"
|
|
|
|
#include <wv2/word97_generated.h>
|
|
#include <wv2/functordata.h>
|
|
#include <wv2/fields.h>
|
|
|
|
#include <kdebug.h>
|
|
#include <tqregexp.h>
|
|
#include <tqdom.h>
|
|
#include <tdelocale.h>
|
|
|
|
TQColor Conversion::color(int number, int defaultcolor, bool defaultWhite)
|
|
{
|
|
switch(number)
|
|
{
|
|
case 0:
|
|
if(defaultWhite)
|
|
return TQt::white;
|
|
case 1:
|
|
return TQt::black;
|
|
case 2:
|
|
return TQt::blue;
|
|
case 3:
|
|
return TQt::cyan;
|
|
case 4:
|
|
return TQt::green;
|
|
case 5:
|
|
return TQt::magenta;
|
|
case 6:
|
|
return TQt::red;
|
|
case 7:
|
|
return TQt::yellow;
|
|
case 8:
|
|
return TQt::white;
|
|
case 9:
|
|
return TQt::darkBlue;
|
|
case 10:
|
|
return TQt::darkCyan;
|
|
case 11:
|
|
return TQt::darkGreen;
|
|
case 12:
|
|
return TQt::darkMagenta;
|
|
case 13:
|
|
return TQt::darkRed;
|
|
case 14:
|
|
return TQt::darkYellow;
|
|
case 15:
|
|
return TQt::darkGray;
|
|
case 16:
|
|
return TQt::lightGray;
|
|
|
|
default:
|
|
kdDebug(30513) << "Conversion::color: unknown color: " << number << endl;
|
|
if(defaultcolor == -1)
|
|
return TQColor("black");
|
|
else
|
|
return color(defaultcolor, -1);
|
|
}
|
|
}
|
|
|
|
int Conversion::fillPatternStyle( int ipat )
|
|
{
|
|
// See $TQTDIR/doc/html/qbrush.html#setStyle
|
|
switch( ipat ) {
|
|
case 0: // Automatic (Apparently it means Solid from background color instead of foreground)
|
|
case 1: // Solid
|
|
return TQt::SolidPattern;
|
|
case 2: // 5%
|
|
case 35: // 2.5 Percent
|
|
case 36: // 7.5 Percent
|
|
return TQt::Dense7Pattern;
|
|
case 3: // 10%
|
|
case 37: // 12.5 Percent
|
|
case 38: // 15 Percent
|
|
case 39: // 17.5 Percent
|
|
case 4: // 20%
|
|
return TQt::Dense6Pattern;
|
|
case 40: // 22.5 Percent
|
|
case 5: // 25%
|
|
case 41: // 27.5 Percent
|
|
case 6: // 30%
|
|
case 42: // 32.5 Percent
|
|
case 43: // 35 Percent
|
|
case 44: // 37.5 Percent
|
|
case 7: // 40%
|
|
return TQt::Dense5Pattern;
|
|
case 45: // 42.5 Percent
|
|
case 46: // 45 Percent
|
|
case 47: // 47.5 Percent
|
|
case 8: // 50%
|
|
case 48: // 52.5 Percent
|
|
case 49: // 55 Percent
|
|
return TQt::Dense4Pattern;
|
|
case 50: // 57.5 Percent
|
|
case 9: // 60%
|
|
case 51: // 62.5 Percent
|
|
case 52: // 65 Percent
|
|
case 53: // 67.5 Percent
|
|
case 10: // 70%
|
|
case 54: // 72.5 Percent
|
|
return TQt::Dense3Pattern;
|
|
case 11: // 75%
|
|
case 55: // 77.5 Percent
|
|
case 12: // 80%
|
|
case 56: // 82.5 Percent
|
|
case 57: // 85 Percent
|
|
case 58: // 87.5 Percent
|
|
case 13: // 90%
|
|
return TQt::Dense2Pattern;
|
|
case 59: // 92.5 Percent
|
|
case 60: // 95 Percent
|
|
case 61: // 97.5 Percent
|
|
case 62: // 97 Percent
|
|
return TQt::Dense1Pattern;
|
|
case 14: // Dark Horizontal
|
|
case 20: // Horizontal
|
|
return TQt::HorPattern;
|
|
case 15: // Dark Vertical
|
|
case 21: // Vertical
|
|
return TQt::VerPattern;
|
|
case 16: // Dark Forward Diagonal
|
|
case 22: // Forward Diagonal
|
|
return TQt::FDiagPattern;
|
|
case 17: // Dark Backward Diagonal
|
|
case 23: // Backward Diagonal
|
|
return TQt::BDiagPattern;
|
|
case 18: // Dark Cross
|
|
case 24: // Cross
|
|
return TQt::CrossPattern;
|
|
case 19: // Dark Diagonal Cross
|
|
case 25: // Diagonal Cross
|
|
return TQt::DiagCrossPattern;
|
|
default:
|
|
kdWarning(30513) << "Unhandled undocumented SHD ipat value: " << ipat << endl;
|
|
return TQt::NoBrush;
|
|
}
|
|
}
|
|
|
|
|
|
int Conversion::ditheringToGray( int ipat, bool* ok )
|
|
{
|
|
*ok = true; // optimistic ;)
|
|
switch( ipat ) {
|
|
case 2: // 5%
|
|
return 255 - tqRound(0.05 * 255);
|
|
case 35: // 2.5 Percent
|
|
return 255 - tqRound(0.025 * 255);
|
|
case 36: // 7.5 Percent
|
|
return 255 - tqRound(0.075 * 255);
|
|
case 3: // 10%
|
|
return 255 - tqRound(0.1 * 255);
|
|
case 37: // 12.5 Percent
|
|
return 255 - tqRound(0.125 * 255);
|
|
case 38: // 15 Percent
|
|
return 255 - tqRound(0.15 * 255);
|
|
case 39: // 17.5 Percent
|
|
return 255 - tqRound(0.175 * 255);
|
|
case 4: // 20%
|
|
return 255 - tqRound(0.2 * 255);
|
|
case 40: // 22.5 Percent
|
|
return 255 - tqRound(0.225 * 255);
|
|
case 5: // 25%
|
|
return 255 - tqRound(0.25 * 255);
|
|
case 41: // 27.5 Percent
|
|
return 255 - tqRound(0.275 * 255);
|
|
case 6: // 30%
|
|
return 255 - tqRound(0.3 * 255);
|
|
case 42: // 32.5 Percent
|
|
return 255 - tqRound(0.325 * 255);
|
|
case 43: // 35 Percent
|
|
return 255 - tqRound(0.35 * 255);
|
|
case 44: // 37.5 Percent
|
|
return 255 - tqRound(0.375 * 255);
|
|
case 7: // 40%
|
|
return 255 - tqRound(0.4 * 255);
|
|
case 45: // 42.5 Percent
|
|
return 255 - tqRound(0.425 * 255);
|
|
case 46: // 45 Percent
|
|
return 255 - tqRound(0.45 * 255);
|
|
case 47: // 47.5 Percent
|
|
return 255 - tqRound(0.475 * 255);
|
|
case 8: // 50%
|
|
return 255 - tqRound(0.5 * 255);
|
|
case 48: // 52.5 Percent
|
|
return 255 - tqRound(0.525 * 255);
|
|
case 49: // 55 Percent
|
|
return 255 - tqRound(0.55 * 255);
|
|
case 50: // 57.5 Percent
|
|
return 255 - tqRound(0.575 * 255);
|
|
case 9: // 60%
|
|
return 255 - tqRound(0.6 * 255);
|
|
case 51: // 62.5 Percent
|
|
return 255 - tqRound(0.625 * 255);
|
|
case 52: // 65 Percent
|
|
return 255 - tqRound(0.65 * 255);
|
|
case 53: // 67.5 Percent
|
|
return 255 - tqRound(0.675 * 255);
|
|
case 10: // 70%
|
|
return 255 - tqRound(0.7 * 255);
|
|
case 54: // 72.5 Percent
|
|
return 255 - tqRound(0.725 * 255);
|
|
case 11: // 75%
|
|
return 255 - tqRound(0.75 * 255);
|
|
case 55: // 77.5 Percent
|
|
return 255 - tqRound(0.775 * 255);
|
|
case 12: // 80%
|
|
return 255 - tqRound(0.8 * 255);
|
|
case 56: // 82.5 Percent
|
|
return 255 - tqRound(0.825 * 255);
|
|
case 57: // 85 Percent
|
|
return 255 - tqRound(0.85 * 255);
|
|
case 58: // 87.5 Percent
|
|
return 255 - tqRound(0.875 * 255);
|
|
case 13: // 90%
|
|
return 255 - tqRound(0.9 * 255);
|
|
case 59: // 92.5 Percent
|
|
return 255 - tqRound(0.925 * 255);
|
|
case 60: // 95 Percent
|
|
return 255 - tqRound(0.95 * 255);
|
|
case 61: // 97.5 Percent
|
|
return 255 - tqRound(0.975 * 255);
|
|
case 62: // 97 Percent
|
|
return 255 - tqRound(0.97 * 255);
|
|
default:
|
|
*ok = false;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
TQString Conversion::alignment( int jc ) {
|
|
TQString value( "left" );
|
|
if ( jc == 1 )
|
|
value = "center";
|
|
else if ( jc == 2 )
|
|
value = "right";
|
|
else if ( jc == 3 )
|
|
value = "justify";
|
|
return value;
|
|
}
|
|
|
|
TQString Conversion::lineSpacing( const wvWare::Word97::LSPD& lspd )
|
|
{
|
|
TQString value( "0" );
|
|
if ( lspd.fMultLinespace == 1 )
|
|
{
|
|
// This will be e.g. 1.5 for a 1.5 linespacing.
|
|
float proportionalLineSpacing = (float)lspd.dyaLine / 240.0;
|
|
if ( TQABS(proportionalLineSpacing - 1.5) <= 0.25 ) // close to 1.5?
|
|
value = "oneandhalf";
|
|
else if ( proportionalLineSpacing > 1.75) // close to 2.0, or more?
|
|
value = "double";
|
|
}
|
|
else if ( lspd.fMultLinespace == 0 )
|
|
{
|
|
// see sprmPDyaLine in generator_wword8.htm
|
|
//float value = TQABS((float)lspd.dyaLine / 20.0); // twip -> pt
|
|
// lspd.dyaLine > 0 means "at least", < 0 means "exactly"
|
|
// "at least" is now possible in kword, but here it's the size of the whole
|
|
// line, not the spacing between the line (!)
|
|
// To convert between the two, we'd need to find out the height of the
|
|
// highest character in the line, and substract it from the value..... Ouch.
|
|
// Better implement line-height-at-least like OOo has.
|
|
}
|
|
else
|
|
kdWarning(30513) << "Unhandled LSPD::fMultLinespace value: " << lspd.fMultLinespace << endl;
|
|
return value;
|
|
}
|
|
|
|
void Conversion::setColorAttributes( TQDomElement& element, int ico, const TQString& prefix, bool defaultWhite )
|
|
{
|
|
TQColor color = Conversion::color( ico, -1, defaultWhite );
|
|
element.setAttribute( prefix.isNull() ? "red" : prefix+"Red", color.red() );
|
|
element.setAttribute( prefix.isNull() ? "blue" : prefix+"Blue", color.blue() );
|
|
element.setAttribute( prefix.isNull() ? "green" : prefix+"Green", color.green() );
|
|
}
|
|
|
|
void Conversion::setBorderAttributes( TQDomElement& borderElement, const wvWare::Word97::BRC& brc, const TQString& prefix )
|
|
{
|
|
setColorAttributes( borderElement, brc.cv, prefix, false );
|
|
|
|
borderElement.setAttribute( prefix.isNull() ? "width" : prefix+"Width",
|
|
(double)brc.dptLineWidth / 8.0 );
|
|
|
|
TQString style = "0"; // KWord: solid
|
|
switch ( brc.brcType ) {
|
|
case 0: // none
|
|
Q_ASSERT( brc.dptLineWidth == 0 ); // otherwise kword will show a border!
|
|
break;
|
|
case 7: // dash large gap
|
|
case 22: // dash small gap
|
|
style = "1"; // KWord: dashes
|
|
break;
|
|
case 6: // dot
|
|
style = "2";
|
|
break;
|
|
case 8: // dot dash
|
|
style = "3";
|
|
break;
|
|
case 9: // dot dot dash
|
|
style = "4";
|
|
break;
|
|
case 3: // double
|
|
style = "5";
|
|
break;
|
|
case 1: // single
|
|
default:
|
|
// if a fancy unsupported border is specified -> better a normal border than none
|
|
// (so we keep the default value, "0", for "solid single line".
|
|
break;
|
|
}
|
|
borderElement.setAttribute( prefix.isNull() ? "style" : prefix+"Style", style );
|
|
// We ignore brc.dptSpace (spacing), brc.fShadow (shadow), and brc.fFrame (?)
|
|
}
|
|
|
|
int Conversion::numberFormatCode( int nfc )
|
|
{
|
|
switch ( nfc )
|
|
{
|
|
case 1: // upper case roman
|
|
return 5;
|
|
case 2: // lower case roman
|
|
return 4;
|
|
case 3: // upper case letter
|
|
return 3;
|
|
case 4: // lower case letter
|
|
return 2;
|
|
case 5: // arabic with a trailing dot (added by writeCounter)
|
|
case 6: // numbered (one, two, three) - not supported by KWord
|
|
case 7: // ordinal (first, second, third) - not supported by KWord
|
|
case 22: // leading zero (01-09, 10-99, 100-...) - not supported by KWord
|
|
case 0: // arabic
|
|
return 1;
|
|
}
|
|
kdWarning(30513) << k_funcinfo << "Unknown NFC: " << nfc << endl;
|
|
return 1;
|
|
}
|
|
|
|
int Conversion::headerTypeToFrameInfo( unsigned char type )
|
|
{
|
|
switch (type) {
|
|
case wvWare::HeaderData::HeaderEven:
|
|
return 2;
|
|
case wvWare::HeaderData::HeaderOdd:
|
|
return 3;
|
|
case wvWare::HeaderData::FooterEven:
|
|
return 5;
|
|
case wvWare::HeaderData::FooterOdd:
|
|
return 6;
|
|
case wvWare::HeaderData::HeaderFirst:
|
|
return 1;
|
|
case wvWare::HeaderData::FooterFirst:
|
|
return 4;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
TQString Conversion::headerTypeToFramesetName( unsigned char type )
|
|
{
|
|
switch (type) {
|
|
case wvWare::HeaderData::HeaderEven:
|
|
return i18n("Even Pages Header");
|
|
case wvWare::HeaderData::HeaderOdd:
|
|
return i18n("Odd Pages Header");
|
|
case wvWare::HeaderData::FooterEven:
|
|
return i18n("Even Pages Footer");
|
|
case wvWare::HeaderData::FooterOdd:
|
|
return i18n("Odd Pages Footer");
|
|
case wvWare::HeaderData::HeaderFirst:
|
|
return i18n("First Page Header");
|
|
case wvWare::HeaderData::FooterFirst:
|
|
return i18n("First Page Footer");
|
|
}
|
|
return TQString();
|
|
}
|
|
|
|
bool Conversion::isHeader( unsigned char type )
|
|
{
|
|
switch (type) {
|
|
case wvWare::HeaderData::HeaderEven:
|
|
case wvWare::HeaderData::HeaderOdd:
|
|
case wvWare::HeaderData::HeaderFirst:
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
int Conversion::headerMaskToHType( unsigned char mask )
|
|
{
|
|
bool hasFirst = ( mask & wvWare::HeaderData::HeaderFirst );
|
|
// Odd is always there. We have even!=odd only if Even is there too.
|
|
bool hasEvenOdd = ( mask & wvWare::HeaderData::HeaderEven );
|
|
//kdDebug(30513) << k_funcinfo << " hasEvenOdd=" << hasEvenOdd << endl;
|
|
if ( hasFirst )
|
|
return hasEvenOdd ? 1 : 2;
|
|
return hasEvenOdd ? 3 : 0;
|
|
}
|
|
|
|
int Conversion::headerMaskToFType( unsigned char mask )
|
|
{
|
|
bool hasFirst = ( mask & wvWare::HeaderData::FooterFirst );
|
|
bool hasEvenOdd = ( mask & wvWare::HeaderData::FooterEven );
|
|
// Odd is always there. We have even!=odd only if Even is there too.
|
|
kdDebug(30513) << k_funcinfo << " hasEvenOdd=" << hasEvenOdd << endl;
|
|
if ( hasFirst )
|
|
return hasEvenOdd ? 1 : 2;
|
|
return hasEvenOdd ? 3 : 0;
|
|
}
|
|
|
|
int Conversion::fldToFieldType( const wvWare::FLD* fld )
|
|
{
|
|
// assume unhandled
|
|
int m_fieldType = -1;
|
|
|
|
// sanity check
|
|
if( !fld ) return -1;
|
|
|
|
switch( fld->flt )
|
|
{
|
|
case 15: m_fieldType = 10; break; // title
|
|
case 17: m_fieldType = 2; break; // author
|
|
case 18: m_fieldType = -1; break; // keywords (unhandled)
|
|
case 19: m_fieldType = 11; break; // comments (unhandled)
|
|
case 21: m_fieldType = -1; break; // createdate (unhandled)
|
|
case 22: m_fieldType = -1; break; // savedate (unhandled)
|
|
case 23: m_fieldType = -1; break; // printdate (unhandled)
|
|
case 25: m_fieldType = -1; break; // edittime (unhandled)
|
|
case 29: m_fieldType = 0; break; // filename (unhandled)
|
|
case 32: m_fieldType = -1; break; // time (unhandled)
|
|
case 60: m_fieldType = 2; break; // username <-> KWord's author name
|
|
case 61: m_fieldType = 16; break; // userinitials <-> KWord's author initial)
|
|
case 62: m_fieldType = -1; break; // useraddress (unhandled)
|
|
default: m_fieldType = -1; break;
|
|
}
|
|
|
|
if( m_fieldType < 0 )
|
|
kdDebug(30513) << "unhandled field: fld.ftl: " << (int)fld->flt << endl;
|
|
|
|
return m_fieldType;
|
|
}
|