~ubuntu-branches/ubuntu/precise/koffice/precise

« back to all changes in this revision

Viewing changes to filters/kword/rtf/import/rtfimport.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jonathan Riddell
  • Date: 2010-09-21 15:36:35 UTC
  • mfrom: (1.4.1 upstream) (60.2.11 maverick)
  • Revision ID: james.westby@ubuntu.com-20100921153635-6tejqkiro2u21ydi
Tags: 1:2.2.2-0ubuntu3
Add kubuntu_03_fix-crash-on-closing-sqlite-connection-2.2.2.diff and
kubuntu_04_support-large-memo-values-for-msaccess-2.2.2.diff as
recommended by upstream http://kexi-
project.org/wiki/wikiview/index.php@Kexi2.2_Patches.html#sqlite_stab
ility

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
#include <QFontInfo>
32
32
#include <QTextStream>
33
33
 
34
 
#include <kopicture/KoPicture.h>
 
34
#include <Picture.h>
35
35
#include <KoFilterManager.h>
36
36
 
37
37
 
38
38
typedef KGenericFactory<RTFImport> RTFImportFactory;
39
 
K_EXPORT_COMPONENT_FACTORY( librtfimport, RTFImportFactory( "kofficefilters" ) )
 
39
K_EXPORT_COMPONENT_FACTORY(librtfimport, RTFImportFactory("kofficefilters"))
40
40
 
41
41
// defines a property
42
 
#define PROP(a,b,c,d,e)         { a, b, &RTFImport::c, d, e }
 
42
#define PROP(a,b,c,d,e)  { a, b, &RTFImport::c, d, e }
43
43
 
44
44
// defines a member variable of RTFImport as a property (DEPRECATED)
45
 
#define MEMBER(a,b,c,d,e)       PROP(a,b,c,offsetof(RTFImport,d),e)
 
45
#define MEMBER(a,b,c,d,e) PROP(a,b,c,offsetof(RTFImport,d),e)
46
46
 
47
 
static RTFProperty destinationPropertyTable[] =
48
 
    {
49
 
//              only-valid-in   control word    function                offset, value
50
 
        PROP(   0L,             "@*",           skipGroup,              0L, false ),
51
 
        MEMBER( "@info",        "@author",      parsePlainText,         author, false ),
52
 
        PROP(   "@pict",        "@blipuid",     parseBlipUid,   0, 0 ),
53
 
        PROP(   "@rtf",         "@colortbl",    parseColorTable,        0L, true ),
54
 
        MEMBER( "@info",        "@company",     parsePlainText,         company, false ),
55
 
        MEMBER( "@info",        "@doccomm",     parsePlainText,         doccomm, false ),
56
 
        PROP(   "Text",         "@field",       parseField,             0L, false ),
57
 
        PROP(   "@field",       "@fldinst",     parseFldinst,           0L, false ),
58
 
        PROP(   "@field",       "@fldrslt",     parseFldrslt,           0L, false ),
59
 
        PROP(   "@rtf",         "@fonttbl",     parseFontTable,         0L, true ),
60
 
        MEMBER( "@rtf",         "@footer",      parseRichText,          oddPagesFooter, true ),
61
 
        PROP(   "@rtf",         "@footnote",    parseFootNote,          0L, true ),
62
 
        MEMBER( "@rtf",         "@footerf",     parseRichText,          firstPageFooter, true ),
63
 
        MEMBER( "@rtf",         "@footerl",     parseRichText,          oddPagesFooter, true ),
64
 
        MEMBER( "@rtf",         "@footerr",     parseRichText,          evenPagesFooter, true ),
65
 
        MEMBER( "@rtf",         "@header",      parseRichText,          oddPagesHeader, true ),
66
 
        MEMBER( "@rtf",         "@headerf",     parseRichText,          firstPageHeader, true ),
67
 
        MEMBER( "@rtf",         "@headerl",     parseRichText,          oddPagesHeader, true ),
68
 
        MEMBER( "@rtf",         "@headerr",     parseRichText,          evenPagesHeader, true ),
69
 
        PROP(   "@rtf",         "@info",        parseGroup,             0L, true ),
70
 
        PROP(   "Text",         "@nonshppict",  skipGroup,              0L, false ),
71
 
        PROP(   0L,             "@panose",              skipGroup,      0L, 0 ), // Not supported
72
 
        PROP(   "Text",         "@pict",        parsePicture,           0L, true ),
73
 
        MEMBER( "@",            "@rtf",         parseRichText,          bodyText, true ),
74
 
        PROP(   "Text",         "@shpinst",     skipGroup,              0L, true ),
75
 
        PROP(   "Text",         "@shppict",     parseGroup,             0L, false ),
76
 
        PROP(   "@rtf",         "@stylesheet",  parseStyleSheet,        0L, true ),
77
 
        MEMBER( "@info",        "@title",       parsePlainText,         title, false ),
 
47
static RTFProperty destinationPropertyTable[] = {
 
48
//  only-valid-in control word function  offset, value
 
49
    PROP(0L,  "@*",  skipGroup,  0L, false),
 
50
    MEMBER("@info", "@author", parsePlainText,  author, false),
 
51
    PROP("@pict", "@blipuid", parseBlipUid, 0, 0),
 
52
    PROP("@rtf",  "@colortbl", parseColorTable, 0L, true),
 
53
    MEMBER("@info", "@company", parsePlainText,  company, false),
 
54
    MEMBER("@info", "@doccomm", parsePlainText,  doccomm, false),
 
55
    PROP("Text",  "@field", parseField,  0L, false),
 
56
    PROP("@field", "@fldinst", parseFldinst,  0L, false),
 
57
    PROP("@field", "@fldrslt", parseFldrslt,  0L, false),
 
58
    PROP("@rtf",  "@fonttbl", parseFontTable,  0L, true),
 
59
    MEMBER("@rtf",  "@footer", parseRichText,  oddPagesFooter, true),
 
60
    PROP("@rtf",  "@footnote", parseFootNote,  0L, true),
 
61
    MEMBER("@rtf",  "@footerf", parseRichText,  firstPageFooter, true),
 
62
    MEMBER("@rtf",  "@footerl", parseRichText,  oddPagesFooter, true),
 
63
    MEMBER("@rtf",  "@footerr", parseRichText,  evenPagesFooter, true),
 
64
    MEMBER("@rtf",  "@header", parseRichText,  oddPagesHeader, true),
 
65
    MEMBER("@rtf",  "@headerf", parseRichText,  firstPageHeader, true),
 
66
    MEMBER("@rtf",  "@headerl", parseRichText,  oddPagesHeader, true),
 
67
    MEMBER("@rtf",  "@headerr", parseRichText,  evenPagesHeader, true),
 
68
    PROP("@rtf",  "@info", parseGroup,  0L, true),
 
69
    PROP("Text",  "@nonshppict", skipGroup,  0L, false),
 
70
    PROP(0L,  "@panose",  skipGroup, 0L, 0),   // Not supported
 
71
    PROP("Text",  "@pict", parsePicture,  0L, true),
 
72
    MEMBER("@",  "@rtf",  parseRichText,  bodyText, true),
 
73
    PROP("Text",  "@shpinst", skipGroup,  0L, true),
 
74
    PROP("Text",  "@shppict", parseGroup,  0L, false),
 
75
    PROP("@rtf",  "@stylesheet", parseStyleSheet, 0L, true),
 
76
    MEMBER("@info", "@title", parsePlainText,  title, false),
78
77
};
79
78
 
80
79
static RTFProperty propertyTable[] =
81
80
    // Alphabetical order
82
 
    {
83
 
//              only-valid-in   control word    function                offset, value
84
 
        PROP(   "Text",         "\n",           insertParagraph,        0L, 0 ),
85
 
        PROP(   "Text",         "\r",           insertParagraph,        0L, 0 ),
86
 
        PROP(   0L,             "\'",           insertHexSymbol,        0L, 0 ),
87
 
        PROP(   0L,             "\\",           insertSymbol,           0L, '\\' ),
88
 
        PROP(   0L,             "_",            insertSymbol,           0L, 0x2011 ),
89
 
        PROP(   0L,             "{",            insertSymbol,           0L, '{' ),
90
 
        PROP(   0L,             "|",            insertSymbol,           0L, 0x00b7 ),
91
 
        PROP(   0L,             "}",            insertSymbol,           0L, '}' ),
92
 
        PROP(   0L,             "~",            insertSymbol,           0L, 0x00a0 ),
93
 
        PROP(   0L,             "-",            insertSymbol,           0L, 0x00ad ),
94
 
        PROP(   0L,             "adjustright",  ignoreKeyword,          0L, 0 ), // Not supported, KWord has no grid
95
 
        PROP(   0L,             "ansi", setAnsiCodepage,                0L, 0 ),
96
 
        PROP(   0L,             "ansicpg",      setCodepage,            0L, 0 ),
97
 
        MEMBER( 0L,             "b",            setToggleProperty,      state.format.bold, 0 ),
98
 
        // \bin is handled in the tokenizer
99
 
        MEMBER( "@colortbl",    "blue",         setNumericProperty,     blue, 0 ),
100
 
        MEMBER( 0L,             "box",          setEnumProperty,        state.layout.border, 0 ),
101
 
        PROP(   0L,             "brdrb",        selectLayoutBorder,     0L, 3 ),
102
 
        PROP(   0L,             "brdrcf",       setBorderColor,           0L, 0 ),
103
 
        PROP(   0L,             "brdrdash",     setBorderStyle,         0L, RTFBorder::Dashes ),
104
 
        PROP(   0L,             "brdrdashd",    setBorderStyle,         0L, RTFBorder::DashDot ),
105
 
        PROP(   0L,             "brdrdashdd",   setBorderStyle,         0L, RTFBorder::DashDotDot ),
106
 
        PROP(   0L,             "brdrdashsm",   setBorderStyle,         0L, RTFBorder::Dashes ),
107
 
        PROP(   0L,             "brdrdb",       setBorderStyle,         0L, RTFBorder::Solid ),
108
 
        PROP(   0L,             "brdrdot",      setBorderStyle,         0L, RTFBorder::Dots ),
109
 
        PROP(   0L,             "brdrhairline", setBorderStyle,         0L, RTFBorder::Solid ),
110
 
        PROP(   0L,             "brdrl",        selectLayoutBorder,     0L, 0 ),
111
 
        PROP(   0L,             "brdrr",        selectLayoutBorder,     0L, 1 ),
112
 
        PROP(   0L,             "brdrs",        setBorderStyle,         0L, RTFBorder::Solid ),
113
 
        PROP(   0L,             "brdrsh",       setBorderStyle,         0L, RTFBorder::Solid ),
114
 
        PROP(   0L,             "brdrt",        selectLayoutBorder,     0L, 2 ),
115
 
        PROP(   0L,             "brdrth",       setBorderStyle,         0L, RTFBorder::Solid ),
116
 
        PROP(   0L,             "brdrw",        setBorderProperty,      offsetof(RTFBorder,width), 0 ),
117
 
        PROP(   0L,             "bullet",       insertSymbol,           0L, 0x2022 ),
118
 
        PROP(   0L,             "brsp",         setBorderProperty,      offsetof(RTFBorder,space), 0 ),
119
 
        MEMBER( 0L,             "caps",         setToggleProperty,      state.format.caps, 0 ),
120
 
        MEMBER( 0L,             "cb",           setNumericProperty,     state.format.bgcolor, 0 ),
121
 
        MEMBER( 0L,             "highlight",    setNumericProperty,     state.format.bgcolor, 0 ),
122
 
        PROP(   "Text",         "cell",         insertTableCell,        0L, 0 ),
123
 
        PROP(   0L,             "cellx",        insertCellDef,          0L, 0 ),
124
 
        MEMBER( 0L,             "cf",           setNumericProperty,     state.format.color, 0 ),
125
 
        PROP(   0L,             "chdate",       insertDateTime,         0L, true ),
126
 
        PROP(   0L,             "chpgn",        insertPageNumber,               0L, 0 ),
127
 
        PROP(   0L,             "chtime",       insertDateTime,         0L, false ),
128
 
        PROP(   0L,             "clbrdrb",      selectLayoutBorderFromCell,     0L, 3 ),
129
 
        PROP(   0L,             "clbrdrl",      selectLayoutBorderFromCell,     0L, 0 ),
130
 
        PROP(   0L,             "clbrdrr",      selectLayoutBorderFromCell,     0L, 1 ),
131
 
        PROP(   0L,             "clbrdrt",      selectLayoutBorderFromCell,     0L, 2 ),
132
 
        MEMBER( 0L,             "clcbpat",      setNumericProperty,     state.tableCell.bgcolor, 0 ),
133
 
        PROP(   0L,             "cs",   ignoreKeyword,          0L, 0 ), // Not supported by KWord 1.3
134
 
        PROP(   0L,             "datafield",    skipGroup,              0L, 0 ), // Binary data in variables are not supported
135
 
        MEMBER( "@rtf",         "deff",         setNumericProperty,     defaultFont, 0 ),
136
 
        MEMBER( "@rtf",         "deftab",       setNumericProperty,     defaultTab, 0 ),
137
 
        PROP(   "@pict",        "dibitmap",     setPictureType,         0L, RTFPicture::BMP ),
138
 
        MEMBER( 0L,             "dn",           setNumericProperty,     state.format.baseline, 6 ),
139
 
        PROP(   0L,             "emdash",       insertSymbol,           0L, 0x2014 ),
140
 
        PROP(   "@pict",        "emfblip",      setPictureType,         0L, RTFPicture::EMF ),
141
 
        PROP(   0L,             "emspace",      insertSymbol,           0L, 0x2003 ),
142
 
        PROP(   0L,             "endash",       insertSymbol,           0L, 0x2013 ),
143
 
        PROP(   0L,             "enspace",      insertSymbol,           0L, 0x2002 ),
144
 
        PROP(   0L,             "expnd",        ignoreKeyword,          0L, 0 ), // Expansion/compression of character inter-space not supported
145
 
        PROP(   0L,             "expndtw",      ignoreKeyword,          0L, 0 ), // Expansion/compression of character inter-space not supported
146
 
        MEMBER( 0L,             "f",            setNumericProperty,     state.format.font, 0 ),
147
 
        MEMBER( "@rtf",         "facingp",      setFlagProperty,        facingPages, true ),
148
 
        PROP(   0L,             "fcharset",     setCharset,             0L, 0 ), // Not needed with Qt
149
 
        PROP(   "@fonttbl",     "fdecor",       setFontStyleHint,       0L, QFont::Decorative ),
150
 
        MEMBER( 0L,             "fi",           setNumericProperty,     state.layout.firstIndent, 0 ),
151
 
        PROP(   "@fonttbl",     "fmodern",      setFontStyleHint,       0L, QFont::TypeWriter ),
152
 
        PROP(   "@fonttbl",     "fnil",         setFontStyleHint,       0L, QFont::AnyStyle ),
153
 
        MEMBER( 0L,             "footery",      setNumericProperty,     state.section.footerMargin, 0 ),
154
 
        PROP(   0L,             "formshade",    ignoreKeyword,          0L, 0 ), // Not supported, KWord has no form support
155
 
        MEMBER( "@fonttbl",     "fprq",         setNumericProperty,     font.fixedPitch, 0 ),
156
 
        PROP(   "@fonttbl",     "froman",       setFontStyleHint,       0L, QFont::Serif ),
157
 
        MEMBER( 0L,             "fs",           setNumericProperty,     state.format.fontSize, 0 ),
158
 
        PROP(   "@fonttbl",     "fscript",      setFontStyleHint,       0L, QFont::AnyStyle ),
159
 
        PROP(   "@fonttbl",     "fswiss",       setFontStyleHint,       0L, QFont::SansSerif ),
160
 
        PROP(   "@fonttbl",     "ftech",        setFontStyleHint,       0L, QFont::AnyStyle ),
161
 
        MEMBER( "@colortbl",    "green",        setNumericProperty,     green, 0 ),
162
 
        MEMBER( 0L,             "headery",      setNumericProperty,     state.section.headerMargin, 0 ),
163
 
        MEMBER( 0L,             "i",            setToggleProperty,      state.format.italic, 0 ),
164
 
        MEMBER( 0L,             "intbl",        setFlagProperty,        state.layout.inTable, true ),
165
 
        PROP(   "@pict",        "jpegblip",     setPictureType,         0L, RTFPicture::JPEG ),
166
 
        MEMBER( 0L,             "keep",         setFlagProperty,        state.layout.keep, true ),
167
 
        MEMBER( 0L,             "keepn",        setFlagProperty,        state.layout.keepNext, true ),
168
 
        MEMBER( "@rtf",         "landscape",    setFlagProperty,        landscape, true ),
169
 
        PROP(   0L,             "ldblquote",    insertSymbol,           0L, 0x201c ),
170
 
        MEMBER( 0L,             "li",           setNumericProperty,     state.layout.leftIndent, 0 ),
171
 
        PROP(   0L,             "line",         insertSymbol,           0L, 0x000a ),
172
 
        PROP(   0L,             "lquote",       insertSymbol,           0L, 0x2018 ),
173
 
        PROP(   0L,             "ltrmark",      insertSymbol,           0L, 0x200e ),
174
 
        PROP(   0L,             "mac",  setMacCodepage,         0L, 0 ),
175
 
        PROP(   "@pict",        "macpict",      setPictureType,         0L, RTFPicture::MacPict ),
176
 
        MEMBER( "@rtf",         "margb",        setNumericProperty,     bottomMargin, 0 ),
177
 
        MEMBER( "@rtf",         "margl",        setNumericProperty,     leftMargin, 0 ),
178
 
        MEMBER( "@rtf",         "margr",        setNumericProperty,     rightMargin, 0 ),
179
 
        MEMBER( "@rtf",         "margt",        setNumericProperty,     topMargin, 0 ),
180
 
        MEMBER( 0L,             "nosupersub",   setEnumProperty,        state.format.vertAlign, RTFFormat::Normal ),
181
 
        PROP(   "Text",         "page",         insertPageBreak,        0L, 0 ),
182
 
        MEMBER( 0L,             "pagebb",       setFlagProperty,        state.layout.pageBB, true ),
183
 
        MEMBER( "@rtf",         "paperh",       setNumericProperty,     paperHeight, 0 ),
184
 
        MEMBER( "@rtf",         "paperw",       setNumericProperty,     paperWidth, 0 ),
185
 
        PROP(   "Text",         "par",          insertParagraph,        0L, 0 ),
186
 
        PROP(   0L,             "pard",         setParagraphDefaults,   0L, 0 ),
187
 
        PROP(   0L,             "pc",   setPcCodepage,          0L, 0 ),
188
 
        PROP(   0L,             "pca",  setPcaCodepage,         0L, 0 ),
189
 
        MEMBER( 0L,             "pgbrk",        setToggleProperty,      state.layout.pageBA, true ),
190
 
        MEMBER( "@pict",        "piccropb",     setNumericProperty,     picture.cropBottom, 0 ),
191
 
        MEMBER( "@pict",        "piccropl",     setNumericProperty,     picture.cropLeft, 0 ),
192
 
        MEMBER( "@pict",        "piccropr",     setNumericProperty,     picture.cropRight, 0 ),
193
 
        MEMBER( "@pict",        "piccropt",     setNumericProperty,     picture.cropTop, 0 ),
194
 
        MEMBER( "@pict",        "pich",         setNumericProperty,     picture.height, 0 ),
195
 
        MEMBER( "@pict",        "pichgoal",     setNumericProperty,     picture.desiredHeight, 0 ),
196
 
        MEMBER( "@pict",        "picscaled",    setFlagProperty,        picture.scaled, true ),
197
 
        MEMBER( "@pict",        "picscalex",    setNumericProperty,     picture.scalex, 0 ),
198
 
        MEMBER( "@pict",        "picscaley",    setNumericProperty,     picture.scaley, 0 ),
199
 
        MEMBER( "@pict",        "picw",         setNumericProperty,     picture.width, 0 ),
200
 
        MEMBER( "@pict",        "picwgoal",     setNumericProperty,     picture.desiredWidth, 0 ),
201
 
        PROP(   0L,             "plain",        setPlainFormatting,     0L, 0 ),
202
 
        PROP(   "@pict",        "pmmetafile",   setPictureType,         0L, RTFPicture::WMF ),
203
 
        PROP(   "@pict",        "pngblip",      setPictureType,         0L, RTFPicture::PNG ),
204
 
        MEMBER( 0L,             "qc",           setEnumProperty,        state.layout.alignment, RTFLayout::Centered ),
205
 
        MEMBER( 0L,             "qj",           setEnumProperty,        state.layout.alignment, RTFLayout::Justified ),
206
 
        MEMBER( 0L,             "ql",           setEnumProperty,        state.layout.alignment, RTFLayout::Left ),
207
 
        PROP(   0L,             "qmspace",      insertSymbol,           0L, 0x2004 ),
208
 
        MEMBER( 0L,             "qr",           setEnumProperty,        state.layout.alignment, RTFLayout::Right ),
209
 
        PROP(   0L,             "rdblquote",    insertSymbol,           0L, 0x201d ),
210
 
        MEMBER( "@colortbl",    "red",          setNumericProperty,     red, 0 ),
211
 
        MEMBER( 0L,             "ri",           setNumericProperty,     state.layout.rightIndent, 0 ),
212
 
        PROP(   "Text",         "row",          insertTableRow,         0L, 0 ),
213
 
        PROP(   0L,             "rquote",       insertSymbol,           0L, 0x2019 ),
214
 
        PROP(   0L,             "rtlmark",      insertSymbol,           0L, 0x200f ),
215
 
        MEMBER( 0L,             "s",            setNumericProperty,     state.layout.style, 0 ),
216
 
        MEMBER( 0L,             "sa",           setNumericProperty,     state.layout.spaceAfter, 0 ),
217
 
        MEMBER( 0L,             "sb",           setNumericProperty,     state.layout.spaceBefore, 0 ),
218
 
        MEMBER( 0L,             "scaps",                setToggleProperty,      state.format.smallCaps, 0 ),
219
 
        PROP(   "Text",         "sect",         insertPageBreak,        0L, 0 ),
220
 
        PROP(   0L,             "sectd",        setSectionDefaults,     0L, 0 ),
221
 
        MEMBER( 0L,             "sl",           setNumericProperty,     state.layout.spaceBetween, 0 ),
222
 
        MEMBER( 0L,             "slmult",       setToggleProperty,      state.layout.spaceBetweenMultiple, 0 ),
223
 
        MEMBER( "@stylesheet",  "snext",        setNumericProperty,     style.next, 0 ),
224
 
        MEMBER( 0L,             "strike",       setToggleProperty,      state.format.strike, 0 ),
225
 
        MEMBER( 0L,             "striked",      setToggleProperty,      state.format.striked, 0 ),
226
 
        MEMBER( 0L,             "sub",          setEnumProperty,        state.format.vertAlign, RTFFormat::SubScript ),
227
 
        MEMBER( 0L,             "super",        setEnumProperty,        state.format.vertAlign, RTFFormat::SuperScript ),
228
 
        PROP(   0L,             "tab",          insertSymbol,           0L, 0x0009 ),
229
 
        MEMBER( 0L,             "titlepg",      setFlagProperty,        state.section.titlePage, true ),
230
 
        MEMBER( 0L,             "tldot",        setEnumProperty,        state.layout.tab.leader, RTFTab::Dots ),
231
 
        MEMBER( 0L,             "tlhyph",       setEnumProperty,        state.layout.tab.leader, RTFTab::Hyphens ),
232
 
        MEMBER( 0L,             "tlth",         setEnumProperty,        state.layout.tab.leader, RTFTab::ThickLine ),
233
 
        MEMBER( 0L,             "tlul",         setEnumProperty,        state.layout.tab.leader, RTFTab::Underline ),
234
 
        MEMBER( 0L,             "tqc",          setEnumProperty,        state.layout.tab.type, RTFTab::Centered ),
235
 
        MEMBER( 0L,             "tqdec",        setEnumProperty,        state.layout.tab.type, RTFTab::Decimal ),
236
 
        MEMBER( 0L,             "tqr",          setEnumProperty,        state.layout.tab.type, RTFTab::FlushRight ),
237
 
        MEMBER( 0L,             "trleft",       setNumericProperty,     state.tableRow.left, 0 ),
238
 
        MEMBER( 0L,             "trowd",        setTableRowDefaults,    state.tableRow, 0 ),
239
 
        MEMBER( 0L,             "trqc",         setEnumProperty,        state.tableRow.alignment, RTFLayout::Centered ),
240
 
        MEMBER( 0L,             "trql",         setEnumProperty,        state.tableRow.alignment, RTFLayout::Left ),
241
 
        MEMBER( 0L,             "trqr",         setEnumProperty,        state.tableRow.alignment, RTFLayout::Right ),
242
 
        MEMBER( 0L,             "trrh",         setNumericProperty,     state.tableRow.height, 0 ),
243
 
        PROP(   0L,             "tx",           insertTabDef,           0L, 0 ),
244
 
        MEMBER( 0L,             "u",            insertUnicodeSymbol,    state.format.uc, 0 ),
245
 
        MEMBER( 0L,             "uc",           setNumericProperty,     state.format.uc, 0 ),
246
 
        PROP(   0L,             "ul",           setSimpleUnderlineProperty,     0L, 0 ),
247
 
        MEMBER( 0L,             "ulc",          setNumericProperty,     state.format.underlinecolor, 0 ),
248
 
        PROP(   0L,             "uld",          setUnderlineProperty,   0L, RTFFormat::UnderlineDot ),
249
 
        PROP(   0L,             "uldash",       setUnderlineProperty,   0L, RTFFormat::UnderlineDash ),
250
 
        PROP(   0L,             "uldashd",      setUnderlineProperty,   0L, RTFFormat::UnderlineDashDot ),
251
 
        PROP(   0L,             "uldashdd",     setUnderlineProperty,   0L, RTFFormat::UnderlineDashDotDot ),
252
 
        PROP(   0L,             "uldb",         setUnderlineProperty,   0L, RTFFormat::UnderlineDouble ),
253
 
        PROP(   0L,             "ulnone",       setUnderlineProperty,   0L, RTFFormat::UnderlineNone ),
254
 
        PROP(   0L,             "ulth",         setUnderlineProperty,   0L, RTFFormat::UnderlineThick ),
255
 
        PROP(   0L,             "ulw",          setUnderlineProperty,   0L, RTFFormat::UnderlineWordByWord ),
256
 
        PROP(   0L,             "ulwave",       setUnderlineProperty,   0L, RTFFormat::UnderlineWave ),
257
 
        PROP(   0L,             "ulhwave",      setUnderlineProperty,   0L, RTFFormat::UnderlineWave ),
258
 
        PROP(   0L,             "ululdbwave",   setUnderlineProperty,   0L, RTFFormat::UnderlineWave ),
259
 
        MEMBER( 0L,             "up",           setUpProperty,          state.format.baseline, 6 ),
260
 
        MEMBER( 0L,             "v",            setToggleProperty,      state.format.hidden, 0 ),
261
 
        // ### TODO: \wbitmap: a Windows Device-Dependent Bitmap is not a BMP
262
 
        PROP(   "@pict",        "wbitmap",      setPictureType,         0L, RTFPicture::BMP ),
263
 
        PROP(   "@pict",        "wmetafile",    setPictureType,         0L, RTFPicture::EMF ),
264
 
        PROP(   0L,             "zwj",          insertSymbol,           0L, 0x200d ),
265
 
        PROP(   0L,             "zwnj",         insertSymbol,           0L, 0x200c )
 
81
{
 
82
//  only-valid-in control word function  offset, value
 
83
    PROP("Text",  "\n",  insertParagraph, 0L, 0),
 
84
    PROP("Text",  "\r",  insertParagraph, 0L, 0),
 
85
    PROP(0L,  "\'",  insertHexSymbol, 0L, 0),
 
86
    PROP(0L,  "\\",  insertSymbol,  0L, '\\'),
 
87
    PROP(0L,  "_",  insertSymbol,  0L, 0x2011),
 
88
    PROP(0L,  "{",  insertSymbol,  0L, '{'),
 
89
    PROP(0L,  "|",  insertSymbol,  0L, 0x00b7),
 
90
    PROP(0L,  "}",  insertSymbol,  0L, '}'),
 
91
    PROP(0L,  "~",  insertSymbol,  0L, 0x00a0),
 
92
    PROP(0L,  "-",  insertSymbol,  0L, 0x00ad),
 
93
    PROP(0L,  "adjustright", ignoreKeyword,  0L, 0),   // Not supported, KWord has no grid
 
94
    PROP(0L,  "ansi", setAnsiCodepage,  0L, 0),
 
95
    PROP(0L,  "ansicpg", setCodepage,  0L, 0),
 
96
    MEMBER(0L,  "b",  setToggleProperty, state.format.bold, 0),
 
97
    // \bin is handled in the tokenizer
 
98
    MEMBER("@colortbl", "blue",  setNumericProperty, blue, 0),
 
99
    MEMBER(0L,  "box",  setEnumProperty, state.layout.border, 0),
 
100
    PROP(0L,  "brdrb", selectLayoutBorder, 0L, 3),
 
101
    PROP(0L,  "brdrcf", setBorderColor,           0L, 0),
 
102
    PROP(0L,  "brdrdash", setBorderStyle,  0L, RTFBorder::Dashes),
 
103
    PROP(0L,  "brdrdashd", setBorderStyle,  0L, RTFBorder::DashDot),
 
104
    PROP(0L,  "brdrdashdd", setBorderStyle,  0L, RTFBorder::DashDotDot),
 
105
    PROP(0L,  "brdrdashsm", setBorderStyle,  0L, RTFBorder::Dashes),
 
106
    PROP(0L,  "brdrdb", setBorderStyle,  0L, RTFBorder::Solid),
 
107
    PROP(0L,  "brdrdot", setBorderStyle,  0L, RTFBorder::Dots),
 
108
    PROP(0L,  "brdrhairline", setBorderStyle,  0L, RTFBorder::Solid),
 
109
    PROP(0L,  "brdrl", selectLayoutBorder, 0L, 0),
 
110
    PROP(0L,  "brdrr", selectLayoutBorder, 0L, 1),
 
111
    PROP(0L,  "brdrs", setBorderStyle,  0L, RTFBorder::Solid),
 
112
    PROP(0L,  "brdrsh", setBorderStyle,  0L, RTFBorder::Solid),
 
113
    PROP(0L,  "brdrt", selectLayoutBorder, 0L, 2),
 
114
    PROP(0L,  "brdrth", setBorderStyle,  0L, RTFBorder::Solid),
 
115
    PROP(0L,  "brdrw", setBorderProperty, offsetof(RTFBorder, width), 0),
 
116
    PROP(0L,  "bullet", insertSymbol,  0L, 0x2022),
 
117
    PROP(0L,  "brsp",  setBorderProperty, offsetof(RTFBorder, space), 0),
 
118
    MEMBER(0L,  "caps",  setToggleProperty, state.format.caps, 0),
 
119
    MEMBER(0L,  "cb",  setNumericProperty, state.format.bgcolor, 0),
 
120
    MEMBER(0L,  "highlight", setNumericProperty, state.format.bgcolor, 0),
 
121
    PROP("Text",  "cell",  insertTableCell, 0L, 0),
 
122
    PROP(0L,  "cellx", insertCellDef,  0L, 0),
 
123
    MEMBER(0L,  "cf",  setNumericProperty, state.format.color, 0),
 
124
    PROP(0L,  "chdate", insertDateTime,  0L, true),
 
125
    PROP(0L,  "chpgn", insertPageNumber,  0L, 0),
 
126
    PROP(0L,  "chtime", insertDateTime,  0L, false),
 
127
    PROP(0L,  "clbrdrb", selectLayoutBorderFromCell, 0L, 3),
 
128
    PROP(0L,  "clbrdrl", selectLayoutBorderFromCell, 0L, 0),
 
129
    PROP(0L,  "clbrdrr", selectLayoutBorderFromCell, 0L, 1),
 
130
    PROP(0L,  "clbrdrt", selectLayoutBorderFromCell, 0L, 2),
 
131
    MEMBER(0L,  "clcbpat", setNumericProperty, state.tableCell.bgcolor, 0),
 
132
    PROP(0L,  "cs", ignoreKeyword,  0L, 0),   // Not supported by KWord 1.3
 
133
    PROP(0L,  "datafield", skipGroup,  0L, 0),   // Binary data in variables are not supported
 
134
    MEMBER("@rtf",  "deff",  setNumericProperty, defaultFont, 0),
 
135
    MEMBER("@rtf",  "deftab", setNumericProperty, defaultTab, 0),
 
136
    PROP("@pict", "dibitmap", setPictureType,         0L, RTFPicture::BMP),
 
137
    MEMBER(0L,  "dn",  setNumericProperty, state.format.baseline, 6),
 
138
    PROP(0L,  "emdash", insertSymbol,  0L, 0x2014),
 
139
    PROP("@pict", "emfblip", setPictureType,         0L, RTFPicture::EMF),
 
140
    PROP(0L,  "emspace", insertSymbol,  0L, 0x2003),
 
141
    PROP(0L,  "endash", insertSymbol,  0L, 0x2013),
 
142
    PROP(0L,  "enspace", insertSymbol,  0L, 0x2002),
 
143
    PROP(0L,  "expnd", ignoreKeyword,  0L, 0),   // Expansion/compression of character inter-space not supported
 
144
    PROP(0L,  "expndtw", ignoreKeyword,  0L, 0),   // Expansion/compression of character inter-space not supported
 
145
    MEMBER(0L,  "f",  setNumericProperty, state.format.font, 0),
 
146
    MEMBER("@rtf",  "facingp", setFlagProperty, facingPages, true),
 
147
    PROP(0L,  "fcharset", setCharset,  0L, 0),   // Not needed with Qt
 
148
    PROP("@fonttbl", "fdecor", setFontStyleHint, 0L, QFont::Decorative),
 
149
    MEMBER(0L,  "fi",  setNumericProperty, state.layout.firstIndent, 0),
 
150
    PROP("@fonttbl", "fmodern", setFontStyleHint, 0L, QFont::TypeWriter),
 
151
    PROP("@fonttbl", "fnil",  setFontStyleHint, 0L, QFont::AnyStyle),
 
152
    MEMBER(0L,  "footery", setNumericProperty, state.section.footerMargin, 0),
 
153
    PROP(0L,  "formshade", ignoreKeyword,  0L, 0),   // Not supported, KWord has no form support
 
154
    MEMBER("@fonttbl", "fprq",  setNumericProperty, font.fixedPitch, 0),
 
155
    PROP("@fonttbl", "froman", setFontStyleHint, 0L, QFont::Serif),
 
156
    MEMBER(0L,  "fs",  setNumericProperty, state.format.fontSize, 0),
 
157
    PROP("@fonttbl", "fscript", setFontStyleHint, 0L, QFont::AnyStyle),
 
158
    PROP("@fonttbl", "fswiss", setFontStyleHint, 0L, QFont::SansSerif),
 
159
    PROP("@fonttbl", "ftech", setFontStyleHint, 0L, QFont::AnyStyle),
 
160
    MEMBER("@colortbl", "green", setNumericProperty, green, 0),
 
161
    MEMBER(0L,  "headery", setNumericProperty, state.section.headerMargin, 0),
 
162
    MEMBER(0L,  "i",  setToggleProperty, state.format.italic, 0),
 
163
    MEMBER(0L,  "intbl", setFlagProperty, state.layout.inTable, true),
 
164
    PROP("@pict", "jpegblip", setPictureType,         0L, RTFPicture::JPEG),
 
165
    MEMBER(0L,  "keep",  setFlagProperty, state.layout.keep, true),
 
166
    MEMBER(0L,  "keepn", setFlagProperty, state.layout.keepNext, true),
 
167
    MEMBER("@rtf",  "landscape", setFlagProperty, landscape, true),
 
168
    PROP(0L,  "ldblquote", insertSymbol,  0L, 0x201c),
 
169
    MEMBER(0L,  "li",  setNumericProperty, state.layout.leftIndent, 0),
 
170
    PROP(0L,  "line",  insertSymbol,  0L, 0x000a),
 
171
    PROP(0L,  "lquote", insertSymbol,  0L, 0x2018),
 
172
    PROP(0L,  "ltrmark", insertSymbol,  0L, 0x200e),
 
173
    PROP(0L,  "mac", setMacCodepage,  0L, 0),
 
174
    PROP("@pict", "macpict", setPictureType,         0L, RTFPicture::MacPict),
 
175
    MEMBER("@rtf",  "margb", setNumericProperty, bottomMargin, 0),
 
176
    MEMBER("@rtf",  "margl", setNumericProperty, leftMargin, 0),
 
177
    MEMBER("@rtf",  "margr", setNumericProperty, rightMargin, 0),
 
178
    MEMBER("@rtf",  "margt", setNumericProperty, topMargin, 0),
 
179
    MEMBER(0L,  "nosupersub", setEnumProperty, state.format.vertAlign, RTFFormat::Normal),
 
180
    PROP("Text",  "page",  insertPageBreak, 0L, 0),
 
181
    MEMBER(0L,  "pagebb", setFlagProperty, state.layout.pageBB, true),
 
182
    MEMBER("@rtf",  "paperh", setNumericProperty, paperHeight, 0),
 
183
    MEMBER("@rtf",  "paperw", setNumericProperty, paperWidth, 0),
 
184
    PROP("Text",  "par",  insertParagraph, 0L, 0),
 
185
    PROP(0L,  "pard",  setParagraphDefaults, 0L, 0),
 
186
    PROP(0L,  "pc", setPcCodepage,  0L, 0),
 
187
    PROP(0L,  "pca", setPcaCodepage,  0L, 0),
 
188
    MEMBER(0L,  "pgbrk", setToggleProperty, state.layout.pageBA, true),
 
189
    MEMBER("@pict", "piccropb", setNumericProperty, picture.cropBottom, 0),
 
190
    MEMBER("@pict", "piccropl", setNumericProperty, picture.cropLeft, 0),
 
191
    MEMBER("@pict", "piccropr", setNumericProperty, picture.cropRight, 0),
 
192
    MEMBER("@pict", "piccropt", setNumericProperty, picture.cropTop, 0),
 
193
    MEMBER("@pict", "pich",  setNumericProperty, picture.height, 0),
 
194
    MEMBER("@pict", "pichgoal", setNumericProperty, picture.desiredHeight, 0),
 
195
    MEMBER("@pict", "picscaled", setFlagProperty, picture.scaled, true),
 
196
    MEMBER("@pict", "picscalex", setNumericProperty, picture.scalex, 0),
 
197
    MEMBER("@pict", "picscaley", setNumericProperty, picture.scaley, 0),
 
198
    MEMBER("@pict", "picw",  setNumericProperty, picture.width, 0),
 
199
    MEMBER("@pict", "picwgoal", setNumericProperty, picture.desiredWidth, 0),
 
200
    PROP(0L,  "plain", setPlainFormatting, 0L, 0),
 
201
    PROP("@pict", "pmmetafile", setPictureType,         0L, RTFPicture::WMF),
 
202
    PROP("@pict", "pngblip", setPictureType,         0L, RTFPicture::PNG),
 
203
    MEMBER(0L,  "qc",  setEnumProperty, state.layout.alignment, RTFLayout::Centered),
 
204
    MEMBER(0L,  "qj",  setEnumProperty, state.layout.alignment, RTFLayout::Justified),
 
205
    MEMBER(0L,  "ql",  setEnumProperty, state.layout.alignment, RTFLayout::Left),
 
206
    PROP(0L,  "qmspace", insertSymbol,  0L, 0x2004),
 
207
    MEMBER(0L,  "qr",  setEnumProperty, state.layout.alignment, RTFLayout::Right),
 
208
    PROP(0L,  "rdblquote", insertSymbol,  0L, 0x201d),
 
209
    MEMBER("@colortbl", "red",  setNumericProperty, red, 0),
 
210
    MEMBER(0L,  "ri",  setNumericProperty, state.layout.rightIndent, 0),
 
211
    PROP("Text",  "row",  insertTableRow,  0L, 0),
 
212
    PROP(0L,  "rquote", insertSymbol,  0L, 0x2019),
 
213
    PROP(0L,  "rtlmark", insertSymbol,  0L, 0x200f),
 
214
    MEMBER(0L,  "s",  setNumericProperty, state.layout.style, 0),
 
215
    MEMBER(0L,  "sa",  setNumericProperty, state.layout.spaceAfter, 0),
 
216
    MEMBER(0L,  "sb",  setNumericProperty, state.layout.spaceBefore, 0),
 
217
    MEMBER(0L,  "scaps",  setToggleProperty, state.format.smallCaps, 0),
 
218
    PROP("Text",  "sect",  insertPageBreak, 0L, 0),
 
219
    PROP(0L,  "sectd", setSectionDefaults, 0L, 0),
 
220
    MEMBER(0L,  "sl",  setNumericProperty, state.layout.spaceBetween, 0),
 
221
    MEMBER(0L,  "slmult", setToggleProperty, state.layout.spaceBetweenMultiple, 0),
 
222
    MEMBER("@stylesheet", "snext", setNumericProperty, style.next, 0),
 
223
    MEMBER(0L,  "strike", setToggleProperty, state.format.strike, 0),
 
224
    MEMBER(0L,  "striked", setToggleProperty, state.format.striked, 0),
 
225
    MEMBER(0L,  "sub",  setEnumProperty, state.format.vertAlign, RTFFormat::SubScript),
 
226
    MEMBER(0L,  "super", setEnumProperty, state.format.vertAlign, RTFFormat::SuperScript),
 
227
    PROP(0L,  "tab",  insertSymbol,  0L, 0x0009),
 
228
    MEMBER(0L,  "titlepg", setFlagProperty, state.section.titlePage, true),
 
229
    MEMBER(0L,  "tldot", setEnumProperty, state.layout.tab.leader, RTFTab::Dots),
 
230
    MEMBER(0L,  "tlhyph", setEnumProperty, state.layout.tab.leader, RTFTab::Hyphens),
 
231
    MEMBER(0L,  "tlth",  setEnumProperty, state.layout.tab.leader, RTFTab::ThickLine),
 
232
    MEMBER(0L,  "tlul",  setEnumProperty, state.layout.tab.leader, RTFTab::Underline),
 
233
    MEMBER(0L,  "tqc",  setEnumProperty, state.layout.tab.type, RTFTab::Centered),
 
234
    MEMBER(0L,  "tqdec", setEnumProperty, state.layout.tab.type, RTFTab::Decimal),
 
235
    MEMBER(0L,  "tqr",  setEnumProperty, state.layout.tab.type, RTFTab::FlushRight),
 
236
    MEMBER(0L,  "trleft", setNumericProperty, state.tableRow.left, 0),
 
237
    MEMBER(0L,  "trowd", setTableRowDefaults, state.tableRow, 0),
 
238
    MEMBER(0L,  "trqc",  setEnumProperty, state.tableRow.alignment, RTFLayout::Centered),
 
239
    MEMBER(0L,  "trql",  setEnumProperty, state.tableRow.alignment, RTFLayout::Left),
 
240
    MEMBER(0L,  "trqr",  setEnumProperty, state.tableRow.alignment, RTFLayout::Right),
 
241
    MEMBER(0L,  "trrh",  setNumericProperty, state.tableRow.height, 0),
 
242
    PROP(0L,  "tx",  insertTabDef,  0L, 0),
 
243
    MEMBER(0L,  "u",  insertUnicodeSymbol, state.format.uc, 0),
 
244
    MEMBER(0L,  "uc",  setNumericProperty, state.format.uc, 0),
 
245
    PROP(0L,  "ul",  setSimpleUnderlineProperty, 0L, 0),
 
246
    MEMBER(0L,  "ulc",  setNumericProperty, state.format.underlinecolor, 0),
 
247
    PROP(0L,  "uld",  setUnderlineProperty, 0L, RTFFormat::UnderlineDot),
 
248
    PROP(0L,  "uldash", setUnderlineProperty, 0L, RTFFormat::UnderlineDash),
 
249
    PROP(0L,  "uldashd", setUnderlineProperty, 0L, RTFFormat::UnderlineDashDot),
 
250
    PROP(0L,  "uldashdd", setUnderlineProperty, 0L, RTFFormat::UnderlineDashDotDot),
 
251
    PROP(0L,  "uldb",  setUnderlineProperty, 0L, RTFFormat::UnderlineDouble),
 
252
    PROP(0L,  "ulnone", setUnderlineProperty, 0L, RTFFormat::UnderlineNone),
 
253
    PROP(0L,  "ulth",  setUnderlineProperty, 0L, RTFFormat::UnderlineThick),
 
254
    PROP(0L,  "ulw",  setUnderlineProperty, 0L, RTFFormat::UnderlineWordByWord),
 
255
    PROP(0L,  "ulwave", setUnderlineProperty, 0L, RTFFormat::UnderlineWave),
 
256
    PROP(0L,  "ulhwave", setUnderlineProperty, 0L, RTFFormat::UnderlineWave),
 
257
    PROP(0L,  "ululdbwave", setUnderlineProperty, 0L, RTFFormat::UnderlineWave),
 
258
    MEMBER(0L,  "up",  setUpProperty,  state.format.baseline, 6),
 
259
    MEMBER(0L,  "v",  setToggleProperty, state.format.hidden, 0),
 
260
    // ### TODO: \wbitmap: a Windows Device-Dependent Bitmap is not a BMP
 
261
    PROP("@pict", "wbitmap", setPictureType,         0L, RTFPicture::BMP),
 
262
    PROP("@pict", "wmetafile", setPictureType,         0L, RTFPicture::EMF),
 
263
    PROP(0L,  "zwj",  insertSymbol,  0L, 0x200d),
 
264
    PROP(0L,  "zwnj",  insertSymbol,  0L, 0x200c)
266
265
};
267
266
 
268
 
static RTFField fieldTable[] =
269
 
    {
270
 
//        id             type  subtype  default value
271
 
        { "AUTHOR",      8,    2,       "NO AUTHOR" },
272
 
        { "FILENAME",    8,    0,       "NO FILENAME" },
273
 
        { "TITLE",       8,   10,       "NO TITLE" },
274
 
        { "NUMPAGES",    4,    1,       0 },
275
 
        { "PAGE",        4,    0,       0 },
276
 
        { "TIME",       -1,   -1,       0 },
277
 
        { "DATE",       -1,   -1,       0 },
278
 
        { "HYPERLINK",   9,   -1,       0 },
279
 
        { "SYMBOL",     -1,   -1,       0 },
280
 
        { "IMPORT",     -1,   -1,       0 }
 
267
static RTFField fieldTable[] = {
 
268
//   id   type  subtype  default value
 
269
    { "AUTHOR",  8,    2, "NO AUTHOR" },
 
270
    { "FILENAME",  8,    0, "NO FILENAME" },
 
271
    { "TITLE",  8,   10, "NO TITLE" },
 
272
    { "NUMPAGES",  4,    1, 0 },
 
273
    { "PAGE",  4,    0, 0 },
 
274
    { "TIME", -1,   -1, 0 },
 
275
    { "DATE", -1,   -1, 0 },
 
276
    { "HYPERLINK",  9,   -1, 0 },
 
277
    { "SYMBOL", -1,   -1, 0 },
 
278
    { "IMPORT", -1,   -1, 0 }
281
279
};
282
280
 
283
281
 
284
282
// KWord attributes
285
 
static const char *alignN[4]    = { "left", "right", "justify", "center" };
286
 
static const char *boolN[2]     = { "false", "true" };
287
 
static const char *borderN[4]   = { "LEFTBORDER", "RIGHTBORDER", "TOPBORDER", "BOTTOMBORDER" };
 
283
static const char *alignN[4] = { "left", "right", "justify", "center" };
 
284
static const char *boolN[2] = { "false", "true" };
 
285
static const char *borderN[4] = { "LEFTBORDER", "RIGHTBORDER", "TOPBORDER", "BOTTOMBORDER" };
288
286
 
289
 
RTFImport::RTFImport( QObject* parent, const QStringList& )
290
 
    : KoFilter(parent)
291
 
    , textCodec(0)
292
 
    , utf8TextCodec(0)
 
287
RTFImport::RTFImport(QObject* parent, const QStringList&)
 
288
        : KoFilter(parent)
 
289
        , textCodec(0)
 
290
        , utf8TextCodec(0)
293
291
{
294
 
    for (uint i=0; i < sizeof(propertyTable) / sizeof(propertyTable[0]); i++)
295
 
    {
296
 
        properties.insert( propertyTable[i].name, &propertyTable[i] );
 
292
    for (uint i = 0; i < sizeof(propertyTable) / sizeof(propertyTable[0]); i++) {
 
293
        properties.insert(propertyTable[i].name, &propertyTable[i]);
297
294
    }
298
 
    for (uint i=0; i < sizeof(destinationPropertyTable) / sizeof(destinationPropertyTable[0]); i++)
299
 
    {
300
 
        destinationProperties.insert( destinationPropertyTable[i].name, &destinationPropertyTable[i] );
 
295
    for (uint i = 0; i < sizeof(destinationPropertyTable) / sizeof(destinationPropertyTable[0]); i++) {
 
296
        destinationProperties.insert(destinationPropertyTable[i].name, &destinationPropertyTable[i]);
301
297
    }
302
298
    // DEBUG START
303
299
    // Check the hash size (see QDict doc)
304
 
    kDebug(30515) << properties.count() <<" normal and" << destinationProperties.count() <<" destination keywords loaded";
 
300
    kDebug(30515) << properties.count() << " normal and" << destinationProperties.count() << " destination keywords loaded";
305
301
    if (properties.size() < properties.count())
306
302
        kWarning(30515) << "Hash size of properties too small: " << properties.size() << ". It should be at least " << properties.count() << " and be a prime number";
307
303
    if (destinationProperties.size() < destinationProperties.count())
308
304
        kWarning(30515) << "Hash size of destinationProperties too small: " << destinationProperties.size() << ". It should be at least " << destinationProperties.count() << " and be a prime number";
309
305
    // DEBUG END
310
 
    fnnum=0;
 
306
    fnnum = 0;
311
307
}
312
308
 
313
 
KoFilter::ConversionStatus RTFImport::convert( const QByteArray& from, const QByteArray& to )
 
309
KoFilter::ConversionStatus RTFImport::convert(const QByteArray& from, const QByteArray& to)
314
310
{
315
311
    // This filter only supports RTF to KWord conversion
316
312
    if ((from != "application/rtf") || (to != "application/x-kword"))
320
316
    debugTime.start();
321
317
 
322
318
    // Are we in batch mode, i.e. non-interactive
323
 
    m_batch=false;
324
 
    if ( m_chain->manager() )
 
319
    m_batch = false;
 
320
    if (m_chain->manager())
325
321
        m_batch = m_chain->manager()->getBatchMode();
326
322
 
327
323
    // Open input file
328
324
    inFileName = m_chain->inputFile();
329
 
    QFile in( inFileName );
 
325
    QFile in(inFileName);
330
326
 
331
 
    if (!in.open( QIODevice::ReadOnly ))
332
 
    {
 
327
    if (!in.open(QIODevice::ReadOnly)) {
333
328
        kError(30515) << "Unable to open input file!";
334
329
        in.close();
335
 
        if ( !m_batch )
336
 
        {
337
 
            KMessageBox::error( 0L,
338
 
                i18n("The file cannot be loaded, as it cannot be opened."),
339
 
                i18n("KWord's RTF Import Filter"), 0 );
 
330
        if (!m_batch) {
 
331
            KMessageBox::error(0L,
 
332
                               i18n("The file cannot be loaded, as it cannot be opened."),
 
333
                               i18n("KWord's RTF Import Filter"), 0);
340
334
        }
341
335
        return KoFilter::FileNotFound;
342
336
    }
343
337
 
344
338
    // Document should start with an opening brace
345
 
    token.open( &in );
 
339
    token.open(&in);
346
340
    token.next();
347
341
 
348
 
    if (token.type != RTFTokenizer::OpenGroup)
349
 
    {
 
342
    if (token.type != RTFTokenizer::OpenGroup) {
350
343
        kError(30515) << "Not an RTF file";
351
344
        in.close();
352
 
        if ( !m_batch )
353
 
        {
354
 
            KMessageBox::error( 0L,
355
 
                i18n("The file cannot be loaded, as it seems not to be an RTF document."),
356
 
                i18n("KWord's RTF Import Filter"), 0 );
 
345
        if (!m_batch) {
 
346
            KMessageBox::error(0L,
 
347
                               i18n("The file cannot be loaded, as it seems not to be an RTF document."),
 
348
                               i18n("KWord's RTF Import Filter"), 0);
357
349
        }
358
350
        return KoFilter::WrongFormat;
359
351
    }
362
354
 
363
355
    token.next();
364
356
 
365
 
    if (token.type != RTFTokenizer::ControlWord)
366
 
    {
 
357
    if (token.type != RTFTokenizer::ControlWord) {
367
358
        kError(30515) << "Wrong document type";
368
359
        in.close();
369
 
        if ( !m_batch )
370
 
        {
371
 
            KMessageBox::error( 0L,
372
 
                i18n("The document cannot be loaded, as it seems not to follow the RTF syntax."),
373
 
                i18n("KWord's RTF Import Filter"), 0 );
 
360
        if (!m_batch) {
 
361
            KMessageBox::error(0L,
 
362
                               i18n("The document cannot be loaded, as it seems not to follow the RTF syntax."),
 
363
                               i18n("KWord's RTF Import Filter"), 0);
374
364
        }
375
365
        return KoFilter::WrongFormat;
376
366
    }
377
367
 
378
368
    bool force = false; // By default do not force, despite an unknown keyword or version
379
 
    if ( !qstrcmp( token.text, "rtf" ) )
380
 
    {
 
369
    if (!qstrcmp(token.text, "rtf")) {
381
370
        // RTF is normally version 1 but at least Ted uses 0 as version number
382
 
        if ( token.value > 1 )
383
 
        {
 
371
        if (token.value > 1) {
384
372
            kError(30515) << "Wrong RTF version (" << token.value << "); version 0 or 1 expected";
385
 
            if ( !m_batch )
386
 
            {
387
 
                force = ( KMessageBox::warningYesNo( 0L,
388
 
                    i18n("The RTF (Rich Text Format) document has an unexpected version number: %1. Continuing might result in an erroneous conversion. Do you want to continue?", token.value ),
389
 
                    i18n("KWord's RTF Import Filter") ) == KMessageBox::Yes );
 
373
            if (!m_batch) {
 
374
                force = (KMessageBox::warningYesNo(0L,
 
375
                                                   i18n("The RTF (Rich Text Format) document has an unexpected version number: %1. Continuing might result in an erroneous conversion. Do you want to continue?", token.value),
 
376
                                                   i18n("KWord's RTF Import Filter")) == KMessageBox::Yes);
390
377
            }
391
 
            if ( !force )
392
 
            {
 
378
            if (!force) {
393
379
                in.close();
394
380
                return KoFilter::WrongFormat;
395
381
            }
396
382
        }
397
 
    }
398
 
    else if ( !qstrcmp( token.text, "pwd" ) )
399
 
    {
 
383
    } else if (!qstrcmp(token.text, "pwd")) {
400
384
        // PocketWord's PWD format is similar to RTF but has a version number of 2.
401
 
        if ( token.value != 2 )
402
 
        {
 
385
        if (token.value != 2) {
403
386
            kError(30515) << "Wrong PWD version (" << token.value << "); version 2 expected";
404
 
            if ( !m_batch )
405
 
            {
406
 
                force = ( KMessageBox::warningYesNo( 0L,
407
 
                    i18n("The PWD (PocketWord's Rich Text Format) document has an unexpected version number: %1. Continuing might result in an erroneous conversion. Do you want to continue?", token.value ),
408
 
                    i18n("KWord's RTF Import Filter") ) == KMessageBox::Yes );
 
387
            if (!m_batch) {
 
388
                force = (KMessageBox::warningYesNo(0L,
 
389
                                                   i18n("The PWD (PocketWord's Rich Text Format) document has an unexpected version number: %1. Continuing might result in an erroneous conversion. Do you want to continue?", token.value),
 
390
                                                   i18n("KWord's RTF Import Filter")) == KMessageBox::Yes);
409
391
            }
410
 
            if ( !force )
411
 
            {
 
392
            if (!force) {
412
393
                in.close();
413
394
                return KoFilter::WrongFormat;
414
395
            }
415
396
        }
416
 
    }
417
 
    else if ( !qstrcmp( token.text, "urtf" ) )
418
 
    {
 
397
    } else if (!qstrcmp(token.text, "urtf")) {
419
398
        // URTF seems to have either no version or having version 1
420
 
        if ( token.value > 1 )
421
 
        {
 
399
        if (token.value > 1) {
422
400
            kError(30515) << "Wrong URTF version (" << token.value << "); version 0 or 1 expected";
423
 
            if ( !m_batch )
424
 
            {
425
 
                force = ( KMessageBox::warningYesNo( 0L,
426
 
                    i18n("The URTF (\"Unicode Rich Text Format\") document has an unexpected version number: %1. Continuing might result in an erroneous conversion. Do you want to continue?", token.value ),
427
 
                    i18n("KWord's RTF Import Filter") ) == KMessageBox::Yes );
 
401
            if (!m_batch) {
 
402
                force = (KMessageBox::warningYesNo(0L,
 
403
                                                   i18n("The URTF (\"Unicode Rich Text Format\") document has an unexpected version number: %1. Continuing might result in an erroneous conversion. Do you want to continue?", token.value),
 
404
                                                   i18n("KWord's RTF Import Filter")) == KMessageBox::Yes);
428
405
            }
429
 
            if ( !force )
430
 
            {
 
406
            if (!force) {
431
407
                in.close();
432
408
                return KoFilter::WrongFormat;
433
409
            }
434
410
        }
435
 
    }
436
 
    else
437
 
    {
 
411
    } else {
438
412
        kError(30515) << "Wrong RTF document type (\\" << token.text << "); \\rtf, \\pwd or \\urtf expected";
439
413
        in.close();
440
 
        if ( !m_batch )
441
 
        {
442
 
            KMessageBox::error( 0L,
443
 
                i18n("The RTF document cannot be loaded, as it has an unexpected first keyword: \\%1.",token.text ),
444
 
                i18n("KWord's RTF Import Filter"), 0 );
 
414
        if (!m_batch) {
 
415
            KMessageBox::error(0L,
 
416
                               i18n("The RTF document cannot be loaded, as it has an unexpected first keyword: \\%1.", token.text),
 
417
                               i18n("KWord's RTF Import Filter"), 0);
445
418
        }
446
419
        return KoFilter::WrongFormat;
447
420
    }
448
421
 
449
 
    table       = 0;
450
 
    pictureNumber       = 0;
 
422
    table = 0;
 
423
    pictureNumber = 0;
451
424
 
452
425
    // Document-formatting properties
453
 
    paperWidth  = 12240;
454
 
    paperHeight = 15840;
455
 
    leftMargin  = 1800;
456
 
    topMargin   = 1440;
457
 
    rightMargin = 1800;
458
 
    bottomMargin= 1440;
459
 
    defaultTab  = 720;
460
 
    defaultFont = 0;
461
 
    landscape   = false;
462
 
    facingPages = false;
 
426
    paperWidth = 12240;
 
427
    paperHeight = 15840;
 
428
    leftMargin = 1800;
 
429
    topMargin = 1440;
 
430
    rightMargin = 1800;
 
431
    bottomMargin = 1440;
 
432
    defaultTab = 720;
 
433
    defaultFont = 0;
 
434
    landscape = false;
 
435
    facingPages = false;
463
436
 
464
437
    // Create main document
465
 
    frameSets.clear( 2 );
 
438
    frameSets.clear(2);
466
439
    pictures.clear();
467
 
    bodyText.node.clear( 3 );
468
 
    firstPageHeader.node.clear( 3 );
469
 
    oddPagesHeader.node.clear( 3 );
470
 
    evenPagesHeader.node.clear( 3 );
471
 
    firstPageFooter.node.clear( 3 );
472
 
    oddPagesFooter.node.clear( 3 );
473
 
    evenPagesFooter.node.clear( 3 );
 
440
    bodyText.node.clear(3);
 
441
    firstPageHeader.node.clear(3);
 
442
    oddPagesHeader.node.clear(3);
 
443
    evenPagesHeader.node.clear(3);
 
444
    firstPageFooter.node.clear(3);
 
445
    oddPagesFooter.node.clear(3);
 
446
    evenPagesFooter.node.clear(3);
474
447
    author.clear();
475
448
    company.clear();
476
449
    title.clear();
477
450
    doccomm.clear();
478
451
 
479
 
    stateStack.push( state );
 
452
    stateStack.push(state);
480
453
 
481
454
    // Add a security item for the destination stack
482
455
    destination.name = "!stackbottom";
483
456
 
484
 
    changeDestination( destinationProperties["@rtf"] );
 
457
    changeDestination(destinationProperties["@rtf"]);
485
458
 
486
459
    flddst = -1;
487
460
    emptyCell = state.tableCell;
488
 
    state.format.uc=1;
 
461
    state.format.uc = 1;
489
462
    state.ignoreGroup = false;
490
463
 
491
 
    utf8TextCodec=QTextCodec::codecForName("UTF-8");
492
 
    kDebug(30515) <<"UTF-8 asked, given:" << (utf8TextCodec?utf8TextCodec->name():QString("-none-"));
 
464
    utf8TextCodec = QTextCodec::codecForName("UTF-8");
 
465
    kDebug(30515) << "UTF-8 asked, given:" << (utf8TextCodec ? utf8TextCodec->name() : QString("-none-"));
493
466
 
494
467
    // There is no default encoding in RTF, it must be always declared. (But beware of buggy files!)
495
 
    textCodec=QTextCodec::codecForName("CP 1252"); // Or IBM 437 ?
496
 
    kDebug(30515) <<"CP 1252 asked, given:" << (textCodec?textCodec->name():QString("-none-"));
 
468
    textCodec = QTextCodec::codecForName("CP 1252"); // Or IBM 437 ?
 
469
    kDebug(30515) << "CP 1252 asked, given:" << (textCodec ? textCodec->name() : QString("-none-"));
497
470
 
498
471
    // Parse RTF document
499
 
    while (true)
500
 
    {
 
472
    while (true) {
501
473
        bool firstToken = false;
502
474
        bool ignoreUnknown = false;
503
475
 
504
476
        token.next();
505
477
 
506
 
        while (token.type == RTFTokenizer::OpenGroup)
507
 
        {
 
478
        while (token.type == RTFTokenizer::OpenGroup) {
508
479
            // Store the current state on the stack
509
 
            stateStack.push( state );
 
480
            stateStack.push(state);
510
481
            state.brace0 = false;
511
482
            firstToken = true;
512
483
            ignoreUnknown = false;
513
484
 
514
485
            token.next();
515
486
 
516
 
            if (token.type == RTFTokenizer::ControlWord && !qstrcmp( token.text, "*" ))
517
 
            {
 
487
            if (token.type == RTFTokenizer::ControlWord && !qstrcmp(token.text, "*")) {
518
488
                // {\*\control ...} destination
519
489
                ignoreUnknown = true;
520
490
                token.next();
521
491
            }
522
492
        }
523
 
        if (token.type == RTFTokenizer::CloseGroup)
524
 
        {
525
 
            if (state.brace0)
526
 
            {
 
493
        if (token.type == RTFTokenizer::CloseGroup) {
 
494
            if (state.brace0) {
527
495
                // Close the current destination
528
496
                (this->*destination.destproc)(0L);
529
497
                //kDebug(30515) <<"Closing destination..." << destinationStack.count();
530
 
                if (destinationStack.isEmpty())
531
 
                {
 
498
                if (destinationStack.isEmpty()) {
532
499
                    kWarning(30515) << "Destination stack is empty! Document might be buggy!";
533
500
                    // Keep the destination to save what can still be saved!
534
 
                }
535
 
                else
536
 
                {
 
501
                } else {
537
502
                    destination = destinationStack.pop();
538
503
                }
539
504
            }
540
505
            // ### TODO: why can this not be simplified to use QValueList::isEmpty()
541
 
            if (stateStack.count() <= 1)
542
 
            {
 
506
            if (stateStack.count() <= 1) {
543
507
                // End-of-document, keep formatting properties
544
508
                stateStack.pop();
545
509
                break;
546
 
            }
547
 
            else
548
 
            {
 
510
            } else {
549
511
                // Retrieve the current state from the stack
550
512
                state = stateStack.pop();
551
513
            }
552
 
        }
553
 
        else if (token.type == RTFTokenizer::ControlWord)
554
 
        {
 
514
        } else if (token.type == RTFTokenizer::ControlWord) {
555
515
            RTFProperty *property = properties[token.text];
556
516
 
557
 
            if (property != 0L)
558
 
            {
 
517
            if (property != 0L) {
559
518
                if (property->onlyValidIn == 0L ||
560
 
                    property->onlyValidIn == destination.name ||
561
 
                    property->onlyValidIn == destination.group)
562
 
                {
563
 
                    (this->*property->cwproc)( property );
 
519
                        property->onlyValidIn == destination.name ||
 
520
                        property->onlyValidIn == destination.group) {
 
521
                    (this->*property->cwproc)(property);
564
522
                }
565
 
            }
566
 
            else if (firstToken)
567
 
            {
 
523
            } else if (firstToken) {
568
524
                // Possible destination change
569
525
                *(--token.text) = '@';
570
526
                property = destinationProperties[token.text];
571
527
 
572
528
                if ((property != 0L) &&
573
 
                    (property->onlyValidIn == 0L ||
574
 
                     property->onlyValidIn == destination.name ||
575
 
                     property->onlyValidIn == destination.group))
576
 
                {
 
529
                        (property->onlyValidIn == 0L ||
 
530
                         property->onlyValidIn == destination.name ||
 
531
                         property->onlyValidIn == destination.group)) {
577
532
                    // Change destination
578
 
                    changeDestination( property );
579
 
                }
580
 
                else if (ignoreUnknown)
581
 
                {
 
533
                    changeDestination(property);
 
534
                } else if (ignoreUnknown) {
582
535
                    // Skip unknown {\* ...} destination
583
 
                    changeDestination( destinationProperties["@*"] );
 
536
                    changeDestination(destinationProperties["@*"]);
584
537
                    debugUnknownKeywords[token.text]++;
585
 
                }
586
 
                else if ( !property )
587
 
                {
588
 
                    kWarning(30515) << "Unknown first non-ignorable token of a group: " << token.text; kDebug(30515) <<"Destination:" << ( (void*) destination.name ) <<" Destination stack depth:" << destinationStack.count();
 
538
                } else if (!property) {
 
539
                    kWarning(30515) << "Unknown first non-ignorable token of a group: " << token.text; kDebug(30515) << "Destination:" << ((void*) destination.name) << " Destination stack depth:" << destinationStack.count();
589
540
                    // Put the second warning separately, as it can crash if destination.name is dangling
590
541
                    kWarning(30515) << " Assuming destination: " << destination.name;
591
542
                    debugUnknownKeywords[token.text]++;
592
543
                }
593
 
            }
594
 
            else
595
 
            {
 
544
            } else {
596
545
                debugUnknownKeywords[token.text]++;
597
546
            }
598
 
        }
599
 
        else if (token.type == RTFTokenizer::PlainText || token.type == RTFTokenizer::BinaryData)
600
 
        {
 
547
        } else if (token.type == RTFTokenizer::PlainText || token.type == RTFTokenizer::BinaryData) {
601
548
            (this->*destination.destproc)(0L);
602
549
        }
603
550
    }
604
551
 
605
552
    // Determine header and footer type
606
553
    const int hType = facingPages
607
 
        ? (state.section.titlePage ? 3 : 1) : (state.section.titlePage ? 2 : 0);
 
554
                      ? (state.section.titlePage ? 3 : 1) : (state.section.titlePage ? 2 : 0);
608
555
 
609
556
    const bool hasHeader = !oddPagesHeader.node.isEmpty() ||
610
 
        (facingPages &&!evenPagesHeader.node.isEmpty()) ||
611
 
        (state.section.titlePage && !firstPageHeader.node.isEmpty());
 
557
                           (facingPages && !evenPagesHeader.node.isEmpty()) ||
 
558
                           (state.section.titlePage && !firstPageHeader.node.isEmpty());
612
559
    const bool hasFooter = !oddPagesFooter.node.isEmpty() ||
613
 
        (facingPages && !evenPagesFooter.node.isEmpty()) ||
614
 
        (state.section.titlePage && !firstPageFooter.node.isEmpty());
 
560
                           (facingPages && !evenPagesFooter.node.isEmpty()) ||
 
561
                           (state.section.titlePage && !firstPageFooter.node.isEmpty());
615
562
 
616
 
    kDebug(30515) <<"hType" << hType <<" hasHeader" << hasHeader <<" hasFooter" << hasFooter;
 
563
    kDebug(30515) << "hType" << hType << " hasHeader" << hasHeader << " hasFooter" << hasFooter;
617
564
 
618
565
    // Create main document
619
 
    DomNode mainDoc( "DOC" );
620
 
      mainDoc.setAttribute( "mime", "application/x-kword" );
621
 
      mainDoc.setAttribute( "syntaxVersion", "3" );
622
 
      mainDoc.setAttribute( "editor", "KWord's RTF Import Filter" );
623
 
      mainDoc.addNode( "PAPER" );
624
 
        mainDoc.setAttribute( "format", 6 );
625
 
        mainDoc.setAttribute( "columns", 1 );
626
 
        mainDoc.setAttribute( "columnspacing", 2 );
627
 
        mainDoc.setAttribute( "spHeadBody", 4 );
628
 
        mainDoc.setAttribute( "spFootBody", 4 );
629
 
        mainDoc.setAttribute( "zoom", 100 );
630
 
        mainDoc.setAttribute( "width", .05*paperWidth );
631
 
        mainDoc.setAttribute( "height", .05*paperHeight );
632
 
        mainDoc.setAttribute( "orientation", landscape );
633
 
        mainDoc.setAttribute( "hType", hType );
634
 
        mainDoc.setAttribute( "fType", hType );
635
 
        mainDoc.addNode( "PAPERBORDERS" );
636
 
          mainDoc.addRect( leftMargin,
637
 
                   (hasHeader ? state.section.headerMargin : topMargin),
638
 
                   rightMargin,
639
 
                   (hasFooter ? state.section.footerMargin : bottomMargin) );
640
 
        mainDoc.closeNode( "PAPERBORDERS" );
641
 
      mainDoc.closeNode( "PAPER" );
642
 
      mainDoc.addNode( "ATTRIBUTES" );
643
 
        mainDoc.setAttribute( "standardpage", 1 );
644
 
        mainDoc.setAttribute( "processing", 0 );
645
 
        //mainDoc.setAttribute( "unit", "pt" ); // use KWord default instead
646
 
        mainDoc.setAttribute( "hasHeader", hasHeader );
647
 
        mainDoc.setAttribute( "hasFooter", hasFooter );
648
 
      mainDoc.closeNode( "ATTRIBUTES" );
649
 
      mainDoc.addNode( "FRAMESETS" );
650
 
        mainDoc.addFrameSet( "Frameset 1", 1, 0 );
651
 
          mainDoc.addFrame( leftMargin, topMargin, (paperWidth - rightMargin),
652
 
                    (paperHeight - bottomMargin), 1, 0, 0 );
653
 
          mainDoc.closeNode( "FRAME" );
654
 
          mainDoc.appendNode( bodyText.node );
655
 
        mainDoc.closeNode( "FRAMESET" );
656
 
        // Write out headers
657
 
        if (hasHeader)
658
 
        {
659
 
            mainDoc.addFrameSet( "First Page Header", 1, 1 );
660
 
              mainDoc.addFrame( leftMargin, state.section.headerMargin,
661
 
                        (paperWidth - rightMargin), (topMargin - 80), 0, 2, 0 );
662
 
              mainDoc.closeNode( "FRAME" );
663
 
              mainDoc.appendNode( firstPageHeader.node );
664
 
            mainDoc.closeNode( "FRAMESET" );
665
 
            mainDoc.addFrameSet( "Odd Pages Header", 1, 2 );
666
 
              mainDoc.addFrame( leftMargin, state.section.headerMargin,
667
 
                        (paperWidth - rightMargin), (topMargin - 80), 0, 2, 1 );
668
 
              mainDoc.closeNode( "FRAME" );
669
 
              mainDoc.appendNode( oddPagesHeader.node );
670
 
            mainDoc.closeNode( "FRAMESET" );
671
 
            mainDoc.addFrameSet( "Even Pages Header", 1, 3 );
672
 
              mainDoc.addFrame( leftMargin, state.section.headerMargin,
673
 
                        (paperWidth - rightMargin), (topMargin - 80), 0, 2, 2 );
674
 
              mainDoc.closeNode( "FRAME" );
675
 
              mainDoc.appendNode( evenPagesHeader.node );
676
 
            mainDoc.closeNode( "FRAMESET" );
677
 
        }
678
 
        // Write out footers
679
 
        if (hasFooter)
680
 
        {
681
 
            mainDoc.addFrameSet( "First Page Footer", 1, 4 );
682
 
              mainDoc.addFrame( leftMargin, state.section.headerMargin,
683
 
                        (paperWidth - rightMargin), (topMargin - 80), 0, 2, 0 );
684
 
              mainDoc.closeNode( "FRAME" );
685
 
              mainDoc.appendNode( firstPageFooter.node );
686
 
            mainDoc.closeNode( "FRAMESET" );
687
 
            mainDoc.addFrameSet( "Odd Pages Footer", 1, 5 );
688
 
              mainDoc.addFrame( leftMargin, state.section.headerMargin,
689
 
                        (paperWidth - rightMargin), (topMargin - 80), 0, 2, 1 );
690
 
              mainDoc.closeNode( "FRAME" );
691
 
              mainDoc.appendNode( oddPagesFooter.node );
692
 
            mainDoc.closeNode( "FRAMESET" );
693
 
            mainDoc.addFrameSet( "Even Pages Footer", 1, 6 );
694
 
              mainDoc.addFrame( leftMargin, state.section.headerMargin,
695
 
                        (paperWidth - rightMargin), (topMargin - 80), 0, 2, 2 );
696
 
              mainDoc.closeNode( "FRAME" );
697
 
              mainDoc.appendNode( evenPagesFooter.node );
698
 
            mainDoc.closeNode( "FRAMESET" );
699
 
        }
700
 
        // Write out footnotes
701
 
        int num=1;
702
 
        foreach(RTFTextState* footnote, footnotes)
703
 
        {
704
 
            QByteArray str;
705
 
            str.setNum(num);
706
 
            str.prepend("Footnote ");
707
 
            num++;
708
 
            mainDoc.addFrameSet( str, 1, 7 );
709
 
              mainDoc.addFrame( leftMargin, paperHeight - bottomMargin-80,
710
 
                        (paperWidth - rightMargin), paperHeight-bottomMargin, 0, 2, 0 );
711
 
              mainDoc.closeNode( "FRAME" );
712
 
              mainDoc.appendNode( footnote->node );
713
 
            mainDoc.closeNode( "FRAMESET" );
714
 
        }
715
 
        mainDoc.appendNode( frameSets );
716
 
        mainDoc.closeNode( "FRAMESETS" );
717
 
        mainDoc.addNode( "PICTURES" );
718
 
        mainDoc.appendNode( pictures );
719
 
        mainDoc.closeNode( "PICTURES" );
720
 
        mainDoc.addNode( "STYLES" );
721
 
        kwFormat.id  = 1;
722
 
        kwFormat.pos = 0;
723
 
        kwFormat.len = 0;
724
 
 
725
 
        // Process all styles in the style sheet
726
 
        const QVector<RTFStyle>::ConstIterator endStyleSheet=styleSheet.constEnd();
727
 
        for (QVector<RTFStyle>::ConstIterator it=styleSheet.constBegin();it!=endStyleSheet;++it)
728
 
        {
729
 
            mainDoc.addNode( "STYLE" );
730
 
            kwFormat.fmt = (*it).format;
731
 
 
732
 
            // Search for 'following' style
733
 
            for (QVector<RTFStyle>::ConstIterator it2=styleSheet.constBegin();it2!=endStyleSheet;++it2)
734
 
            {
735
 
                if ((*it2).layout.style == (*it).next)
736
 
                {
737
 
                    mainDoc.addNode( "FOLLOWING" );
738
 
                    mainDoc.setAttribute( "name", CheckAndEscapeXmlText( (*it2).name ));
739
 
                    mainDoc.closeNode( "FOLLOWING");
740
 
                    break;
741
 
                }
 
566
    DomNode mainDoc("DOC");
 
567
    mainDoc.setAttribute("mime", "application/x-kword");
 
568
    mainDoc.setAttribute("syntaxVersion", "3");
 
569
    mainDoc.setAttribute("editor", "KWord's RTF Import Filter");
 
570
    mainDoc.addNode("PAPER");
 
571
    mainDoc.setAttribute("format", 6);
 
572
    mainDoc.setAttribute("columns", 1);
 
573
    mainDoc.setAttribute("columnspacing", 2);
 
574
    mainDoc.setAttribute("spHeadBody", 4);
 
575
    mainDoc.setAttribute("spFootBody", 4);
 
576
    mainDoc.setAttribute("zoom", 100);
 
577
    mainDoc.setAttribute("width", .05*paperWidth);
 
578
    mainDoc.setAttribute("height", .05*paperHeight);
 
579
    mainDoc.setAttribute("orientation", landscape);
 
580
    mainDoc.setAttribute("hType", hType);
 
581
    mainDoc.setAttribute("fType", hType);
 
582
    mainDoc.addNode("PAPERBORDERS");
 
583
    mainDoc.addRect(leftMargin,
 
584
                    (hasHeader ? state.section.headerMargin : topMargin),
 
585
                    rightMargin,
 
586
                    (hasFooter ? state.section.footerMargin : bottomMargin));
 
587
    mainDoc.closeNode("PAPERBORDERS");
 
588
    mainDoc.closeNode("PAPER");
 
589
    mainDoc.addNode("ATTRIBUTES");
 
590
    mainDoc.setAttribute("standardpage", 1);
 
591
    mainDoc.setAttribute("processing", 0);
 
592
    //mainDoc.setAttribute( "unit", "pt" ); // use KWord default instead
 
593
    mainDoc.setAttribute("hasHeader", hasHeader);
 
594
    mainDoc.setAttribute("hasFooter", hasFooter);
 
595
    mainDoc.closeNode("ATTRIBUTES");
 
596
    mainDoc.addNode("FRAMESETS");
 
597
    mainDoc.addFrameSet("Frameset 1", 1, 0);
 
598
    mainDoc.addFrame(leftMargin, topMargin, (paperWidth - rightMargin),
 
599
                     (paperHeight - bottomMargin), 1, 0, 0);
 
600
    mainDoc.closeNode("FRAME");
 
601
    mainDoc.appendNode(bodyText.node);
 
602
    mainDoc.closeNode("FRAMESET");
 
603
    // Write out headers
 
604
    if (hasHeader) {
 
605
        mainDoc.addFrameSet("First Page Header", 1, 1);
 
606
        mainDoc.addFrame(leftMargin, state.section.headerMargin,
 
607
                         (paperWidth - rightMargin), (topMargin - 80), 0, 2, 0);
 
608
        mainDoc.closeNode("FRAME");
 
609
        mainDoc.appendNode(firstPageHeader.node);
 
610
        mainDoc.closeNode("FRAMESET");
 
611
        mainDoc.addFrameSet("Odd Pages Header", 1, 2);
 
612
        mainDoc.addFrame(leftMargin, state.section.headerMargin,
 
613
                         (paperWidth - rightMargin), (topMargin - 80), 0, 2, 1);
 
614
        mainDoc.closeNode("FRAME");
 
615
        mainDoc.appendNode(oddPagesHeader.node);
 
616
        mainDoc.closeNode("FRAMESET");
 
617
        mainDoc.addFrameSet("Even Pages Header", 1, 3);
 
618
        mainDoc.addFrame(leftMargin, state.section.headerMargin,
 
619
                         (paperWidth - rightMargin), (topMargin - 80), 0, 2, 2);
 
620
        mainDoc.closeNode("FRAME");
 
621
        mainDoc.appendNode(evenPagesHeader.node);
 
622
        mainDoc.closeNode("FRAMESET");
 
623
    }
 
624
    // Write out footers
 
625
    if (hasFooter) {
 
626
        mainDoc.addFrameSet("First Page Footer", 1, 4);
 
627
        mainDoc.addFrame(leftMargin, state.section.headerMargin,
 
628
                         (paperWidth - rightMargin), (topMargin - 80), 0, 2, 0);
 
629
        mainDoc.closeNode("FRAME");
 
630
        mainDoc.appendNode(firstPageFooter.node);
 
631
        mainDoc.closeNode("FRAMESET");
 
632
        mainDoc.addFrameSet("Odd Pages Footer", 1, 5);
 
633
        mainDoc.addFrame(leftMargin, state.section.headerMargin,
 
634
                         (paperWidth - rightMargin), (topMargin - 80), 0, 2, 1);
 
635
        mainDoc.closeNode("FRAME");
 
636
        mainDoc.appendNode(oddPagesFooter.node);
 
637
        mainDoc.closeNode("FRAMESET");
 
638
        mainDoc.addFrameSet("Even Pages Footer", 1, 6);
 
639
        mainDoc.addFrame(leftMargin, state.section.headerMargin,
 
640
                         (paperWidth - rightMargin), (topMargin - 80), 0, 2, 2);
 
641
        mainDoc.closeNode("FRAME");
 
642
        mainDoc.appendNode(evenPagesFooter.node);
 
643
        mainDoc.closeNode("FRAMESET");
 
644
    }
 
645
    // Write out footnotes
 
646
    int num = 1;
 
647
    foreach(RTFTextState* footnote, footnotes) {
 
648
        QByteArray str;
 
649
        str.setNum(num);
 
650
        str.prepend("Footnote ");
 
651
        num++;
 
652
        mainDoc.addFrameSet(str, 1, 7);
 
653
        mainDoc.addFrame(leftMargin, paperHeight - bottomMargin - 80,
 
654
                         (paperWidth - rightMargin), paperHeight - bottomMargin, 0, 2, 0);
 
655
        mainDoc.closeNode("FRAME");
 
656
        mainDoc.appendNode(footnote->node);
 
657
        mainDoc.closeNode("FRAMESET");
 
658
    }
 
659
    mainDoc.appendNode(frameSets);
 
660
    mainDoc.closeNode("FRAMESETS");
 
661
    mainDoc.addNode("PICTURES");
 
662
    mainDoc.appendNode(pictures);
 
663
    mainDoc.closeNode("PICTURES");
 
664
    mainDoc.addNode("STYLES");
 
665
    kwFormat.id  = 1;
 
666
    kwFormat.pos = 0;
 
667
    kwFormat.len = 0;
 
668
 
 
669
    // Process all styles in the style sheet
 
670
    const QVector<RTFStyle>::ConstIterator endStyleSheet = styleSheet.constEnd();
 
671
    for (QVector<RTFStyle>::ConstIterator it = styleSheet.constBegin();it != endStyleSheet;++it) {
 
672
        mainDoc.addNode("STYLE");
 
673
        kwFormat.fmt = (*it).format;
 
674
 
 
675
        // Search for 'following' style
 
676
        for (QVector<RTFStyle>::ConstIterator it2 = styleSheet.constBegin();it2 != endStyleSheet;++it2) {
 
677
            if ((*it2).layout.style == (*it).next) {
 
678
                mainDoc.addNode("FOLLOWING");
 
679
                mainDoc.setAttribute("name", CheckAndEscapeXmlText((*it2).name));
 
680
                mainDoc.closeNode("FOLLOWING");
 
681
                break;
742
682
            }
743
 
            addLayout( mainDoc, (*it).name, (*it).layout, false );
744
 
            addFormat( mainDoc, kwFormat, 0L );
745
 
            mainDoc.closeNode( "STYLE" );
746
683
        }
747
 
      mainDoc.closeNode( "STYLES" );
748
 
    mainDoc.closeNode( "DOC" );
 
684
        addLayout(mainDoc, (*it).name, (*it).layout, false);
 
685
        addFormat(mainDoc, kwFormat, 0L);
 
686
        mainDoc.closeNode("STYLE");
 
687
    }
 
688
    mainDoc.closeNode("STYLES");
 
689
    mainDoc.closeNode("DOC");
749
690
 
750
691
    // Create document info
751
 
    DomNode docInfo( "document-info" );
752
 
      docInfo.addNode( "log" );
753
 
        docInfo.addNode( "text" );
754
 
        docInfo.closeNode( "text" );
755
 
      docInfo.closeNode( "log" );
756
 
      docInfo.addNode( "author" );
757
 
        docInfo.addNode( "company" );
758
 
          docInfo.appendNode( company );
759
 
        docInfo.closeNode( "company" );
760
 
        docInfo.addNode( "full-name" );
761
 
          docInfo.appendNode( author );
762
 
        docInfo.closeNode( "full-name" );
763
 
        docInfo.addNode( "email" );
764
 
        docInfo.closeNode( "email" );
765
 
        docInfo.addNode( "telephone" );
766
 
        docInfo.closeNode( "telephone" );
767
 
        docInfo.addNode( "fax" );
768
 
        docInfo.closeNode( "fax" );
769
 
        docInfo.addNode( "country" );
770
 
        docInfo.closeNode( "country" );
771
 
        docInfo.addNode( "postal-code" );
772
 
        docInfo.closeNode( "postal-code" );
773
 
        docInfo.addNode( "city" );
774
 
        docInfo.closeNode( "city" );
775
 
        docInfo.addNode( "street" );
776
 
        docInfo.closeNode( "street" );
777
 
      docInfo.closeNode( "author" );
778
 
      docInfo.addNode( "about" );
779
 
        docInfo.addNode( "abstract" );
780
 
          docInfo.appendNode( doccomm );
781
 
        docInfo.closeNode( "abstract" );
782
 
      docInfo.addNode( "title" );
783
 
        docInfo.appendNode( title );
784
 
      docInfo.closeNode( "title" );
785
 
      docInfo.closeNode( "about" );
786
 
    docInfo.closeNode( "document-info" );
 
692
    DomNode docInfo("document-info");
 
693
    docInfo.addNode("log");
 
694
    docInfo.addNode("text");
 
695
    docInfo.closeNode("text");
 
696
    docInfo.closeNode("log");
 
697
    docInfo.addNode("author");
 
698
    docInfo.addNode("company");
 
699
    docInfo.appendNode(company);
 
700
    docInfo.closeNode("company");
 
701
    docInfo.addNode("full-name");
 
702
    docInfo.appendNode(author);
 
703
    docInfo.closeNode("full-name");
 
704
    docInfo.addNode("email");
 
705
    docInfo.closeNode("email");
 
706
    docInfo.addNode("telephone");
 
707
    docInfo.closeNode("telephone");
 
708
    docInfo.addNode("fax");
 
709
    docInfo.closeNode("fax");
 
710
    docInfo.addNode("country");
 
711
    docInfo.closeNode("country");
 
712
    docInfo.addNode("postal-code");
 
713
    docInfo.closeNode("postal-code");
 
714
    docInfo.addNode("city");
 
715
    docInfo.closeNode("city");
 
716
    docInfo.addNode("street");
 
717
    docInfo.closeNode("street");
 
718
    docInfo.closeNode("author");
 
719
    docInfo.addNode("about");
 
720
    docInfo.addNode("abstract");
 
721
    docInfo.appendNode(doccomm);
 
722
    docInfo.closeNode("abstract");
 
723
    docInfo.addNode("title");
 
724
    docInfo.appendNode(title);
 
725
    docInfo.closeNode("title");
 
726
    docInfo.closeNode("about");
 
727
    docInfo.closeNode("document-info");
787
728
 
788
729
    // Write out main document and document info
789
 
    writeOutPart( "root", mainDoc );
790
 
    writeOutPart( "documentinfo.xml", docInfo );
 
730
    writeOutPart("root", mainDoc);
 
731
    writeOutPart("documentinfo.xml", docInfo);
791
732
    in.close();
792
733
 
793
 
    kDebug(30515) <<"RTF FILTER TIME:" << debugTime.elapsed();
 
734
    kDebug(30515) << "RTF FILTER TIME:" << debugTime.elapsed();
794
735
 
795
 
    for (QMap<QString,int>::ConstIterator it=debugUnknownKeywords.constBegin();
796
 
        it!=debugUnknownKeywords.constEnd();it++)
797
 
        kDebug(30515) <<"Unknown keyword:" << QString("%1" ).arg( it.value(), 4 )  <<" *" << it.key();
 
736
    for (QMap<QString, int>::ConstIterator it = debugUnknownKeywords.constBegin();
 
737
            it != debugUnknownKeywords.constEnd();it++)
 
738
        kDebug(30515) << "Unknown keyword:" << QString("%1").arg(it.value(), 4)  << " *" << it.key();
798
739
 
799
740
    return KoFilter::OK;
800
741
}
801
742
 
802
 
void RTFImport::ignoreKeyword( RTFProperty * )
 
743
void RTFImport::ignoreKeyword(RTFProperty *)
803
744
{
804
745
}
805
746
 
806
 
void RTFImport::setCodepage( RTFProperty * )
 
747
void RTFImport::setCodepage(RTFProperty *)
807
748
{
808
749
    QTextCodec* oldCodec = textCodec;
809
750
    QByteArray cp;
810
 
    if ( token.value == 10000 )
811
 
    {
 
751
    if (token.value == 10000) {
812
752
        cp = "Apple Roman"; // ### TODO: how to support the other ones (Qt does not know them!)
813
 
    }
814
 
    else
815
 
    {
816
 
        cp.setNum( token.value );
 
753
    } else {
 
754
        cp.setNum(token.value);
817
755
        cp.prepend("CP");
818
756
    }
819
 
    textCodec=QTextCodec::codecForName(cp);
820
 
    kDebug(30515) <<"\\ansicpg: codepage:" << token.value <<"asked:"<< cp <<" given:" << (textCodec?textCodec->name():QString("-none-"));
821
 
    if ( ! textCodec )
822
 
        textCodec = oldCodec;
823
 
}
824
 
 
825
 
void RTFImport::setMacCodepage( RTFProperty * )
826
 
{
827
 
    QTextCodec* oldCodec = textCodec;
828
 
    textCodec=QTextCodec::codecForName("Apple Roman");
829
 
    kDebug(30515) <<"\\mac" << (textCodec?textCodec->name():QString("-none-"));
830
 
    if ( ! textCodec )
831
 
        textCodec = oldCodec;
832
 
}
833
 
 
834
 
void RTFImport::setAnsiCodepage( RTFProperty * )
835
 
{
836
 
    QTextCodec* oldCodec = textCodec;
837
 
    textCodec=QTextCodec::codecForName("CP1252");
838
 
    kDebug(30515) <<"\\ansi" << (textCodec?textCodec->name():QString("-none-"));
839
 
    if ( ! textCodec )
840
 
        textCodec = oldCodec;
841
 
}
842
 
 
843
 
void RTFImport::setPcaCodepage( RTFProperty * )
844
 
{
845
 
    QTextCodec* oldCodec = textCodec;
846
 
    textCodec=QTextCodec::codecForName("IBM 850"); // Qt writes the name with a space
847
 
    kDebug(30515) <<"\\pca" << (textCodec?textCodec->name():QString("-none-"));
848
 
    if ( ! textCodec )
849
 
        textCodec = oldCodec;
850
 
}
851
 
 
852
 
void RTFImport::setPcCodepage( RTFProperty * )
853
 
{
854
 
    QTextCodec* oldCodec = textCodec;
855
 
    textCodec=QTextCodec::codecForName("IBM 850"); // This is an approximation
856
 
    kDebug(30515) <<"\\pc (approximation)" << (textCodec?textCodec->name():QString("-none-"));
857
 
    if ( ! textCodec )
858
 
        textCodec = oldCodec;
859
 
}
860
 
 
861
 
void RTFImport::setToggleProperty( RTFProperty *property )
 
757
    textCodec = QTextCodec::codecForName(cp);
 
758
    kDebug(30515) << "\\ansicpg: codepage:" << token.value << "asked:" << cp << " given:" << (textCodec ? textCodec->name() : QString("-none-"));
 
759
    if (! textCodec)
 
760
        textCodec = oldCodec;
 
761
}
 
762
 
 
763
void RTFImport::setMacCodepage(RTFProperty *)
 
764
{
 
765
    QTextCodec* oldCodec = textCodec;
 
766
    textCodec = QTextCodec::codecForName("Apple Roman");
 
767
    kDebug(30515) << "\\mac" << (textCodec ? textCodec->name() : QString("-none-"));
 
768
    if (! textCodec)
 
769
        textCodec = oldCodec;
 
770
}
 
771
 
 
772
void RTFImport::setAnsiCodepage(RTFProperty *)
 
773
{
 
774
    QTextCodec* oldCodec = textCodec;
 
775
    textCodec = QTextCodec::codecForName("CP1252");
 
776
    kDebug(30515) << "\\ansi" << (textCodec ? textCodec->name() : QString("-none-"));
 
777
    if (! textCodec)
 
778
        textCodec = oldCodec;
 
779
}
 
780
 
 
781
void RTFImport::setPcaCodepage(RTFProperty *)
 
782
{
 
783
    QTextCodec* oldCodec = textCodec;
 
784
    textCodec = QTextCodec::codecForName("IBM 850"); // Qt writes the name with a space
 
785
    kDebug(30515) << "\\pca" << (textCodec ? textCodec->name() : QString("-none-"));
 
786
    if (! textCodec)
 
787
        textCodec = oldCodec;
 
788
}
 
789
 
 
790
void RTFImport::setPcCodepage(RTFProperty *)
 
791
{
 
792
    QTextCodec* oldCodec = textCodec;
 
793
    textCodec = QTextCodec::codecForName("IBM 850"); // This is an approximation
 
794
    kDebug(30515) << "\\pc (approximation)" << (textCodec ? textCodec->name() : QString("-none-"));
 
795
    if (! textCodec)
 
796
        textCodec = oldCodec;
 
797
}
 
798
 
 
799
void RTFImport::setToggleProperty(RTFProperty *property)
862
800
{
863
801
    ((bool *)this)[property->offset] = (!token.hasParam || token.value != 0);
864
802
}
865
803
 
866
 
void RTFImport::setFlagProperty( RTFProperty *property )
 
804
void RTFImport::setFlagProperty(RTFProperty *property)
867
805
{
868
806
    ((bool *)this)[property->offset] = property->value;
869
807
}
870
808
 
871
 
void RTFImport::setCharset( RTFProperty *property )
 
809
void RTFImport::setCharset(RTFProperty *property)
872
810
{
873
811
    QByteArray cp;
874
 
    switch(token.value) {
875
 
        case 0: cp = "CP1252"; break; // ANSI_CHARSET
876
 
        case 1: cp = "CP1252"; break; // DEFAULT_CHARSET
 
812
    switch (token.value) {
 
813
    case 0: cp = "CP1252"; break; // ANSI_CHARSET
 
814
    case 1: cp = "CP1252"; break; // DEFAULT_CHARSET
877
815
        //case 2: cp = ""; break; // SYMBOL_CHARSET not supported yet.
878
 
        case 77: cp = "Apple Roman"; break; // MAC_CHARSET
879
 
        case 128: cp = "Shift-JIS"; break; // SHIFTJIS_CHARSET "CP932"
880
 
        case 129: cp = "eucKR"; break; // HANGUL_CHARSET "CP949"
881
 
        case 130: cp = "CP1361"; break; // JOHAB_CHARSET doesn't really seem to be supported by Qt :-(
882
 
        case 134: cp = "GB2312"; break; // GB2312_CHARSET "CP936"
883
 
        case 136: cp = "Big5-HKSCS"; break; // CHINESEBIG5_CHARSET "CP950"
884
 
        case 161: cp = "CP1253"; break; // GREEK_CHARSET
885
 
        case 162: cp = "CP1254"; break; // TURKISH_CHARSET
886
 
        case 163: cp = "CP1258"; break; // VIETNAMESE_CHARSET
887
 
        case 177: cp = "CP1255"; break; // HEBREW_CHARSET
888
 
        case 178: cp = "CP1256"; break; // ARABIC_CHARSET / ARABICSIMPLIFIED_CHARSET
889
 
        case 186: cp = "CP1257"; break; // BALTIC_CHARSET
890
 
        case 204: cp = "CP1251"; break; // RUSSIAN_CHARSET / CYRILLIC_CHARSET
891
 
        case 222: cp = "CP874"; break; // THAI_CHARSET
892
 
        case 238: cp = "CP1250"; break; // EASTEUROPE_CHARSET / EASTERNEUROPE_CHARSET
893
 
        case 255: cp = "CP850"; break; // OEM_CHARSET "IBM 850"
894
 
        default: return;
 
816
    case 77: cp = "Apple Roman"; break; // MAC_CHARSET
 
817
    case 128: cp = "Shift-JIS"; break; // SHIFTJIS_CHARSET "CP932"
 
818
    case 129: cp = "eucKR"; break; // HANGUL_CHARSET "CP949"
 
819
    case 130: cp = "CP1361"; break; // JOHAB_CHARSET doesn't really seem to be supported by Qt :-(
 
820
    case 134: cp = "GB2312"; break; // GB2312_CHARSET "CP936"
 
821
    case 136: cp = "Big5-HKSCS"; break; // CHINESEBIG5_CHARSET "CP950"
 
822
    case 161: cp = "CP1253"; break; // GREEK_CHARSET
 
823
    case 162: cp = "CP1254"; break; // TURKISH_CHARSET
 
824
    case 163: cp = "CP1258"; break; // VIETNAMESE_CHARSET
 
825
    case 177: cp = "CP1255"; break; // HEBREW_CHARSET
 
826
    case 178: cp = "CP1256"; break; // ARABIC_CHARSET / ARABICSIMPLIFIED_CHARSET
 
827
    case 186: cp = "CP1257"; break; // BALTIC_CHARSET
 
828
    case 204: cp = "CP1251"; break; // RUSSIAN_CHARSET / CYRILLIC_CHARSET
 
829
    case 222: cp = "CP874"; break; // THAI_CHARSET
 
830
    case 238: cp = "CP1250"; break; // EASTEUROPE_CHARSET / EASTERNEUROPE_CHARSET
 
831
    case 255: cp = "CP850"; break; // OEM_CHARSET "IBM 850"
 
832
    default: return;
895
833
    }
896
834
    QTextCodec* oldCodec = textCodec;
897
 
    textCodec=QTextCodec::codecForName(cp);
898
 
    kDebug(30515) <<"\\fcharset: charset:" << token.value <<" codepage:"<< cp <<" given:" << (textCodec?textCodec->name():QString("-none-"));
899
 
    if ( ! textCodec )
 
835
    textCodec = QTextCodec::codecForName(cp);
 
836
    kDebug(30515) << "\\fcharset: charset:" << token.value << " codepage:" << cp << " given:" << (textCodec ? textCodec->name() : QString("-none-"));
 
837
    if (! textCodec)
900
838
        textCodec = oldCodec;
901
839
}
902
840
 
903
 
void RTFImport::setNumericProperty( RTFProperty *property )
 
841
void RTFImport::setNumericProperty(RTFProperty *property)
904
842
{
905
843
    *((int *)(((char *)this) + property->offset)) = token.hasParam ? token.value : property->value;
906
844
}
907
845
 
908
 
void RTFImport::setEnumProperty( RTFProperty *property )
 
846
void RTFImport::setEnumProperty(RTFProperty *property)
909
847
{
910
848
    *((int *)(((char *)this) + property->offset)) = property->value;
911
849
}
912
850
 
913
 
void RTFImport::setFontStyleHint( RTFProperty* property )
914
 
{
915
 
    font.styleHint = QFont::StyleHint( property->value );
916
 
}
917
 
 
918
 
void RTFImport::setPictureType( RTFProperty* property )
919
 
{
920
 
    picture.type = RTFPicture::PictureType( property->value );
921
 
}
922
 
 
923
 
void RTFImport::setSimpleUnderlineProperty( RTFProperty* )
 
851
void RTFImport::setFontStyleHint(RTFProperty* property)
 
852
{
 
853
    font.styleHint = QFont::StyleHint(property->value);
 
854
}
 
855
 
 
856
void RTFImport::setPictureType(RTFProperty* property)
 
857
{
 
858
    picture.type = RTFPicture::PictureType(property->value);
 
859
}
 
860
 
 
861
void RTFImport::setSimpleUnderlineProperty(RTFProperty*)
924
862
{
925
863
    state.format.underline
926
 
         = (!token.hasParam || token.value != 0)
927
 
         ? RTFFormat::UnderlineSimple : RTFFormat::UnderlineNone;
928
 
}
929
 
 
930
 
void RTFImport::setUnderlineProperty( RTFProperty* property )
931
 
{
932
 
    state.format.underline = RTFFormat::Underline( property->value );
933
 
}
934
 
 
935
 
void RTFImport::setBorderStyle( RTFProperty *property )
936
 
{
937
 
    if (state.layout.border)
938
 
    {
939
 
        state.layout.border->style = static_cast <RTFBorder::BorderStyle> ( property->value );
940
 
    }
941
 
    else
942
 
    {
943
 
        for (uint i=0; i < 4; i++)
944
 
        {
945
 
            state.layout.borders[i].style = static_cast <RTFBorder::BorderStyle> ( property->value );
 
864
    = (!token.hasParam || token.value != 0)
 
865
      ? RTFFormat::UnderlineSimple : RTFFormat::UnderlineNone;
 
866
}
 
867
 
 
868
void RTFImport::setUnderlineProperty(RTFProperty* property)
 
869
{
 
870
    state.format.underline = RTFFormat::Underline(property->value);
 
871
}
 
872
 
 
873
void RTFImport::setBorderStyle(RTFProperty *property)
 
874
{
 
875
    if (state.layout.border) {
 
876
        state.layout.border->style = static_cast <RTFBorder::BorderStyle>(property->value);
 
877
    } else {
 
878
        for (uint i = 0; i < 4; i++) {
 
879
            state.layout.borders[i].style = static_cast <RTFBorder::BorderStyle>(property->value);
946
880
        }
947
881
    }
948
882
}
949
883
 
950
 
void RTFImport::setBorderProperty( RTFProperty *property )
 
884
void RTFImport::setBorderProperty(RTFProperty *property)
951
885
{
952
886
    //kDebug() <<"setBorderProperty:";
953
 
    if (state.layout.border)
954
 
    {
 
887
    if (state.layout.border) {
955
888
        state.layout.border->width = token.value;
956
 
    }
957
 
    else
958
 
    {
959
 
        for (uint i=0; i < 4; i++)
960
 
        {
 
889
    } else {
 
890
        for (uint i = 0; i < 4; i++) {
961
891
            state.layout.borders[i].width = token.value;
962
892
        }
963
893
    }
964
894
}
965
895
 
966
 
void RTFImport::setBorderColor( RTFProperty * )
 
896
void RTFImport::setBorderColor(RTFProperty *)
967
897
{
968
 
    if (state.layout.border)
969
 
    {
 
898
    if (state.layout.border) {
970
899
        state.layout.border->color = token.value;
971
 
    }
972
 
    else
973
 
    {
974
 
        for (uint i=0; i < 4; i++)
975
 
        {
 
900
    } else {
 
901
        for (uint i = 0; i < 4; i++) {
976
902
            state.layout.borders[i].color = token.value;
977
903
        }
978
904
    }
979
905
}
980
906
 
981
 
void RTFImport::setUpProperty( RTFProperty * )
 
907
void RTFImport::setUpProperty(RTFProperty *)
982
908
{
983
909
    state.format.baseline = token.hasParam ? -token.value : -6;
984
910
}
985
911
 
986
 
void RTFImport::setPlainFormatting( RTFProperty * )
 
912
void RTFImport::setPlainFormatting(RTFProperty *)
987
913
{
988
914
    RTFFormat &format = state.format;
989
915
 
990
 
    format.font         = defaultFont;
991
 
    format.fontSize     = 24;
992
 
    format.baseline     = 0;
993
 
    format.color        = -1;
994
 
    format.bgcolor      = -1;
995
 
    format.underlinecolor       = -1;
996
 
    format.vertAlign    = RTFFormat::Normal;
997
 
    format.bold         = false;
998
 
    format.italic       = false;
999
 
    format.strike       = false;
1000
 
    format.striked      = false;
1001
 
    format.hidden       = false;
1002
 
    format.caps         = false;
1003
 
    format.smallCaps    = false;
 
916
    format.font  = defaultFont;
 
917
    format.fontSize = 24;
 
918
    format.baseline = 0;
 
919
    format.color = -1;
 
920
    format.bgcolor = -1;
 
921
    format.underlinecolor = -1;
 
922
    format.vertAlign = RTFFormat::Normal;
 
923
    format.bold  = false;
 
924
    format.italic = false;
 
925
    format.strike = false;
 
926
    format.striked = false;
 
927
    format.hidden = false;
 
928
    format.caps  = false;
 
929
    format.smallCaps = false;
1004
930
 
1005
 
    format.underline            = RTFFormat::UnderlineNone;
 
931
    format.underline  = RTFFormat::UnderlineNone;
1006
932
 
1007
933
    // Do not reset format.uc !
1008
934
}
1009
935
 
1010
 
void RTFImport::setParagraphDefaults( RTFProperty * )
 
936
void RTFImport::setParagraphDefaults(RTFProperty *)
1011
937
{
1012
938
    RTFLayout &layout = state.layout;
1013
939
 
1014
940
    layout.tablist.clear();
1015
 
    layout.tab.type     = RTFTab::Left;
1016
 
    layout.tab.leader   = RTFTab::None;
 
941
    layout.tab.type = RTFTab::Left;
 
942
    layout.tab.leader = RTFTab::None;
1017
943
 
1018
 
    for (uint i=0; i < 4; i++)
1019
 
    {
 
944
    for (uint i = 0; i < 4; i++) {
1020
945
        RTFBorder &border = layout.borders[i];
1021
946
        border.color = -1;
1022
947
        border.width = 0;
1023
948
        border.style = RTFBorder::None;
1024
949
    }
1025
 
    layout.firstIndent  = 0;
1026
 
    layout.leftIndent   = 0;
1027
 
    layout.rightIndent  = 0;
1028
 
    layout.spaceBefore  = 0;
1029
 
    layout.spaceAfter   = 0;
1030
 
    layout.spaceBetween = 0;
 
950
    layout.firstIndent = 0;
 
951
    layout.leftIndent = 0;
 
952
    layout.rightIndent = 0;
 
953
    layout.spaceBefore = 0;
 
954
    layout.spaceAfter = 0;
 
955
    layout.spaceBetween = 0;
1031
956
    layout.spaceBetweenMultiple = false;
1032
 
    layout.style        = 0;
1033
 
    layout.alignment    = RTFLayout::Left;
1034
 
    layout.border       = 0L;
1035
 
    layout.inTable      = false;
1036
 
    layout.keep         = false;
1037
 
    layout.keepNext     = false;
1038
 
    layout.pageBB       = false;
1039
 
    layout.pageBA       = false;
 
957
    layout.style = 0;
 
958
    layout.alignment = RTFLayout::Left;
 
959
    layout.border = 0L;
 
960
    layout.inTable = false;
 
961
    layout.keep  = false;
 
962
    layout.keepNext = false;
 
963
    layout.pageBB = false;
 
964
    layout.pageBA = false;
1040
965
}
1041
966
 
1042
 
void RTFImport::setSectionDefaults( RTFProperty * )
 
967
void RTFImport::setSectionDefaults(RTFProperty *)
1043
968
{
1044
969
    RTFSectionLayout &section = state.section;
1045
970
 
1046
 
    section.headerMargin        = 720;
1047
 
    section.footerMargin        = 720;
1048
 
    section.titlePage           = false;
 
971
    section.headerMargin = 720;
 
972
    section.footerMargin = 720;
 
973
    section.titlePage  = false;
1049
974
}
1050
975
 
1051
 
void RTFImport::setTableRowDefaults( RTFProperty * )
 
976
void RTFImport::setTableRowDefaults(RTFProperty *)
1052
977
{
1053
978
    RTFTableRow &tableRow = state.tableRow;
1054
979
    RTFTableCell &tableCell = state.tableCell;
1055
980
 
1056
 
    tableRow.height     = 0;
1057
 
    tableRow.left       = 0;
1058
 
    tableRow.alignment  = RTFLayout::Left;
 
981
    tableRow.height = 0;
 
982
    tableRow.left = 0;
 
983
    tableRow.alignment = RTFLayout::Left;
1059
984
    tableRow.cells.clear();
1060
 
    tableCell.bgcolor   = -1;
 
985
    tableCell.bgcolor = -1;
1061
986
 
1062
 
    for (uint i=0; i < 4; i++)
1063
 
    {
 
987
    for (uint i = 0; i < 4; i++) {
1064
988
        RTFBorder &border = tableCell.borders[i];
1065
989
        border.color = -1;
1066
990
        border.width = 0;
1068
992
    }
1069
993
}
1070
994
 
1071
 
void RTFImport::selectLayoutBorder( RTFProperty * property )
 
995
void RTFImport::selectLayoutBorder(RTFProperty * property)
1072
996
{
1073
997
    state.layout.border = & state.layout.borders [ property->value ];
1074
998
}
1075
999
 
1076
 
void RTFImport::selectLayoutBorderFromCell( RTFProperty * property )
 
1000
void RTFImport::selectLayoutBorderFromCell(RTFProperty * property)
1077
1001
{
1078
1002
    state.layout.border = & state.tableCell.borders [ property->value ];
1079
1003
}
1080
1004
 
1081
 
void RTFImport::insertParagraph( RTFProperty * )
 
1005
void RTFImport::insertParagraph(RTFProperty *)
1082
1006
{
1083
 
    if (state.layout.inTable)
1084
 
    {
1085
 
        if (textState->table == 0)
1086
 
        {
 
1007
    if (state.layout.inTable) {
 
1008
        if (textState->table == 0) {
1087
1009
            // Create a new table cell
1088
1010
            textState->table = ++table;
1089
1011
        }
1090
 
        addParagraph( textState->cell, false );
1091
 
    }
1092
 
    else
1093
 
    {
1094
 
        if (textState->table)
1095
 
        {
 
1012
        addParagraph(textState->cell, false);
 
1013
    } else {
 
1014
        if (textState->table) {
1096
1015
            finishTable();
1097
1016
        }
1098
 
        addParagraph( textState->node, false );
 
1017
        addParagraph(textState->node, false);
1099
1018
    }
1100
1019
}
1101
1020
 
1102
 
void RTFImport::insertPageBreak( RTFProperty * )
 
1021
void RTFImport::insertPageBreak(RTFProperty *)
1103
1022
{
1104
 
    if (textState->length > 0)
1105
 
    {
 
1023
    if (textState->length > 0) {
1106
1024
        insertParagraph();
1107
1025
    }
1108
 
    addParagraph( textState->node, true );
 
1026
    addParagraph(textState->node, true);
1109
1027
}
1110
1028
 
1111
 
void RTFImport::insertTableCell( RTFProperty * )
 
1029
void RTFImport::insertTableCell(RTFProperty *)
1112
1030
{
1113
1031
    //{{
1114
1032
    bool b = state.layout.inTable;
1117
1035
    state.layout.inTable = b;
1118
1036
    //}}
1119
1037
    textState->frameSets << textState->cell.toString();
1120
 
    textState->cell.clear( 3 );
 
1038
    textState->cell.clear(3);
1121
1039
}
1122
1040
 
1123
 
void RTFImport::insertTableRow( RTFProperty * )
 
1041
void RTFImport::insertTableRow(RTFProperty *)
1124
1042
{
1125
 
    if (!textState->frameSets.isEmpty())
1126
 
    {
 
1043
    if (!textState->frameSets.isEmpty()) {
1127
1044
        RTFTableRow row = state.tableRow;
1128
1045
        row.frameSets = textState->frameSets;
1129
1046
 
1130
 
        if (textState->rows.isEmpty())
1131
 
        {
 
1047
        if (textState->rows.isEmpty()) {
1132
1048
            char buf[64];
1133
 
            sprintf( buf, "Table %d", textState->table );
 
1049
            sprintf(buf, "Table %d", textState->table);
1134
1050
            RTFLayout::Alignment align = row.alignment;
1135
1051
 
1136
1052
            // Store the current state on the stack
1137
 
            stateStack.push( state );
 
1053
            stateStack.push(state);
1138
1054
            resetState();
1139
 
            state.layout.alignment = align;     // table alignment
 
1055
            state.layout.alignment = align; // table alignment
1140
1056
 
1141
1057
            // Add anchor for new table (default layout)
1142
 
            addAnchor( buf );
1143
 
            addParagraph( textState->node, false );
 
1058
            addAnchor(buf);
 
1059
            addParagraph(textState->node, false);
1144
1060
 
1145
1061
            // Retrieve the current state from the stack
1146
1062
            state = stateStack.pop();
1147
1063
        }
1148
1064
 
1149
1065
        // Number of cell definitions should equal the number of cells
1150
 
        while (row.cells.count() > row.frameSets.count())
1151
 
        {
 
1066
        while (row.cells.count() > row.frameSets.count()) {
1152
1067
            // ### TODO: verify if it is the right action and how we have come here at all.
1153
1068
            row.cells.pop_back();
1154
1069
        }
1155
 
        while (row.cells.count() < row.frameSets.count())
1156
 
        {
 
1070
        while (row.cells.count() < row.frameSets.count()) {
1157
1071
            row.cells << row.cells.last();
1158
1072
        }
1159
1073
        int lx = row.left;
1160
1074
 
1161
1075
        // Each cell should be at least 1x1 in size
1162
 
        if (row.height == 0)
1163
 
        {
 
1076
        if (row.height == 0) {
1164
1077
            row.height = 1;
1165
1078
        }
1166
 
        for (int k=0; k < row.cells.count(); k++)
1167
 
        {
 
1079
        for (int k = 0; k < row.cells.count(); k++) {
1168
1080
            if ((row.cells[k].x - lx) < 1)
1169
1081
                row.cells[k].x = ++lx;
1170
1082
            else
1171
1083
                lx = row.cells[k].x;
1172
1084
        }
1173
 
        if (row.left < 0)
1174
 
        {
1175
 
            for (int k=0; k < row.cells.count(); k++)
1176
 
            {
 
1085
        if (row.left < 0) {
 
1086
            for (int k = 0; k < row.cells.count(); k++) {
1177
1087
                row.cells[k].x -= row.left;
1178
1088
            }
1179
1089
            row.left = 0;
1183
1093
    }
1184
1094
}
1185
1095
 
1186
 
void RTFImport::insertCellDef( RTFProperty * )
 
1096
void RTFImport::insertCellDef(RTFProperty *)
1187
1097
{
1188
1098
    RTFTableCell &cell = state.tableCell;
1189
 
    cell.x              = token.value;
 
1099
    cell.x  = token.value;
1190
1100
    state.tableRow.cells << cell;
1191
 
    cell.bgcolor        = -1;
 
1101
    cell.bgcolor = -1;
1192
1102
 
1193
 
    for (uint i=0; i < 4; i++)
1194
 
    {
 
1103
    for (uint i = 0; i < 4; i++) {
1195
1104
        RTFBorder &border = cell.borders[i];
1196
1105
        border.color = -1;
1197
1106
        border.width = 0;
1199
1108
    }
1200
1109
}
1201
1110
 
1202
 
void RTFImport::insertTabDef( RTFProperty * )
 
1111
void RTFImport::insertTabDef(RTFProperty *)
1203
1112
{
1204
1113
    RTFTab tab = state.layout.tab;
1205
 
    tab.position        = token.value;
1206
 
    state.layout.tablist.push( tab );
1207
 
    tab.type            = RTFTab::Left;
1208
 
    tab.leader          = RTFTab::None;
 
1114
    tab.position = token.value;
 
1115
    state.layout.tablist.push(tab);
 
1116
    tab.type  = RTFTab::Left;
 
1117
    tab.leader  = RTFTab::None;
1209
1118
}
1210
1119
 
1211
 
void RTFImport::insertUTF8( int ch )
 
1120
void RTFImport::insertUTF8(int ch)
1212
1121
{
1213
 
    kDebug(30515) <<"insertUTF8:" << ch;
 
1122
    kDebug(30515) << "insertUTF8:" << ch;
1214
1123
    char buf[4];
1215
1124
    char *text = buf;
1216
1125
    char *tk = token.text;
1221
1130
    // - it will be done later
1222
1131
    // - list definitions need to use char(1), char(2)...
1223
1132
    // ### FIXME: for high Unicode values, RTF uses negative values
1224
 
    if (ch > 0x007f)
1225
 
    {
1226
 
        if (ch > 0x07ff)
1227
 
        {
 
1133
    if (ch > 0x007f) {
 
1134
        if (ch > 0x07ff) {
1228
1135
            *text++ = 0xe0 | (ch >> 12);
1229
1136
            ch = (ch & 0xfff) | 0x1000;
1230
1137
        }
1234
1141
    *text++ = ch;
1235
1142
    *text++ = 0;
1236
1143
 
1237
 
    QTextCodec* oldCodec=textCodec;
 
1144
    QTextCodec* oldCodec = textCodec;
1238
1145
 
1239
1146
    if (utf8TextCodec)
1240
 
        textCodec=utf8TextCodec;
 
1147
        textCodec = utf8TextCodec;
1241
1148
    else
1242
1149
        kError(30515) << "No UTF-8 QTextCodec available";
1243
1150
 
1244
1151
    (this->*destination.destproc)(0L);
1245
1152
 
1246
 
    textCodec=oldCodec;
 
1153
    textCodec = oldCodec;
1247
1154
    token.text = tk;
1248
1155
}
1249
1156
 
1250
 
void RTFImport::insertSymbol( RTFProperty *property )
 
1157
void RTFImport::insertSymbol(RTFProperty *property)
1251
1158
{
1252
 
    insertUTF8( property->value );
 
1159
    insertUTF8(property->value);
1253
1160
}
1254
1161
 
1255
 
void RTFImport::insertHexSymbol( RTFProperty * )
 
1162
void RTFImport::insertHexSymbol(RTFProperty *)
1256
1163
{
1257
1164
    //kDebug(30515) <<"insertHexSymbol:" << token.value;
1258
1165
 
1261
1168
 
1262
1169
    // Some files have \'00 which is pretty bad, as NUL is end of string for us.
1263
1170
    // (e.g. attachment #7758 of bug #90649)
1264
 
    if ( !token.value )
1265
 
    {
 
1171
    if (!token.value) {
1266
1172
        kWarning(30515) << "Trying to insert NUL character!";
1267
1173
        return;
1268
1174
    }
1278
1184
    token.text = tk;
1279
1185
}
1280
1186
 
1281
 
void RTFImport::insertUnicodeSymbol( RTFProperty * )
 
1187
void RTFImport::insertUnicodeSymbol(RTFProperty *)
1282
1188
{
1283
1189
    const int ch = token.value;
1284
1190
 
1285
1191
    // Ignore the next N characters (or control words)
1286
 
    for (uint i=state.format.uc; i > 0; )
1287
 
    {
 
1192
    for (uint i = state.format.uc; i > 0;) {
1288
1193
        token.next();
1289
1194
 
1290
1195
        if (token.type == RTFTokenizer::ControlWord)
1291
 
            --i;        // Ignore as single token
 
1196
            --i; // Ignore as single token
1292
1197
        else if (token.type == RTFTokenizer::OpenGroup ||
1293
 
                 token.type == RTFTokenizer::CloseGroup)
1294
 
        {
 
1198
                 token.type == RTFTokenizer::CloseGroup) {
1295
1199
            break;
1296
 
        }
1297
 
        else if (token.type == RTFTokenizer::PlainText)
1298
 
        {
1299
 
            const uint len = qstrlen( token.text );
1300
 
            if ( len < i )
 
1200
        } else if (token.type == RTFTokenizer::PlainText) {
 
1201
            const uint len = qstrlen(token.text);
 
1202
            if (len < i)
1301
1203
                i -= len;
1302
 
            else
1303
 
            {
 
1204
            else {
1304
1205
                token.text += i;
1305
1206
                break;
1306
1207
            }
1307
1208
        }
1308
1209
    }
1309
 
    if (token.type != RTFTokenizer::PlainText)
1310
 
    {
 
1210
    if (token.type != RTFTokenizer::PlainText) {
1311
1211
        token.type = RTFTokenizer::PlainText;
1312
1212
        token.text[0] = 0;
1313
1213
    }
1314
 
    insertUTF8( ch ); // ### TODO: put it higher in this function
 
1214
    insertUTF8(ch);   // ### TODO: put it higher in this function
1315
1215
    (this->*destination.destproc)(0L);
1316
1216
}
1317
1217
 
1318
 
void RTFImport::parseFontTable( RTFProperty * )
 
1218
void RTFImport::parseFontTable(RTFProperty *)
1319
1219
{
1320
 
    if (token.type == RTFTokenizer::OpenGroup)
1321
 
    {
 
1220
    if (token.type == RTFTokenizer::OpenGroup) {
1322
1221
        font.name.clear();
1323
1222
        font.styleHint = QFont::AnyStyle;
1324
1223
        font.fixedPitch = 0;
1325
 
    }
1326
 
    else if (token.type == RTFTokenizer::PlainText)
1327
 
    {
1328
 
        if (!textCodec)
1329
 
        {
 
1224
    } else if (token.type == RTFTokenizer::PlainText) {
 
1225
        if (!textCodec) {
1330
1226
            kError(30515) << "No text codec for font!";
1331
1227
            return; // We have no text codec, so we cannot proceed!
1332
1228
        }
1333
1229
        // ### TODO VERIFY: a RTF group could be in the middle of the font name
1334
1230
        // ### TODO VERIFY:  I do not now if it is specified in RTF but attachment #7758 of bug #90649 has it.
1335
1231
        // Semicolons separate fonts
1336
 
        if (strchr( token.text, ';' ) == 0L) // ### TODO: is this allowed with multi-byte Asian characters?
1337
 
            font.name += textCodec->toUnicode( token.text );
1338
 
        else
1339
 
        {
 
1232
        if (strchr(token.text, ';') == 0L)   // ### TODO: is this allowed with multi-byte Asian characters?
 
1233
            font.name += textCodec->toUnicode(token.text);
 
1234
        else {
1340
1235
            // Add font to font table
1341
 
            *strchr( token.text, ';' ) = 0; // ### TODO: is this allowed with multi-byte Asian characters?
1342
 
            font.name += textCodec->toUnicode( token.text );
 
1236
            *strchr(token.text, ';') = 0;   // ### TODO: is this allowed with multi-byte Asian characters?
 
1237
            font.name += textCodec->toUnicode(token.text);
1343
1238
            // Use Qt to look up the closest matching installed font
1344
 
            QFont qFont( font.name );
1345
 
            qFont.setFixedPitch( (font.fixedPitch == 1) );
1346
 
            qFont.setStyleHint( font.styleHint );
1347
 
            for(;!qFont.exactMatch();)
1348
 
            {
1349
 
                int space=font.name.lastIndexOf(' ', font.name.length());
1350
 
                if(space==-1)
 
1239
            QFont qFont(font.name);
 
1240
            qFont.setFixedPitch((font.fixedPitch == 1));
 
1241
            qFont.setStyleHint(font.styleHint);
 
1242
            for (;!qFont.exactMatch();) {
 
1243
                int space = font.name.lastIndexOf(' ', font.name.length());
 
1244
                if (space == -1)
1351
1245
                    break;
1352
1246
                font.name.truncate(space);
1353
 
                qFont.setFamily( font.name );
 
1247
                qFont.setFamily(font.name);
1354
1248
            }
1355
 
            const QFontInfo info( qFont );
1356
 
            const QString newFontName ( info.family() );
1357
 
            kDebug(30515) <<"Font" << state.format.font <<" asked:" << font.name <<" given:" << newFontName;
 
1249
            const QFontInfo info(qFont);
 
1250
            const QString newFontName(info.family());
 
1251
            kDebug(30515) << "Font" << state.format.font << " asked:" << font.name << " given:" << newFontName;
1358
1252
 
1359
 
            if ( newFontName.isEmpty() )
1360
 
               fontTable.insert(  state.format.font, font.name );
 
1253
            if (newFontName.isEmpty())
 
1254
                fontTable.insert(state.format.font, font.name);
1361
1255
            else
1362
 
               fontTable.insert( state.format.font, newFontName );
1363
 
            font.name.truncate( 0 );
 
1256
                fontTable.insert(state.format.font, newFontName);
 
1257
            font.name.truncate(0);
1364
1258
            font.styleHint = QFont::AnyStyle;
1365
1259
            font.fixedPitch = 0;
1366
1260
        }
1367
1261
    }
1368
1262
}
1369
1263
 
1370
 
void RTFImport::parseStyleSheet( RTFProperty * )
 
1264
void RTFImport::parseStyleSheet(RTFProperty *)
1371
1265
{
1372
 
    if (token.type == RTFTokenizer::OpenGroup)
1373
 
    {
 
1266
    if (token.type == RTFTokenizer::OpenGroup) {
1374
1267
        style.name = "";
1375
1268
        style.next = -1;
1376
 
    }
1377
 
    else if (token.type == RTFTokenizer::PlainText)
1378
 
    {
 
1269
    } else if (token.type == RTFTokenizer::PlainText) {
1379
1270
        // Semicolons separate styles
1380
 
        if (strchr( token.text, ';' ) == 0L) // ### TODO: is this allowed with multi-byte Asian characters?
1381
 
            style.name += textCodec->toUnicode( token.text );
1382
 
        else
1383
 
        {
 
1271
        if (strchr(token.text, ';') == 0L)   // ### TODO: is this allowed with multi-byte Asian characters?
 
1272
            style.name += textCodec->toUnicode(token.text);
 
1273
        else {
1384
1274
            // Add style to style sheet
1385
 
            *strchr( token.text, ';' ) = 0; // ### TODO: is this allowed with multi-byte Asian characters?
1386
 
            style.name  += textCodec->toUnicode( token.text );
 
1275
            *strchr(token.text, ';') = 0;   // ### TODO: is this allowed with multi-byte Asian characters?
 
1276
            style.name  += textCodec->toUnicode(token.text);
1387
1277
            style.format = state.format;
1388
1278
            style.layout = state.layout;
1389
1279
            style.next   = (style.next == -1) ? style.layout.style : style.next;
1390
1280
            styleSheet << style;
1391
 
            style.name.truncate( 0 );
 
1281
            style.name.truncate(0);
1392
1282
            style.next   = -1;
1393
1283
        }
1394
1284
    }
1395
1285
}
1396
1286
 
1397
 
void RTFImport::parseColorTable( RTFProperty * )
 
1287
void RTFImport::parseColorTable(RTFProperty *)
1398
1288
{
1399
 
    if (token.type == RTFTokenizer::OpenGroup)
1400
 
    {
 
1289
    if (token.type == RTFTokenizer::OpenGroup) {
1401
1290
        red = 0;
1402
1291
        green = 0;
1403
1292
        blue = 0;
1404
 
    }
1405
 
    else if (token.type == RTFTokenizer::PlainText)
1406
 
    {
 
1293
    } else if (token.type == RTFTokenizer::PlainText) {
1407
1294
        // Note: the color table can be a simple ; character only, especially in PWD files
1408
1295
        // Search for semicolon(s)
1409
 
        while ((token.text = strchr( token.text, ';' )))
1410
 
        {
1411
 
            colorTable << QColor( red, green, blue );
 
1296
        while ((token.text = strchr(token.text, ';'))) {
 
1297
            colorTable << QColor(red, green, blue);
1412
1298
            red = green = blue = 0;
1413
1299
            ++token.text;
1414
1300
        }
1415
1301
    }
1416
1302
}
1417
1303
 
1418
 
void RTFImport::parseBlipUid( RTFProperty * )
 
1304
void RTFImport::parseBlipUid(RTFProperty *)
1419
1305
{
1420
 
    if (token.type == RTFTokenizer::OpenGroup)
1421
 
    {
 
1306
    if (token.type == RTFTokenizer::OpenGroup) {
1422
1307
        picture.identifier.clear();
1423
 
    }
1424
 
    else if (token.type == RTFTokenizer::PlainText)
1425
 
    {
1426
 
        picture.identifier += QString::fromUtf8( token.text );
1427
 
    }
1428
 
    else if (token.type == RTFTokenizer::CloseGroup)
1429
 
    {
1430
 
        kDebug(30515) <<"\\blipuid:" << picture.identifier;
 
1308
    } else if (token.type == RTFTokenizer::PlainText) {
 
1309
        picture.identifier += QString::fromUtf8(token.text);
 
1310
    } else if (token.type == RTFTokenizer::CloseGroup) {
 
1311
        kDebug(30515) << "\\blipuid:" << picture.identifier;
1431
1312
    }
1432
1313
}
1433
1314
 
1434
 
void RTFImport::parsePicture( RTFProperty * )
 
1315
void RTFImport::parsePicture(RTFProperty *)
1435
1316
{
1436
1317
    if (state.ignoreGroup)
1437
1318
        return;
1438
1319
 
1439
 
    if (token.type == RTFTokenizer::OpenGroup)
1440
 
    {
1441
 
        picture.type            = RTFPicture::PNG;
1442
 
        picture.width           = 0;
1443
 
        picture.height          = 0;
1444
 
        picture.desiredWidth    = 0;
1445
 
        picture.desiredHeight   = 0;
1446
 
        picture.scalex          = 100; // Default is 100%
1447
 
        picture.scaley          = 100; // Default is 100%
1448
 
        picture.cropLeft        = 0;
1449
 
        picture.cropTop         = 0;
1450
 
        picture.cropRight       = 0;
1451
 
        picture.cropBottom      = 0;
1452
 
        picture.nibble          = 0;
1453
 
        picture.bits.truncate( 0 );
 
1320
    if (token.type == RTFTokenizer::OpenGroup) {
 
1321
        picture.type  = RTFPicture::PNG;
 
1322
        picture.width  = 0;
 
1323
        picture.height  = 0;
 
1324
        picture.desiredWidth = 0;
 
1325
        picture.desiredHeight = 0;
 
1326
        picture.scalex  = 100; // Default is 100%
 
1327
        picture.scaley  = 100; // Default is 100%
 
1328
        picture.cropLeft = 0;
 
1329
        picture.cropTop  = 0;
 
1330
        picture.cropRight = 0;
 
1331
        picture.cropBottom = 0;
 
1332
        picture.nibble  = 0;
 
1333
        picture.bits.truncate(0);
1454
1334
        picture.identifier.clear();
1455
 
    }
1456
 
    else if (token.type == RTFTokenizer::PlainText)
1457
 
    {
1458
 
        if (picture.nibble)
1459
 
        {
 
1335
    } else if (token.type == RTFTokenizer::PlainText) {
 
1336
        if (picture.nibble) {
1460
1337
            *(--token.text) = picture.nibble;
1461
1338
        }
1462
 
        uint n = qstrlen( token.text ) >> 1;
1463
 
        picture.bits.resize( picture.bits.size() + n );
 
1339
        uint n = qstrlen(token.text) >> 1;
 
1340
        picture.bits.resize(picture.bits.size() + n);
1464
1341
        char *src = token.text;
1465
1342
        char *dst = (picture.bits.data() + picture.bits.size() - n);
1466
1343
 
1467
1344
        // Store hexadecimal data
1468
 
        while (n-- > 0)
1469
 
        {
 
1345
        while (n-- > 0) {
1470
1346
            int k = *src++;
1471
1347
            int l = *src++;
1472
1348
            *dst++ = (((k + ((k & 16) ? 0 : 9)) & 0xf) << 4) |
1473
 
                      ((l + ((l & 16) ? 0 : 9)) & 0xf);
 
1349
                     ((l + ((l & 16) ? 0 : 9)) & 0xf);
1474
1350
        }
1475
1351
        picture.nibble = *src;
1476
 
    }
1477
 
    else if (token.type == RTFTokenizer::BinaryData)
1478
 
    {
 
1352
    } else if (token.type == RTFTokenizer::BinaryData) {
1479
1353
        picture.bits = token.binaryData;
1480
 
        kDebug(30515) <<"Binary data of length:" << picture.bits.size();
1481
 
    }
1482
 
    else if (token.type == RTFTokenizer::CloseGroup)
1483
 
    {
 
1354
        kDebug(30515) << "Binary data of length:" << picture.bits.size();
 
1355
    } else if (token.type == RTFTokenizer::CloseGroup) {
1484
1356
        const char *ext;
1485
1357
 
1486
1358
        // Select file extension based on picture type
1487
 
        switch (picture.type)
1488
 
        {
 
1359
        switch (picture.type) {
1489
1360
        case RTFPicture::WMF:
1490
1361
        case RTFPicture::EMF:
1491
1362
            ext = ".wmf";
1514
1385
        frameName.prepend("Picture ");
1515
1386
 
1516
1387
        QString idStr;
1517
 
        if (picture.identifier.isEmpty())
1518
 
        {
 
1388
        if (picture.identifier.isEmpty()) {
1519
1389
            idStr = pictName;
1520
 
        }
1521
 
        else
1522
 
        {
 
1390
        } else {
1523
1391
            idStr += picture.identifier.trimmed();
1524
1392
            idStr += ext;
1525
1393
        }
1526
1394
 
1527
 
        kDebug(30515) <<"Picture:" << pictName <<" Frame:" << frameName;
 
1395
        kDebug(30515) << "Picture:" << pictName << " Frame:" << frameName;
1528
1396
 
1529
1397
        // Store picture
1530
 
        KoStoreDevice* dev = m_chain->storageFile( pictName, KoStore::Write );
1531
 
        if ( dev )
1532
 
            dev->write(picture.bits.data(),picture.bits.size());
 
1398
        KoStoreDevice* dev = m_chain->storageFile(pictName, KoStore::Write);
 
1399
        if (dev)
 
1400
            dev->write(picture.bits.data(), picture.bits.size());
1533
1401
        else
1534
1402
            kError(30515) << "Could not save: " << pictName;
1535
1403
 
1536
1404
 
1537
1405
        // Add anchor to rich text destination
1538
 
        addAnchor( frameName );
 
1406
        addAnchor(frameName);
1539
1407
 
1540
1408
        // It is safe, as we call currentDateTime only once for each picture
1541
1409
        const QDateTime dt(QDateTime::currentDateTime());
1542
1410
 
1543
1411
        // Add pixmap or clipart (key)
1544
 
        pictures.addKey( dt, idStr, pictName );
 
1412
        pictures.addKey(dt, idStr, pictName);
1545
1413
 
1546
1414
        // Add picture or clipart frameset
1547
 
        frameSets.addFrameSet( frameName, 2, 0 );
 
1415
        frameSets.addFrameSet(frameName, 2, 0);
1548
1416
        //kDebug(30515) <<"Width:" << picture.desiredWidth <<" scalex:" << picture.scalex <<"%";
1549
1417
        //kDebug(30515) <<"Height:" << picture.desiredHeight<<" scaley:" << picture.scaley <<"%";
1550
 
        frameSets.addFrame( 0, 0,
1551
 
                (picture.desiredWidth  * picture.scalex) /100 ,
1552
 
                (picture.desiredHeight * picture.scaley) /100 , 0, 1, 0 );
1553
 
        frameSets.closeNode( "FRAME" );
1554
 
        frameSets.addNode( "PICTURE" );
1555
 
        frameSets.addKey( dt, idStr );
1556
 
        frameSets.closeNode( "PICTURE" );
1557
 
        frameSets.closeNode( "FRAMESET" );
 
1418
        frameSets.addFrame(0, 0,
 
1419
                           (picture.desiredWidth  * picture.scalex) / 100 ,
 
1420
                           (picture.desiredHeight * picture.scaley) / 100 , 0, 1, 0);
 
1421
        frameSets.closeNode("FRAME");
 
1422
        frameSets.addNode("PICTURE");
 
1423
        frameSets.addKey(dt, idStr);
 
1424
        frameSets.closeNode("PICTURE");
 
1425
        frameSets.closeNode("FRAMESET");
1558
1426
        picture.identifier.clear();
1559
1427
    }
1560
1428
}
1561
1429
 
1562
 
void RTFImport::addImportedPicture( const QString& rawFileName )
 
1430
void RTFImport::addImportedPicture(const QString& rawFileName)
1563
1431
{
1564
 
    kDebug(30515) <<"Import field: reading" << rawFileName;
 
1432
    kDebug(30515) << "Import field: reading" << rawFileName;
1565
1433
 
1566
 
    if (rawFileName=="\\*")
1567
 
    {
 
1434
    if (rawFileName == "\\*") {
1568
1435
        kError(30515) << "Import field without file name!";
1569
1436
        return;
1570
1437
    }
1571
1438
 
1572
 
    QString slashPath( rawFileName );
1573
 
    slashPath.replace('\\','/'); // Replace directory separators.
 
1439
    QString slashPath(rawFileName);
 
1440
    slashPath.replace('\\', '/'); // Replace directory separators.
1574
1441
    // ### TODO: what with MS-DOS absolute paths? (Will only work for KOffice on Win32)
1575
1442
    QFileInfo info;
1576
 
    info.setFile( inFileName );
1577
 
    QDir dir( info.path() );
 
1443
    info.setFile(inFileName);
 
1444
    QDir dir(info.path());
1578
1445
 
1579
1446
    KUrl url;
1580
 
    url.setPath(dir.filePath( rawFileName ));
1581
 
 
1582
 
    kDebug(30515) <<"Path:" << url.prettyUrl();
1583
 
 
1584
 
    KoPicture pic;
 
1447
    url.setPath(dir.filePath(rawFileName));
 
1448
 
 
1449
    kDebug(30515) << "Path:" << url.prettyUrl();
 
1450
 
 
1451
    Picture pic;
1585
1452
    pic.setKeyAndDownloadPicture(url, 0); // ### TODO: find a better parent if possible
1586
 
    if (pic.isNull())
1587
 
    {
 
1453
    if (pic.isNull()) {
1588
1454
        kError(30515) << "Import field: file is empty: " << rawFileName;
1589
1455
        return;
1590
1456
    }
1601
1467
    frameName.prepend("Picture ");
1602
1468
 
1603
1469
 
1604
 
    kDebug(30515) <<"Imported picture:" << pictName <<" Frame:" << frameName;
 
1470
    kDebug(30515) << "Imported picture:" << pictName << " Frame:" << frameName;
1605
1471
 
1606
1472
    // Store picture
1607
 
    KoStoreDevice* dev = m_chain->storageFile( pictName, KoStore::Write );
1608
 
    if ( dev )
 
1473
    KoStoreDevice* dev = m_chain->storageFile(pictName, KoStore::Write);
 
1474
    if (dev)
1609
1475
        pic.save(dev);
1610
1476
    else
1611
1477
        kError(30515) << "Could not save: " << pictName;
1612
1478
 
1613
1479
    // Add anchor to rich text destination
1614
 
    addAnchor( frameName );
 
1480
    addAnchor(frameName);
1615
1481
 
1616
1482
    // It is safe, as we call currentDateTime only once for each picture
1617
 
    const QDateTime dt( pic.getKey().lastModified() );
 
1483
    const QDateTime dt(pic.getKey().lastModified());
1618
1484
 
1619
1485
    // Add picture key
1620
 
    pictures.addKey( dt, rawFileName, pictName );
 
1486
    pictures.addKey(dt, rawFileName, pictName);
1621
1487
 
1622
1488
    // Add picture frameset
1623
 
    const QSize size ( pic.getOriginalSize() * 20 );  // We need twips for addFrame
1624
 
    frameSets.addFrameSet( frameName, 2, 0 );
1625
 
    frameSets.addFrame( 0, 0, size.width(), size.height(), 0, 1, 0 );
1626
 
    frameSets.closeNode( "FRAME" );
1627
 
    frameSets.addNode( "PICTURE" );
1628
 
    frameSets.addKey( dt, rawFileName );
1629
 
    frameSets.closeNode( "PICTURE" );
1630
 
    frameSets.closeNode( "FRAMESET" );
 
1489
    const QSize size(pic.getOriginalSize() * 20);     // We need twips for addFrame
 
1490
    frameSets.addFrameSet(frameName, 2, 0);
 
1491
    frameSets.addFrame(0, 0, size.width(), size.height(), 0, 1, 0);
 
1492
    frameSets.closeNode("FRAME");
 
1493
    frameSets.addNode("PICTURE");
 
1494
    frameSets.addKey(dt, rawFileName);
 
1495
    frameSets.closeNode("PICTURE");
 
1496
    frameSets.closeNode("FRAMESET");
1631
1497
}
1632
1498
 
1633
 
void RTFImport::insertPageNumber( RTFProperty * )
 
1499
void RTFImport::insertPageNumber(RTFProperty *)
1634
1500
{
1635
1501
    DomNode node;
1636
 
    node.addNode( "PGNUM" );
1637
 
    node.setAttribute( "subtype", 0 );
1638
 
    node.setAttribute( "value", 0 );
 
1502
    node.addNode("PGNUM");
 
1503
    node.setAttribute("subtype", 0);
 
1504
    node.setAttribute("value", 0);
1639
1505
    node.closeNode("PGNUM");
1640
 
    addVariable( node, 4, "NUMBER", &state.format);
1641
 
}
1642
 
 
1643
 
void RTFImport::insertDateTime( RTFProperty *property )
1644
 
{
1645
 
    kDebug(30515) <<"insertDateTime:" << property->value;
1646
 
    addDateTime( QString(), bool(property->value), state.format );
1647
 
}
1648
 
 
1649
 
void RTFImport::addDateTime( const QString& format, const bool isDate, RTFFormat& fmt )
1650
 
{
1651
 
    bool asDate=isDate; // Should the variable be a date variable?
 
1506
    addVariable(node, 4, "NUMBER", &state.format);
 
1507
}
 
1508
 
 
1509
void RTFImport::insertDateTime(RTFProperty *property)
 
1510
{
 
1511
    kDebug(30515) << "insertDateTime:" << property->value;
 
1512
    addDateTime(QString(), bool(property->value), state.format);
 
1513
}
 
1514
 
 
1515
void RTFImport::addDateTime(const QString& format, const bool isDate, RTFFormat& fmt)
 
1516
{
 
1517
    bool asDate = isDate; // Should the variable be a date variable?
1652
1518
    QString kwordFormat(format);
1653
 
    if (format.isEmpty())
1654
 
    {
 
1519
    if (format.isEmpty()) {
1655
1520
        if (isDate)
1656
1521
            kwordFormat = "DATElocale";
1657
1522
        else
1658
1523
            kwordFormat = "TIMElocale";
1659
 
    }
1660
 
    else if (!isDate)
1661
 
    {
 
1524
    } else if (!isDate) {
1662
1525
        // It is a time with a specified format, so check if it is really a time
1663
1526
        // (as in KWord 1.3, a date can have a time format but a time cannot have a date format
1664
 
        const QRegExp regexp ("[yMd]"); // any date format character?
1665
 
        asDate = (regexp.indexIn(format)>-1);  // if yes, then it is a date
 
1527
        const QRegExp regexp("[yMd]");  // any date format character?
 
1528
        asDate = (regexp.indexIn(format) > -1);  // if yes, then it is a date
1666
1529
    }
1667
1530
    DomNode node;
1668
 
    if (asDate)
1669
 
    {
 
1531
    if (asDate) {
1670
1532
        node.clear(7);
1671
1533
        node.addNode("DATE");
1672
1534
        node.setAttribute("year", 0);
1675
1537
        node.setAttribute("fix", 0);
1676
1538
        node.closeNode("DATE");
1677
1539
        addVariable(node, 0, kwordFormat, &fmt);
1678
 
    }
1679
 
    else
1680
 
    {
 
1540
    } else {
1681
1541
        node.clear(7);
1682
1542
        node.addNode("TIME");
1683
1543
        node.setAttribute("hour", 0);
1689
1549
    }
1690
1550
}
1691
1551
 
1692
 
void RTFImport::parseField( RTFProperty * )
 
1552
void RTFImport::parseField(RTFProperty *)
1693
1553
{
1694
 
    if (token.type == RTFTokenizer::OpenGroup)
1695
 
    {
1696
 
        if (flddst == -1)
1697
 
        {
 
1554
    if (token.type == RTFTokenizer::OpenGroup) {
 
1555
        if (flddst == -1) {
1698
1556
            // Destination for unsupported fields
1699
1557
            flddst = (destinationStack.count() - 1);
1700
1558
        }
1701
1559
        fldinst = "";
1702
1560
        fldrslt = "";
1703
1561
        destination.group = 0L;
1704
 
    }
1705
 
    else if (token.type == RTFTokenizer::CloseGroup)
1706
 
    {
1707
 
        if (!fldinst.isEmpty())
1708
 
        {
 
1562
    } else if (token.type == RTFTokenizer::CloseGroup) {
 
1563
        if (!fldinst.isEmpty()) {
1709
1564
            DomNode node;
1710
 
            QString strFldinst( QString::fromUtf8(fldinst) );
1711
 
            QStringList list = strFldinst.split( ' ', QString::SkipEmptyParts );
1712
 
            kDebug(30515) <<"Field:" << list;
 
1565
            QString strFldinst(QString::fromUtf8(fldinst));
 
1566
            QStringList list = strFldinst.split(' ', QString::SkipEmptyParts);
 
1567
            kDebug(30515) << "Field:" << list;
1713
1568
            uint i;
1714
1569
 
1715
 
            QString fieldName ( list[0].toUpper() );
 
1570
            QString fieldName(list[0].toUpper());
1716
1571
            fieldName.remove('\\'); // Remove \, especialy leading ones in OOWriter RTF files
1717
1572
            node.clear(7);
1718
1573
 
1719
 
                bool ok=false;
1720
 
            for (i=0; i < sizeof(fieldTable) /sizeof(fieldTable[0]); i++)
1721
 
            {
1722
 
                if (fieldName == fieldTable[i].id)
1723
 
                {
1724
 
                    kDebug(30515) <<"Field found:" << fieldTable[i].id;
1725
 
                    ok=true;
 
1574
            bool ok = false;
 
1575
            for (i = 0; i < sizeof(fieldTable) / sizeof(fieldTable[0]); i++) {
 
1576
                if (fieldName == fieldTable[i].id) {
 
1577
                    kDebug(30515) << "Field found:" << fieldTable[i].id;
 
1578
                    ok = true;
1726
1579
                    break;
1727
1580
                }
1728
1581
            }
1729
 
                if (!ok)
1730
 
                {
1731
 
                    kWarning(30515) << "Field not supported: " << fieldName;
1732
 
                    return;
1733
 
                }
1734
 
            if (fieldTable[i].type == 4)
1735
 
            {
1736
 
                node.addNode( "PGNUM" );
1737
 
                node.setAttribute( "subtype", fieldTable[i].subtype );
1738
 
                node.setAttribute( "value", 0 );
 
1582
            if (!ok) {
 
1583
                kWarning(30515) << "Field not supported: " << fieldName;
 
1584
                return;
 
1585
            }
 
1586
            if (fieldTable[i].type == 4) {
 
1587
                node.addNode("PGNUM");
 
1588
                node.setAttribute("subtype", fieldTable[i].subtype);
 
1589
                node.setAttribute("value", 0);
1739
1590
                node.closeNode("PGNUM");
1740
 
                addVariable( node, 4, "NUMBER", &fldfmt);
1741
 
            }
1742
 
            else if (fieldTable[i].type == 8)
1743
 
            {
1744
 
                node.addNode( "FIELD" );
1745
 
                node.setAttribute( "subtype", fieldTable[i].subtype );
1746
 
                node.setAttribute( "value", fieldTable[i].value );
 
1591
                addVariable(node, 4, "NUMBER", &fldfmt);
 
1592
            } else if (fieldTable[i].type == 8) {
 
1593
                node.addNode("FIELD");
 
1594
                node.setAttribute("subtype", fieldTable[i].subtype);
 
1595
                node.setAttribute("value", fieldTable[i].value);
1747
1596
                node.closeNode("FIELD");
1748
 
                addVariable( node, 8, "STRING", &fldfmt);
1749
 
            }
1750
 
            else if (fieldTable[i].type == 9)
1751
 
            {
 
1597
                addVariable(node, 8, "STRING", &fldfmt);
 
1598
            } else if (fieldTable[i].type == 9) {
1752
1599
                QString hrefName;
1753
1600
 
1754
1601
                // Use ConstIterator
1755
 
                for (int i=1; i < list.count(); i++)
1756
 
                {
1757
 
                    if (list[i] == "\\l")
1758
 
                    {
 
1602
                for (int i = 1; i < list.count(); i++) {
 
1603
                    if (list[i] == "\\l") {
1759
1604
                        hrefName += '#';
1760
 
                    }
1761
 
                    else if (list[i].startsWith( '"' ) && list[i].endsWith( '"' ))
1762
 
                    {
1763
 
                        hrefName += list[i].mid( 1, (list[i].length() - 2) );
1764
 
                    }
1765
 
                    else if (list[i].startsWith("http"))
1766
 
                    {
 
1605
                    } else if (list[i].startsWith('"') && list[i].endsWith('"')) {
 
1606
                        hrefName += list[i].mid(1, (list[i].length() - 2));
 
1607
                    } else if (list[i].startsWith("http")) {
1767
1608
                        hrefName += list[i];
1768
1609
                    }
1769
1610
                }
1770
 
                node.addNode( "LINK" );
1771
 
                node.setAttribute( "linkName", QString::fromLatin1( fldrslt ) );
1772
 
                node.setAttribute( "hrefName", hrefName );
1773
 
                node.closeNode( "LINK" );
1774
 
                addVariable( node, 9, "STRING", &fldfmt);
1775
 
            }
1776
 
            else if (fieldName == "SYMBOL")
1777
 
            {
1778
 
                if (list.count() >= 2)
1779
 
                {
 
1611
                node.addNode("LINK");
 
1612
                node.setAttribute("linkName", QString::fromLatin1(fldrslt));
 
1613
                node.setAttribute("hrefName", hrefName);
 
1614
                node.closeNode("LINK");
 
1615
                addVariable(node, 9, "STRING", &fldfmt);
 
1616
            } else if (fieldName == "SYMBOL") {
 
1617
                if (list.count() >= 2) {
1780
1618
                    int ch = list[1].toInt();
1781
1619
 
1782
 
                    if (ch > 0)
1783
 
                    {
 
1620
                    if (ch > 0) {
1784
1621
                        // ### TODO: some error control (the destination might be invalid!)
1785
1622
                        destination = destinationStack[flddst];
1786
1623
                        state.format = fldfmt;
1787
 
                        insertUTF8( ch );
 
1624
                        insertUTF8(ch);
1788
1625
                    }
1789
1626
                }
1790
 
            }
1791
 
            else if (fieldName == "TIME" || fieldName == "DATE")
1792
 
            {
1793
 
                QString strFldinst( QString::fromUtf8(fldinst) );
 
1627
            } else if (fieldName == "TIME" || fieldName == "DATE") {
 
1628
                QString strFldinst(QString::fromUtf8(fldinst));
1794
1629
                QRegExp regexp("\\\\@\\s*\"(.+)\""); // \@ "Text"
1795
 
                if (regexp.indexIn(strFldinst)==-1)
1796
 
                { // Not found? Perhaps it is not in quotes (even if it is rare)
 
1630
                if (regexp.indexIn(strFldinst) == -1) { // Not found? Perhaps it is not in quotes (even if it is rare)
1797
1631
                    kWarning(30515) << "Date/time field format not in quotes!";
1798
1632
                    strFldinst += ' '; // Add a space at the end to simplify the regular expression
1799
1633
                    regexp = QRegExp("\\\\@(\\S+)\\s+"); // \@some_text_up_to_a_space
1800
1634
                    regexp.indexIn(strFldinst);
1801
1635
                }
1802
1636
                QString format(regexp.cap(1));
1803
 
                kDebug(30515) <<"Date/time field format:" << format;
 
1637
                kDebug(30515) << "Date/time field format:" << format;
1804
1638
                format.replace("am/pm", "ap");
1805
1639
                format.replace("a/p", "ap"); // Approximation
1806
1640
                format.replace("AM/PM", "AP");
1807
1641
                format.replace("A/P", "AP"); // Approximation
1808
1642
                format.remove("'"); // KWord 1.3 cannot protect text in date/time
1809
 
                addDateTime( format, (fieldName == "DATE"), fldfmt );
1810
 
            }
1811
 
            else if (fieldName == "IMPORT")
1812
 
            {
1813
 
                addImportedPicture( list[1] );
 
1643
                addDateTime(format, (fieldName == "DATE"), fldfmt);
 
1644
            } else if (fieldName == "IMPORT") {
 
1645
                addImportedPicture(list[1]);
1814
1646
            }
1815
1647
 
1816
1648
            fldinst = "";
1817
1649
        }
1818
1650
 
1819
 
        if (flddst == (int) (destinationStack.count() - 1))
1820
 
        {
 
1651
        if (flddst == (int)(destinationStack.count() - 1)) {
1821
1652
            // Top-level field closed, clear field destination
1822
1653
            flddst = -1;
1823
1654
        }
1824
1655
    }
1825
1656
}
1826
1657
 
1827
 
void RTFImport::parseFldinst( RTFProperty * )
 
1658
void RTFImport::parseFldinst(RTFProperty *)
1828
1659
{
1829
 
    if (token.type == RTFTokenizer::OpenGroup)
1830
 
    {
 
1660
    if (token.type == RTFTokenizer::OpenGroup) {
1831
1661
        fldinst = "";
1832
 
    }
1833
 
    else if (token.type == RTFTokenizer::PlainText)
1834
 
    {
 
1662
    } else if (token.type == RTFTokenizer::PlainText) {
1835
1663
        fldinst += token.text;
1836
1664
    }
1837
1665
}
1838
1666
 
1839
 
void RTFImport::parseFldrslt( RTFProperty * )
 
1667
void RTFImport::parseFldrslt(RTFProperty *)
1840
1668
{
1841
 
    if (fldinst.isEmpty())
1842
 
    {
1843
 
        if (token.type == RTFTokenizer::OpenGroup)
1844
 
        {
 
1669
    if (fldinst.isEmpty()) {
 
1670
        if (token.type == RTFTokenizer::OpenGroup) {
1845
1671
            // ### TODO: why is this destination change not done with the corresponding procedure "changeDestination"?
1846
1672
            destination = destinationStack[flddst];
1847
1673
            destination.destproc = &RTFImport::parseFldrslt;
1848
 
        }
1849
 
        else if (token.type != RTFTokenizer::CloseGroup)
1850
 
        {
 
1674
        } else if (token.type != RTFTokenizer::CloseGroup) {
1851
1675
            (this->*destinationStack[flddst].destproc)(0L);
1852
1676
        }
1853
 
    }
1854
 
    else if (token.type == RTFTokenizer::OpenGroup)
1855
 
    {
 
1677
    } else if (token.type == RTFTokenizer::OpenGroup) {
1856
1678
        fldrslt = "";
1857
 
    }
1858
 
    else if (token.type == RTFTokenizer::PlainText)
1859
 
    {
 
1679
    } else if (token.type == RTFTokenizer::PlainText) {
1860
1680
        fldrslt += token.text;
1861
 
    }
1862
 
    else if (token.type == RTFTokenizer::CloseGroup)
1863
 
    {
 
1681
    } else if (token.type == RTFTokenizer::CloseGroup) {
1864
1682
        fldfmt = state.format;
1865
1683
    }
1866
1684
}
1867
1685
 
1868
 
void RTFImport::addVariable (const DomNode& spec, int type, const QString& key, const RTFFormat* fmt)
 
1686
void RTFImport::addVariable(const DomNode& spec, int type, const QString& key, const RTFFormat* fmt)
1869
1687
{
1870
1688
    DomNode node;
1871
1689
 
1872
 
    node.clear( 6 );
1873
 
    node.addNode( "VARIABLE" );
 
1690
    node.clear(6);
 
1691
    node.addNode("VARIABLE");
1874
1692
    node.closeTag(true);
1875
 
        node.addNode("TYPE");
1876
 
        node.setAttribute( "type", type );
1877
 
        node.setAttribute( "key", CheckAndEscapeXmlText(key) );
1878
 
        node.setAttribute( "text", 1 );
1879
 
        node.closeNode("TYPE");
 
1693
    node.addNode("TYPE");
 
1694
    node.setAttribute("type", type);
 
1695
    node.setAttribute("key", CheckAndEscapeXmlText(key));
 
1696
    node.setAttribute("text", 1);
 
1697
    node.closeNode("TYPE");
1880
1698
 
1881
 
        node.appendNode(spec);
1882
 
    node.closeNode( "VARIABLE" );
 
1699
    node.appendNode(spec);
 
1700
    node.closeNode("VARIABLE");
1883
1701
    kwFormat.xmldata = node.toString();
1884
1702
    kwFormat.id  = 4;
1885
1703
    kwFormat.pos = textState->length++;
1886
1704
    kwFormat.len = 1;
1887
1705
    if (fmt)
1888
1706
        kwFormat.fmt = *fmt;
1889
 
    textState->text.append( '#' );
 
1707
    textState->text.append('#');
1890
1708
    textState->formats << kwFormat;
1891
1709
}
1892
1710
 
1893
 
void RTFImport::parseFootNote( RTFProperty * property)
 
1711
void RTFImport::parseFootNote(RTFProperty * property)
1894
1712
{
1895
 
    if(token.type==RTFTokenizer::OpenGroup)
1896
 
    {
1897
 
        RTFTextState* newTextState=new RTFTextState;
 
1713
    if (token.type == RTFTokenizer::OpenGroup) {
 
1714
        RTFTextState* newTextState = new RTFTextState;
1898
1715
        footnotes.append(newTextState);
1899
1716
        fnnum++;
1900
1717
        destination.target = newTextState;
1904
1721
 
1905
1722
        DomNode node;
1906
1723
 
1907
 
        node.clear( 7 );
1908
 
            node.addNode("FOOTNOTE");
1909
 
            node.setAttribute("numberingtype", "auto");
1910
 
            node.setAttribute("notetype", "footnote");
1911
 
            node.setAttribute("frameset", QString::fromLatin1(str));
1912
 
            node.setAttribute("value", fnnum);
1913
 
            node.closeNode("FOOTNOTE");
 
1724
        node.clear(7);
 
1725
        node.addNode("FOOTNOTE");
 
1726
        node.setAttribute("numberingtype", "auto");
 
1727
        node.setAttribute("notetype", "footnote");
 
1728
        node.setAttribute("frameset", QString::fromLatin1(str));
 
1729
        node.setAttribute("value", fnnum);
 
1730
        node.closeNode("FOOTNOTE");
1914
1731
        addVariable(node, 11, "STRING");
1915
1732
    }
1916
1733
    parseRichText(property);
1917
1734
}
1918
1735
 
1919
 
void RTFImport::parseRichText( RTFProperty * )
 
1736
void RTFImport::parseRichText(RTFProperty *)
1920
1737
{
1921
 
    if (token.type == RTFTokenizer::OpenGroup)
1922
 
    {
 
1738
    if (token.type == RTFTokenizer::OpenGroup) {
1923
1739
        // Save and change rich text destination
1924
1740
        RTFTextState *oldState = textState;
1925
1741
        textState = destination.target;
1928
1744
 
1929
1745
        // Initialize rich text state
1930
1746
        textState->text.clear();
1931
 
        textState->node.clear( 3 );
1932
 
        textState->cell.clear( 3 );
 
1747
        textState->node.clear(3);
 
1748
        textState->cell.clear(3);
1933
1749
        textState->formats.clear();
1934
1750
        textState->frameSets.clear();
1935
1751
        textState->rows.clear();
1936
1752
        textState->table  = 0;
1937
1753
        textState->length = 0;
1938
 
    }
1939
 
    else if (token.type == RTFTokenizer::PlainText)
1940
 
    {
 
1754
    } else if (token.type == RTFTokenizer::PlainText) {
1941
1755
        // Ignore hidden text
1942
 
        if (!state.format.hidden)
1943
 
        {
1944
 
            const int len = (token.text[0] < 0) ? 1 : qstrlen( token.text );
 
1756
        if (!state.format.hidden) {
 
1757
            const int len = (token.text[0] < 0) ? 1 : qstrlen(token.text);
1945
1758
 
1946
1759
            // Check and store format changes
1947
 
            if ( textState->formats.isEmpty() ||
1948
 
                textState->formats.last().fmt != state.format ||
1949
 
                ( !textState->formats.last().xmldata.isEmpty() ) )
1950
 
            {
 
1760
            if (textState->formats.isEmpty() ||
 
1761
                    textState->formats.last().fmt != state.format ||
 
1762
                    (!textState->formats.last().xmldata.isEmpty())) {
1951
1763
                kwFormat.fmt = state.format;
1952
1764
                kwFormat.id  = 1;
1953
1765
                kwFormat.pos = textState->length;
1954
1766
                kwFormat.len = len;
1955
1767
                textState->formats << kwFormat;
1956
1768
                kwFormat.xmldata.clear();
1957
 
            }
1958
 
            else
1959
 
            {
 
1769
            } else {
1960
1770
                textState->formats.last().len += len;
1961
1771
            }
1962
1772
            textState->length += len;
1963
 
            textState->text.addTextNode( token.text, textCodec );
 
1773
            textState->text.addTextNode(token.text, textCodec);
1964
1774
        }
1965
 
    }
1966
 
    else if (token.type == RTFTokenizer::CloseGroup)
1967
 
    {
 
1775
    } else if (token.type == RTFTokenizer::CloseGroup) {
1968
1776
        if (textState->length)
1969
1777
            insertParagraph();
1970
1778
        if (textState->table)
1975
1783
    }
1976
1784
}
1977
1785
 
1978
 
void RTFImport::parsePlainText( RTFProperty * )
 
1786
void RTFImport::parsePlainText(RTFProperty *)
1979
1787
{
1980
 
    if (token.type == RTFTokenizer::OpenGroup)
1981
 
    {
 
1788
    if (token.type == RTFTokenizer::OpenGroup) {
1982
1789
        destination.target->node.clear();
1983
 
    }
1984
 
    else if (token.type == RTFTokenizer::PlainText)
1985
 
    {
1986
 
        destination.target->node.addTextNode( token.text, textCodec );
1987
 
    }
1988
 
}
1989
 
 
1990
 
void RTFImport::parseGroup( RTFProperty * )
1991
 
{
1992
 
}
1993
 
 
1994
 
void RTFImport::skipGroup( RTFProperty * )
1995
 
{
1996
 
    kDebug(30515) <<"Skip Group:" << token.type;
 
1790
    } else if (token.type == RTFTokenizer::PlainText) {
 
1791
        destination.target->node.addTextNode(token.text, textCodec);
 
1792
    }
 
1793
}
 
1794
 
 
1795
void RTFImport::parseGroup(RTFProperty *)
 
1796
{
 
1797
}
 
1798
 
 
1799
void RTFImport::skipGroup(RTFProperty *)
 
1800
{
 
1801
    kDebug(30515) << "Skip Group:" << token.type;
1997
1802
    state.ignoreGroup = true;
1998
1803
}
1999
1804
 
2005
1810
    setTableRowDefaults();
2006
1811
}
2007
1812
 
2008
 
void RTFImport::changeDestination( RTFProperty *property )
 
1813
void RTFImport::changeDestination(RTFProperty *property)
2009
1814
{
2010
 
    kDebug(30515) <<"changeDestination:" << property->name;
2011
 
    destinationStack.push( destination );
2012
 
    destination.name     = property->name;
 
1815
    kDebug(30515) << "changeDestination:" << property->name;
 
1816
    destinationStack.push(destination);
 
1817
    destination.name  = property->name;
2013
1818
    destination.destproc = property->cwproc;
2014
 
    if ( property->offset )
2015
 
        destination.target = (RTFTextState*) ( (char *)this + property->offset );
 
1819
    if (property->offset)
 
1820
        destination.target = (RTFTextState*)((char *)this + property->offset);
2016
1821
    else
2017
1822
        destination.target = &m_dummyTextState;
2018
1823
 
2019
1824
    state.brace0 = true;
2020
1825
 
2021
 
    if (property->value)
2022
 
    {
 
1826
    if (property->value) {
2023
1827
        resetState();
2024
1828
        destination.group = 0L;
2025
1829
    }
2029
1833
    (this->*destination.destproc)(0L);
2030
1834
}
2031
1835
 
2032
 
void RTFImport::addAnchor( const char *instance )
 
1836
void RTFImport::addAnchor(const char *instance)
2033
1837
{
2034
1838
    DomNode node;
2035
1839
 
2036
 
    node.clear( 6 );
2037
 
    node.addNode( "ANCHOR" );
2038
 
    node.setAttribute( "type", "frameset" );
2039
 
    node.setAttribute( "instance", instance );
2040
 
    node.closeNode( "ANCHOR" );
 
1840
    node.clear(6);
 
1841
    node.addNode("ANCHOR");
 
1842
    node.setAttribute("type", "frameset");
 
1843
    node.setAttribute("instance", instance);
 
1844
    node.closeNode("ANCHOR");
2041
1845
    kwFormat.xmldata = node.toString();
2042
1846
    kwFormat.id  = 6;
2043
1847
    kwFormat.pos = textState->length++;
2044
1848
    kwFormat.len = 1;
2045
 
    textState->text.append( '#' );
 
1849
    textState->text.append('#');
2046
1850
    textState->formats << kwFormat;
2047
1851
}
2048
1852
 
2049
 
void RTFImport::addFormat( DomNode &node, const KWFormat& format, const RTFFormat* baseFormat )
 
1853
void RTFImport::addFormat(DomNode &node, const KWFormat& format, const RTFFormat* baseFormat)
2050
1854
{
2051
1855
    // Support both (\dn, \up) and (\sub, \super) for super/sub script
2052
1856
    int vertAlign  = format.fmt.vertAlign;
2055
1859
    int fontSize0  = ~fontSize;
2056
1860
 
2057
1861
    // Adjust vertical alignment and font size if (\dn, \up) are used
2058
 
    if (format.fmt.vertAlign == RTFFormat::Normal && format.fmt.baseline)
2059
 
    {
 
1862
    if (format.fmt.vertAlign == RTFFormat::Normal && format.fmt.baseline) {
2060
1863
        if (format.fmt.baseline < 0)
2061
1864
            vertAlign = RTFFormat::SuperScript;
2062
 
        else    // (format.baseline > 0)
 
1865
        else // (format.baseline > 0)
2063
1866
            vertAlign = RTFFormat::SubScript;
2064
1867
 
2065
1868
        fontSize += (fontSize >> 1);
2066
1869
    }
2067
 
    if (baseFormat)
2068
 
    {
 
1870
    if (baseFormat) {
2069
1871
        vertAlign0 = baseFormat->vertAlign;
2070
1872
        fontSize0  = (baseFormat->fontSize >> 1);
2071
1873
 
2072
 
        if (vertAlign0 == RTFFormat::Normal && baseFormat->baseline)
2073
 
        {
 
1874
        if (vertAlign0 == RTFFormat::Normal && baseFormat->baseline) {
2074
1875
            if (baseFormat->baseline < 0)
2075
1876
                vertAlign0 = RTFFormat::SuperScript;
2076
1877
            else    // (baseFormat.baseline > 0)
2079
1880
            fontSize0 += (fontSize0 >> 1);
2080
1881
        }
2081
1882
    }
2082
 
    node.addNode( "FORMAT" );
2083
 
    node.setAttribute( "id", (int)format.id );
 
1883
    node.addNode("FORMAT");
 
1884
    node.setAttribute("id", (int)format.id);
2084
1885
 
2085
 
    if (format.len != 0)
2086
 
    {
 
1886
    if (format.len != 0) {
2087
1887
        // Add pos and len if this is not a style sheet definition
2088
 
        node.setAttribute( "pos", (int)format.pos );
2089
 
        node.setAttribute( "len", (int)format.len );
 
1888
        node.setAttribute("pos", (int)format.pos);
 
1889
        node.setAttribute("len", (int)format.len);
2090
1890
    }
2091
 
    if ((format.id == 1)||(format.id == 4))
2092
 
    {
 
1891
    if ((format.id == 1) || (format.id == 4)) {
2093
1892
        // Normal text, store changes between format and base format
2094
 
        if (!baseFormat || format.fmt.color != baseFormat->color)
2095
 
        {
2096
 
            node.addNode( "COLOR" );
 
1893
        if (!baseFormat || format.fmt.color != baseFormat->color) {
 
1894
            node.addNode("COLOR");
2097
1895
            node.addColor((format.fmt.color < colorTable.count() && format.fmt.color >= 0)
2098
 
                           ? colorTable.value(format.fmt.color) : QColor(Qt::black));
 
1896
                          ? colorTable.value(format.fmt.color) : QColor(Qt::black));
2099
1897
 
2100
 
            node.closeNode( "COLOR" );
 
1898
            node.closeNode("COLOR");
2101
1899
        }
2102
1900
        if (format.fmt.bgcolor < colorTable.count() &&
2103
 
            format.fmt.bgcolor >= 0 &&
2104
 
            (!baseFormat || format.fmt.bgcolor != baseFormat->bgcolor) &&
2105
 
            colorTable[format.fmt.bgcolor].isValid())
2106
 
        {
2107
 
            node.addNode( "TEXTBACKGROUNDCOLOR" );
2108
 
            node.addColor( colorTable[format.fmt.bgcolor] );
2109
 
            node.closeNode( "TEXTBACKGROUNDCOLOR" );
 
1901
                format.fmt.bgcolor >= 0 &&
 
1902
                (!baseFormat || format.fmt.bgcolor != baseFormat->bgcolor) &&
 
1903
                colorTable[format.fmt.bgcolor].isValid()) {
 
1904
            node.addNode("TEXTBACKGROUNDCOLOR");
 
1905
            node.addColor(colorTable[format.fmt.bgcolor]);
 
1906
            node.closeNode("TEXTBACKGROUNDCOLOR");
2110
1907
        }
2111
 
        if (!baseFormat || format.fmt.font != baseFormat->font)
2112
 
        {
2113
 
            node.addNode( "FONT" );
 
1908
        if (!baseFormat || format.fmt.font != baseFormat->font) {
 
1909
            node.addNode("FONT");
2114
1910
 
2115
 
            if (fontTable.contains( format.fmt.font ))
2116
 
            {
2117
 
                node.setAttribute( "name", fontTable[format.fmt.font] );
 
1911
            if (fontTable.contains(format.fmt.font)) {
 
1912
                node.setAttribute("name", fontTable[format.fmt.font]);
2118
1913
            }
2119
 
            node.closeNode( "FONT" );
2120
 
        }
2121
 
        if (!baseFormat || format.fmt.bold != baseFormat->bold)
2122
 
        {
2123
 
            node.addNode( "WEIGHT" );
2124
 
            node.setAttribute( "value", (format.fmt.bold ? 75 : 50) );
2125
 
            node.closeNode( "WEIGHT" );
2126
 
        }
2127
 
        if (fontSize != fontSize0)
2128
 
        {
2129
 
            node.addNode( "SIZE" );
2130
 
            node.setAttribute( "value", fontSize );
2131
 
            node.closeNode( "SIZE" );
2132
 
        }
2133
 
        if (!baseFormat || format.fmt.italic != baseFormat->italic)
2134
 
        {
2135
 
            node.addNode( "ITALIC" );
2136
 
            node.setAttribute( "value", format.fmt.italic );
2137
 
            node.closeNode( "ITALIC" );
2138
 
        }
2139
 
        if (!baseFormat || format.fmt.underline != baseFormat->underline )
2140
 
        {
2141
 
            node.addNode( "UNDERLINE" );
2142
 
            QByteArray st,styleline,wordbyword("0");
 
1914
            node.closeNode("FONT");
 
1915
        }
 
1916
        if (!baseFormat || format.fmt.bold != baseFormat->bold) {
 
1917
            node.addNode("WEIGHT");
 
1918
            node.setAttribute("value", (format.fmt.bold ? 75 : 50));
 
1919
            node.closeNode("WEIGHT");
 
1920
        }
 
1921
        if (fontSize != fontSize0) {
 
1922
            node.addNode("SIZE");
 
1923
            node.setAttribute("value", fontSize);
 
1924
            node.closeNode("SIZE");
 
1925
        }
 
1926
        if (!baseFormat || format.fmt.italic != baseFormat->italic) {
 
1927
            node.addNode("ITALIC");
 
1928
            node.setAttribute("value", format.fmt.italic);
 
1929
            node.closeNode("ITALIC");
 
1930
        }
 
1931
        if (!baseFormat || format.fmt.underline != baseFormat->underline) {
 
1932
            node.addNode("UNDERLINE");
 
1933
            QByteArray st, styleline, wordbyword("0");
2143
1934
            st.setNum(format.fmt.underline);
2144
1935
            int underlinecolor = format.fmt.underlinecolor;
2145
1936
 
2146
 
            switch (format.fmt.underline)
2147
 
            {
 
1937
            switch (format.fmt.underline) {
2148
1938
            case RTFFormat::UnderlineNone:
2149
 
            default:
2150
 
                {
2151
 
                    st="0";
2152
 
                    underlinecolor=-1; // Reset underline color
2153
 
                    break;
2154
 
                }
2155
 
            case RTFFormat::UnderlineSimple:
2156
 
                {
2157
 
                    st="single";
2158
 
                    break;
2159
 
                }
2160
 
            case RTFFormat::UnderlineDouble:
2161
 
                {
2162
 
                    st="double";
2163
 
                    break;
2164
 
                }
2165
 
            case RTFFormat::UnderlineThick:
2166
 
                {
2167
 
                    st="single-bold";
2168
 
                    styleline="solid";
2169
 
                    break;
2170
 
                }
 
1939
            default: {
 
1940
                st = "0";
 
1941
                underlinecolor = -1; // Reset underline color
 
1942
                break;
 
1943
            }
 
1944
            case RTFFormat::UnderlineSimple: {
 
1945
                st = "single";
 
1946
                break;
 
1947
            }
 
1948
            case RTFFormat::UnderlineDouble: {
 
1949
                st = "double";
 
1950
                break;
 
1951
            }
 
1952
            case RTFFormat::UnderlineThick: {
 
1953
                st = "single-bold";
 
1954
                styleline = "solid";
 
1955
                break;
 
1956
            }
2171
1957
 
2172
 
            case RTFFormat::UnderlineWordByWord:
2173
 
                {
2174
 
                    st="single";
2175
 
                    styleline="solid";
2176
 
                    wordbyword="1";
2177
 
                    break;
2178
 
                }
2179
 
            case RTFFormat::UnderlineDash:
2180
 
                {
2181
 
                    st="single";
2182
 
                    styleline="dash";
2183
 
                    break;
2184
 
                }
2185
 
            case RTFFormat::UnderlineDot:
2186
 
                {
2187
 
                    st="single";
2188
 
                    styleline="dot";
2189
 
                    break;
2190
 
                }
2191
 
            case RTFFormat::UnderlineDashDot:
2192
 
                {
2193
 
                    st="single";
2194
 
                    styleline="dashdot";
2195
 
                    break;
2196
 
                }
2197
 
            case RTFFormat::UnderlineDashDotDot:
2198
 
                {
2199
 
                    st="single";
2200
 
                    styleline="dashdotdot";
2201
 
                    break;
2202
 
                }
2203
 
            case RTFFormat::UnderlineWave:
2204
 
                {
2205
 
                    st="single";
2206
 
                    styleline="wave";
2207
 
                    break;
2208
 
                }
 
1958
            case RTFFormat::UnderlineWordByWord: {
 
1959
                st = "single";
 
1960
                styleline = "solid";
 
1961
                wordbyword = "1";
 
1962
                break;
 
1963
            }
 
1964
            case RTFFormat::UnderlineDash: {
 
1965
                st = "single";
 
1966
                styleline = "dash";
 
1967
                break;
 
1968
            }
 
1969
            case RTFFormat::UnderlineDot: {
 
1970
                st = "single";
 
1971
                styleline = "dot";
 
1972
                break;
 
1973
            }
 
1974
            case RTFFormat::UnderlineDashDot: {
 
1975
                st = "single";
 
1976
                styleline = "dashdot";
 
1977
                break;
 
1978
            }
 
1979
            case RTFFormat::UnderlineDashDotDot: {
 
1980
                st = "single";
 
1981
                styleline = "dashdotdot";
 
1982
                break;
 
1983
            }
 
1984
            case RTFFormat::UnderlineWave: {
 
1985
                st = "single";
 
1986
                styleline = "wave";
 
1987
                break;
 
1988
            }
2209
1989
            } // end of switch
2210
 
            node.setAttribute( "value", QString::fromLatin1(st) );
2211
 
            node.setAttribute( "wordbyword", QString::fromLatin1(wordbyword) );
2212
 
            if ( !styleline.isEmpty() )
2213
 
                node.setAttribute( "styleline", QString::fromLatin1(styleline) );
2214
 
            if ( underlinecolor >= 0 && underlinecolor < colorTable.count() )
2215
 
            {
2216
 
                node.setAttribute( "underlinecolor", colorTable[underlinecolor].name() );
 
1990
            node.setAttribute("value", QString::fromLatin1(st));
 
1991
            node.setAttribute("wordbyword", QString::fromLatin1(wordbyword));
 
1992
            if (!styleline.isEmpty())
 
1993
                node.setAttribute("styleline", QString::fromLatin1(styleline));
 
1994
            if (underlinecolor >= 0 && underlinecolor < colorTable.count()) {
 
1995
                node.setAttribute("underlinecolor", colorTable[underlinecolor].name());
2217
1996
            }
2218
1997
 
2219
 
            node.closeNode( "UNDERLINE" );
 
1998
            node.closeNode("UNDERLINE");
2220
1999
        }
2221
 
        if (!baseFormat || format.fmt.strike != baseFormat->strike || format.fmt.striked != baseFormat->striked)
2222
 
        {
2223
 
            node.addNode( "STRIKEOUT" );
 
2000
        if (!baseFormat || format.fmt.strike != baseFormat->strike || format.fmt.striked != baseFormat->striked) {
 
2001
            node.addNode("STRIKEOUT");
2224
2002
            QByteArray st;
2225
2003
            st.setNum(format.fmt.strike);
2226
 
            if(format.fmt.striked)
2227
 
                st="double";
2228
 
            node.setAttribute( "value", QString::fromLatin1(st) );
2229
 
            node.closeNode( "STRIKEOUT" );
2230
 
        }
2231
 
        if (vertAlign != vertAlign0)
2232
 
        {
2233
 
            node.addNode( "VERTALIGN" );
2234
 
            node.setAttribute( "value", vertAlign );
2235
 
            node.closeNode( "VERTALIGN" );
2236
 
        }
2237
 
        if (!baseFormat || format.fmt.caps != baseFormat->caps || format.fmt.smallCaps != baseFormat->smallCaps)
2238
 
        {
2239
 
            node.addNode( "FONTATTRIBUTE" );
 
2004
            if (format.fmt.striked)
 
2005
                st = "double";
 
2006
            node.setAttribute("value", QString::fromLatin1(st));
 
2007
            node.closeNode("STRIKEOUT");
 
2008
        }
 
2009
        if (vertAlign != vertAlign0) {
 
2010
            node.addNode("VERTALIGN");
 
2011
            node.setAttribute("value", vertAlign);
 
2012
            node.closeNode("VERTALIGN");
 
2013
        }
 
2014
        if (!baseFormat || format.fmt.caps != baseFormat->caps || format.fmt.smallCaps != baseFormat->smallCaps) {
 
2015
            node.addNode("FONTATTRIBUTE");
2240
2016
            QString fontattr;
2241
 
            if ( format.fmt.caps )
2242
 
                fontattr="uppercase";
2243
 
            else if ( format.fmt.smallCaps )
2244
 
                fontattr="smallcaps";
 
2017
            if (format.fmt.caps)
 
2018
                fontattr = "uppercase";
 
2019
            else if (format.fmt.smallCaps)
 
2020
                fontattr = "smallcaps";
2245
2021
            else
2246
 
                fontattr="none";
2247
 
            node.setAttribute( "value", fontattr );
2248
 
            node.closeNode( "FONTATTRIBUTE" );
 
2022
                fontattr = "none";
 
2023
            node.setAttribute("value", fontattr);
 
2024
            node.closeNode("FONTATTRIBUTE");
2249
2025
        }
2250
2026
        //if (!baseFormat)
2251
2027
        //{
2254
2030
        //    node.closeNode( "CHARSET" );
2255
2031
        //}
2256
2032
    }
2257
 
    if (format.id == 4 || format.id == 6)
2258
 
    {
 
2033
    if (format.id == 4 || format.id == 6) {
2259
2034
        // Variable or anchor
2260
 
        node.closeTag( true );
2261
 
        node.append( format.xmldata );
 
2035
        node.closeTag(true);
 
2036
        node.append(format.xmldata);
2262
2037
    }
2263
 
    node.closeNode( "FORMAT" );
 
2038
    node.closeNode("FORMAT");
2264
2039
}
2265
2040
 
2266
 
void RTFImport::addLayout( DomNode &node, const QString &name, const RTFLayout &layout, bool frameBreak )
 
2041
void RTFImport::addLayout(DomNode &node, const QString &name, const RTFLayout &layout, bool frameBreak)
2267
2042
{
2268
2043
    // Style name and alignment
2269
 
    node.addNode( "NAME" );
2270
 
      node.setAttribute( "value", CheckAndEscapeXmlText(name) );
2271
 
    node.closeNode( "NAME" );
2272
 
    node.addNode( "FLOW" );
2273
 
      node.setAttribute( "align", alignN[layout.alignment] );
2274
 
    node.closeNode( "FLOW" );
 
2044
    node.addNode("NAME");
 
2045
    node.setAttribute("value", CheckAndEscapeXmlText(name));
 
2046
    node.closeNode("NAME");
 
2047
    node.addNode("FLOW");
 
2048
    node.setAttribute("align", alignN[layout.alignment]);
 
2049
    node.closeNode("FLOW");
2275
2050
 
2276
2051
    // Indents
2277
 
    if (layout.firstIndent || layout.leftIndent || layout.rightIndent)
2278
 
    {
2279
 
        node.addNode( "INDENTS" );
 
2052
    if (layout.firstIndent || layout.leftIndent || layout.rightIndent) {
 
2053
        node.addNode("INDENTS");
2280
2054
 
2281
2055
        if (layout.firstIndent)
2282
 
            node.setAttribute( "first", .05*layout.firstIndent );
 
2056
            node.setAttribute("first", .05*layout.firstIndent);
2283
2057
        if (layout.leftIndent)
2284
 
            node.setAttribute( "left", .05*layout.leftIndent );
 
2058
            node.setAttribute("left", .05*layout.leftIndent);
2285
2059
        if (layout.rightIndent)
2286
 
            node.setAttribute( "right", .05*layout.rightIndent );
 
2060
            node.setAttribute("right", .05*layout.rightIndent);
2287
2061
 
2288
 
        node.closeNode( "INDENTS" );
 
2062
        node.closeNode("INDENTS");
2289
2063
    }
2290
2064
 
2291
2065
    // Offets
2292
 
    if (layout.spaceBefore || layout.spaceAfter)
2293
 
    {
2294
 
        node.addNode( "OFFSETS" );
 
2066
    if (layout.spaceBefore || layout.spaceAfter) {
 
2067
        node.addNode("OFFSETS");
2295
2068
 
2296
2069
        if (layout.spaceBefore)
2297
 
            node.setAttribute( "before", .05*layout.spaceBefore );
 
2070
            node.setAttribute("before", .05*layout.spaceBefore);
2298
2071
        if (layout.spaceAfter)
2299
 
            node.setAttribute( "after", .05*layout.spaceAfter );
 
2072
            node.setAttribute("after", .05*layout.spaceAfter);
2300
2073
 
2301
 
        node.closeNode( "OFFSETS" );
 
2074
        node.closeNode("OFFSETS");
2302
2075
    }
2303
2076
 
2304
2077
 
2306
2079
 
2307
2080
    QString lineSpacingType;
2308
2081
    QString lineSpacingValue;
2309
 
    if ( layout.spaceBetweenMultiple )
2310
 
    {
 
2082
    if (layout.spaceBetweenMultiple) {
2311
2083
        // Note: 240 is a sort of magic value for one line (Once upon a time, it meant 12pt for a single line)
2312
 
        switch (layout.spaceBetween )
2313
 
        {
2314
 
        case 240:
2315
 
            {
2316
 
                lineSpacingType = "single"; // ### TODO: does KWord really supports this?
2317
 
                break;
2318
 
            }
2319
 
        case 360:
2320
 
            {
2321
 
                lineSpacingType = "oneandhalf";
2322
 
                break;
2323
 
            }
2324
 
        case 480 :
2325
 
            {
2326
 
                lineSpacingType = "double";
2327
 
                break;
2328
 
            }
2329
 
        default:
2330
 
            {
2331
 
                if ( layout.spaceBetween > 0 )
2332
 
                {
2333
 
                    lineSpacingType = "multiple";
2334
 
                    lineSpacingValue.setNum( layout.spaceBetween / 240.0 );
2335
 
                }
2336
 
                break;
2337
 
            }
2338
 
        }
2339
 
    }
2340
 
    else
2341
 
    {
2342
 
        if (layout.spaceBetween > 0)
2343
 
        {
 
2084
        switch (layout.spaceBetween) {
 
2085
        case 240: {
 
2086
            lineSpacingType = "single"; // ### TODO: does KWord really supports this?
 
2087
            break;
 
2088
        }
 
2089
        case 360: {
 
2090
            lineSpacingType = "oneandhalf";
 
2091
            break;
 
2092
        }
 
2093
        case 480 : {
 
2094
            lineSpacingType = "double";
 
2095
            break;
 
2096
        }
 
2097
        default: {
 
2098
            if (layout.spaceBetween > 0) {
 
2099
                lineSpacingType = "multiple";
 
2100
                lineSpacingValue.setNum(layout.spaceBetween / 240.0);
 
2101
            }
 
2102
            break;
 
2103
        }
 
2104
        }
 
2105
    } else {
 
2106
        if (layout.spaceBetween > 0) {
2344
2107
            lineSpacingType = "atleast";
2345
 
            lineSpacingValue.setNum( 0.05*layout.spaceBetween );
 
2108
            lineSpacingValue.setNum(0.05*layout.spaceBetween);
2346
2109
        }
2347
 
        if (layout.spaceBetween < 0)
2348
 
        {
 
2110
        if (layout.spaceBetween < 0) {
2349
2111
            // negative linespace means "exact"
2350
2112
            lineSpacingType = "fixed" ;
2351
 
            lineSpacingValue.setNum( -0.05*layout.spaceBetween );
 
2113
            lineSpacingValue.setNum(-0.05*layout.spaceBetween);
2352
2114
        }
2353
2115
    }
2354
2116
 
2355
 
    if ( ! lineSpacingType.isEmpty() )
2356
 
    {
2357
 
        node.addNode( "LINESPACING" );
2358
 
        node.setAttribute( "type", lineSpacingType );
2359
 
        if ( ! lineSpacingValue.isEmpty() )
2360
 
            node.setAttribute( "spacingvalue", lineSpacingValue );
2361
 
        node.closeNode( "LINESPACING" );
 
2117
    if (! lineSpacingType.isEmpty()) {
 
2118
        node.addNode("LINESPACING");
 
2119
        node.setAttribute("type", lineSpacingType);
 
2120
        if (! lineSpacingValue.isEmpty())
 
2121
            node.setAttribute("spacingvalue", lineSpacingValue);
 
2122
        node.closeNode("LINESPACING");
2362
2123
    }
2363
2124
 
2364
 
    if (layout.keep || layout.pageBB || layout.pageBA || frameBreak || layout.keepNext)
2365
 
    {
2366
 
        node.addNode( "PAGEBREAKING" );
2367
 
          node.setAttribute( "linesTogether", boolN[layout.keep] );
2368
 
          node.setAttribute( "hardFrameBreak", boolN[layout.pageBB] );
2369
 
          node.setAttribute( "hardFrameBreakAfter", boolN[layout.pageBA || frameBreak] );
2370
 
          node.setAttribute( "keepWithNext", boolN[layout.keepNext] );
2371
 
        node.closeNode( "PAGEBREAKING" );
 
2125
    if (layout.keep || layout.pageBB || layout.pageBA || frameBreak || layout.keepNext) {
 
2126
        node.addNode("PAGEBREAKING");
 
2127
        node.setAttribute("linesTogether", boolN[layout.keep]);
 
2128
        node.setAttribute("hardFrameBreak", boolN[layout.pageBB]);
 
2129
        node.setAttribute("hardFrameBreakAfter", boolN[layout.pageBA || frameBreak]);
 
2130
        node.setAttribute("keepWithNext", boolN[layout.keepNext]);
 
2131
        node.closeNode("PAGEBREAKING");
2372
2132
    }
2373
2133
 
2374
2134
    // Paragraph borders
2375
 
    for (uint i=0; i < 4; i++)
2376
 
    {
 
2135
    for (uint i = 0; i < 4; i++) {
2377
2136
        const RTFBorder &border = layout.borders[i];
2378
2137
 
2379
 
        if (border.style != RTFBorder::None || border.width > 0)
2380
 
        {
2381
 
            node.addNode( borderN[i] );
2382
 
              node.addColor( (border.color < colorTable.count() && border.color >= 0)
2383
 
                             ? colorTable[border.color] : QColor(Qt::black) );
2384
 
              node.setAttribute( "style", (int)border.style & 0xf );
2385
 
              node.setAttribute( "width", (border.width < 20) ? 1 : border.width /20 );
2386
 
            node.closeNode( borderN[i] );
 
2138
        if (border.style != RTFBorder::None || border.width > 0) {
 
2139
            node.addNode(borderN[i]);
 
2140
            node.addColor((border.color < colorTable.count() && border.color >= 0)
 
2141
                          ? colorTable[border.color] : QColor(Qt::black));
 
2142
            node.setAttribute("style", (int)border.style & 0xf);
 
2143
            node.setAttribute("width", (border.width < 20) ? 1 : border.width / 20);
 
2144
            node.closeNode(borderN[i]);
2387
2145
        }
2388
2146
    }
2389
2147
 
2390
2148
    // Add automatic tab stop for hanging indent
2391
 
    if (layout.firstIndent < 0 && layout.leftIndent > 0)
2392
 
    {
2393
 
        node.addNode( "TABULATOR" );
2394
 
          node.setAttribute( "type", 0 );
2395
 
          node.setAttribute( "ptpos", .05*layout.leftIndent );
2396
 
        node.closeNode( "TABULATOR" );
 
2149
    if (layout.firstIndent < 0 && layout.leftIndent > 0) {
 
2150
        node.addNode("TABULATOR");
 
2151
        node.setAttribute("type", 0);
 
2152
        node.setAttribute("ptpos", .05*layout.leftIndent);
 
2153
        node.closeNode("TABULATOR");
2397
2154
    }
2398
2155
 
2399
2156
    // Tabulators
2400
 
    if (!layout.tablist.isEmpty())
2401
 
    {
2402
 
        for (int i=0; i < layout.tablist.count(); i++)
2403
 
        {
 
2157
    if (!layout.tablist.isEmpty()) {
 
2158
        for (int i = 0; i < layout.tablist.count(); i++) {
2404
2159
            const RTFTab &tab = layout.tablist[i];
2405
2160
            int l = (int)tab.leader;
2406
 
            node.addNode( "TABULATOR" );
2407
 
            node.setAttribute( "type", tab.type );
2408
 
            node.setAttribute( "ptpos", .05*tab.position );
2409
 
            node.setAttribute( "filling", (l < 2) ? l : ((l == 2) ? 1 : 2) );
2410
 
            node.setAttribute( "width", (l == 4) ? 1. : 0.5 );
2411
 
            node.closeNode( "TABULATOR" );
 
2161
            node.addNode("TABULATOR");
 
2162
            node.setAttribute("type", tab.type);
 
2163
            node.setAttribute("ptpos", .05*tab.position);
 
2164
            node.setAttribute("filling", (l < 2) ? l : ((l == 2) ? 1 : 2));
 
2165
            node.setAttribute("width", (l == 4) ? 1. : 0.5);
 
2166
            node.closeNode("TABULATOR");
2412
2167
        }
2413
2168
    }
2414
2169
}
2415
2170
 
2416
 
void RTFImport::addParagraph( DomNode &node, bool frameBreak )
 
2171
void RTFImport::addParagraph(DomNode &node, bool frameBreak)
2417
2172
{
2418
 
    node.addNode( "PARAGRAPH" );
2419
 
      node.addNode( "TEXT" );
2420
 
        node.appendNode( textState->text );
2421
 
      node.closeNode( "TEXT" );
 
2173
    node.addNode("PARAGRAPH");
 
2174
    node.addNode("TEXT");
 
2175
    node.appendNode(textState->text);
 
2176
    node.closeNode("TEXT");
2422
2177
 
2423
2178
    // Search for style in style sheet
2424
2179
    QString name;
2426
2181
    const int styleNum = state.layout.style;
2427
2182
 
2428
2183
    const QVector<RTFStyle>::ConstIterator endStyleSheet = styleSheet.constEnd();
2429
 
    for ( QVector<RTFStyle>::ConstIterator it=styleSheet.constBegin(); it!=endStyleSheet; ++it )
2430
 
    {
2431
 
        if ( (*it).layout.style == styleNum )
2432
 
        {
2433
 
            if ( textState->length > 0 )
2434
 
            {
 
2184
    for (QVector<RTFStyle>::ConstIterator it = styleSheet.constBegin(); it != endStyleSheet; ++it) {
 
2185
        if ((*it).layout.style == styleNum) {
 
2186
            if (textState->length > 0) {
2435
2187
                format = &(*it).format;
2436
2188
            }
2437
2189
            name = (*it).name;
2443
2195
    kwFormat.pos = 0;
2444
2196
    kwFormat.len = textState->length;
2445
2197
 
2446
 
    if ( name.isEmpty() )
2447
 
    {
 
2198
    if (name.isEmpty()) {
2448
2199
        kWarning(30515) << "Style name empty! Assuming Standard!";
2449
2200
        name = "Standard";
2450
2201
    }
2452
2203
    // Insert character formatting
2453
2204
    bool hasFormats = false;
2454
2205
 
2455
 
    for ( QVector<KWFormat>::ConstIterator it = textState->formats.constBegin(); it != textState->formats.constEnd(); ++it )
2456
 
    {
2457
 
        if ( (*it).id != 1 || (*it).fmt != *format )
2458
 
        {
2459
 
            if (!hasFormats)
2460
 
            {
2461
 
                node.addNode( "FORMATS" );
 
2206
    for (QVector<KWFormat>::ConstIterator it = textState->formats.constBegin(); it != textState->formats.constEnd(); ++it) {
 
2207
        if ((*it).id != 1 || (*it).fmt != *format) {
 
2208
            if (!hasFormats) {
 
2209
                node.addNode("FORMATS");
2462
2210
                hasFormats = true;
2463
2211
            }
2464
 
            addFormat( node, (*it), format );
 
2212
            addFormat(node, (*it), format);
2465
2213
        }
2466
2214
    }
2467
 
    if (hasFormats)
2468
 
    {
2469
 
        node.closeNode( "FORMATS" );
 
2215
    if (hasFormats) {
 
2216
        node.closeNode("FORMATS");
2470
2217
    }
2471
2218
 
2472
2219
    // Write out layout and format
2473
 
      node.addNode( "LAYOUT" );
2474
 
        addLayout( node, name, state.layout, frameBreak );
2475
 
        addFormat( node, kwFormat, 0L );
2476
 
      node.closeNode( "LAYOUT" );
2477
 
    node.closeNode( "PARAGRAPH" );
 
2220
    node.addNode("LAYOUT");
 
2221
    addLayout(node, name, state.layout, frameBreak);
 
2222
    addFormat(node, kwFormat, 0L);
 
2223
    node.closeNode("LAYOUT");
 
2224
    node.closeNode("PARAGRAPH");
2478
2225
 
2479
2226
    // Clear plain text and formats for next paragraph
2480
2227
    textState->text.clear();
2484
2231
 
2485
2232
void RTFImport::finishTable()
2486
2233
{
2487
 
    kDebug(30515) <<"Starting TFImport::finishTable...";
 
2234
    kDebug(30515) << "Starting TFImport::finishTable...";
2488
2235
    QByteArray emptyArray;
2489
2236
    QVector<int> cellx;
2490
2237
    int left = 0, right = 0;
2492
2239
    insertTableRow();
2493
2240
 
2494
2241
    // Calculate maximum horizontal extents
2495
 
    for (int i=0; i < textState->rows.count(); i++)
2496
 
    {
 
2242
    for (int i = 0; i < textState->rows.count(); i++) {
2497
2243
        RTFTableRow &row = textState->rows[i];
2498
2244
 
2499
2245
        if (row.left < left || i == 0)
2503
2249
    }
2504
2250
 
2505
2251
    // Force rectangular table (fill gaps with empty cells)
2506
 
    for (int i=0; i < textState->rows.count(); i++)
2507
 
    {
 
2252
    for (int i = 0; i < textState->rows.count(); i++) {
2508
2253
        RTFTableRow &row = textState->rows[i];
2509
2254
 
2510
 
        if (row.left > left)
2511
 
        {
2512
 
            row.frameSets.prepend( emptyArray );
 
2255
        if (row.left > left) {
 
2256
            row.frameSets.prepend(emptyArray);
2513
2257
            emptyCell.x = row.left;
2514
 
            row.cells.prepend( emptyCell );
 
2258
            row.cells.prepend(emptyCell);
2515
2259
            row.left = left;
2516
2260
        }
2517
 
        if (row.cells.last().x < right)
2518
 
        {
 
2261
        if (row.cells.last().x < right) {
2519
2262
            row.frameSets << emptyArray;
2520
2263
            emptyCell.x = right;
2521
2264
            row.cells << emptyCell;
2522
2265
        }
2523
 
        for (int k=0; k < row.cells.count(); k++)
2524
 
        {
2525
 
            if (!cellx.contains( row.cells[k].x ))
 
2266
        for (int k = 0; k < row.cells.count(); k++) {
 
2267
            if (!cellx.contains(row.cells[k].x))
2526
2268
                cellx << row.cells[k].x;
2527
2269
        }
2528
 
        if (!cellx.contains( row.left ))
2529
 
        {
 
2270
        if (!cellx.contains(row.left)) {
2530
2271
            cellx << row.left;
2531
2272
        }
2532
2273
    }
2533
2274
 
2534
2275
    // Sort vertical cell boundaries
2535
 
    for (int k=0; k < cellx.count(); k++)
2536
 
    {
2537
 
        for (int l=k+1; l < cellx.count(); l++)
2538
 
        {
2539
 
            if (cellx[l] < cellx[k])
2540
 
            {
 
2276
    for (int k = 0; k < cellx.count(); k++) {
 
2277
        for (int l = k + 1; l < cellx.count(); l++) {
 
2278
            if (cellx[l] < cellx[k]) {
2541
2279
                int tmp = cellx[l];
2542
2280
                cellx[l] = cellx[k];
2543
2281
                cellx[k] = tmp;
2547
2285
    int y1 = 0;
2548
2286
 
2549
2287
    // Store cell frame and table information
2550
 
    for (int i=0; i < textState->rows.count(); i++)
2551
 
    {
 
2288
    for (int i = 0; i < textState->rows.count(); i++) {
2552
2289
        RTFTableRow &row = textState->rows[i];
2553
 
        int h  = abs( row.height );
2554
 
        int y2 = y1 + ((h < 400) ? 400 : h);    // KWord work-around
 
2290
        int h  = abs(row.height);
 
2291
        int y2 = y1 + ((h < 400) ? 400 : h); // KWord work-around
2555
2292
        int x1 = row.left;
2556
2293
 
2557
 
        for (int k=0; k < row.cells.count(); k++)
2558
 
        {
 
2294
        for (int k = 0; k < row.cells.count(); k++) {
2559
2295
            char buf[64];
2560
2296
            int x2 = row.cells[k].x;
2561
 
            int col = cellx.indexOf( x1 );
2562
 
 
2563
 
            sprintf( buf, "Table %d Cell %d,%d", textState->table, i, col );
2564
 
            frameSets.addFrameSet( buf, 1, 0 );
2565
 
            sprintf( buf, "Table %d", textState->table );
2566
 
            frameSets.setAttribute( "grpMgr", buf );
2567
 
            frameSets.setAttribute( "row", (int)i );
2568
 
            frameSets.setAttribute( "col", col );
2569
 
            frameSets.setAttribute( "rows", 1 );
2570
 
            frameSets.setAttribute( "cols", cellx.indexOf( x2 ) - col );
2571
 
 
2572
 
            frameSets.addFrame( x1, y1, x2, y2, (row.height < 0) ? 2 : 0, 1, 0 );
 
2297
            int col = cellx.indexOf(x1);
 
2298
 
 
2299
            sprintf(buf, "Table %d Cell %d,%d", textState->table, i, col);
 
2300
            frameSets.addFrameSet(buf, 1, 0);
 
2301
            sprintf(buf, "Table %d", textState->table);
 
2302
            frameSets.setAttribute("grpMgr", buf);
 
2303
            frameSets.setAttribute("row", (int)i);
 
2304
            frameSets.setAttribute("col", col);
 
2305
            frameSets.setAttribute("rows", 1);
 
2306
            frameSets.setAttribute("cols", cellx.indexOf(x2) - col);
 
2307
 
 
2308
            frameSets.addFrame(x1, y1, x2, y2, (row.height < 0) ? 2 : 0, 1, 0);
2573
2309
 
2574
2310
            // Frame borders
2575
 
            for (uint i=0; i < 4; i++)
2576
 
            {
 
2311
            for (uint i = 0; i < 4; i++) {
2577
2312
                RTFBorder &border = row.cells[k].borders[i];
2578
2313
 
2579
 
                if (border.style != RTFBorder::None || border.width > 0)
2580
 
                {
 
2314
                if (border.style != RTFBorder::None || border.width > 0) {
2581
2315
                    const char *id = "lrtb";
2582
2316
                    QColor c = (border.color < colorTable.count() && border.color >= 0)
2583
 
                                ? QColor(colorTable[border.color]) : QColor(Qt::black);
2584
 
                    frameSets.addBorder( (int)id[i], c, (int)border.style & 0x0f,
2585
 
                                         .05*(!border.width ? 10 : border.width) );
 
2317
                               ? QColor(colorTable[border.color]) : QColor(Qt::black);
 
2318
                    frameSets.addBorder((int)id[i], c, (int)border.style & 0x0f,
 
2319
                                        .05*(!border.width ? 10 : border.width));
2586
2320
                }
2587
2321
            }
2588
2322
 
2589
2323
            // Frame background color
2590
2324
            if (row.cells[k].bgcolor < colorTable.count() && row.cells[k].bgcolor >= 0) {
2591
2325
                QColor &color = colorTable[row.cells[k].bgcolor];
2592
 
                frameSets.setAttribute( "bkRed", color.red() );
2593
 
                frameSets.setAttribute( "bkGreen", color.green() );
2594
 
                frameSets.setAttribute( "bkBlue", color.blue() );
 
2326
                frameSets.setAttribute("bkRed", color.red());
 
2327
                frameSets.setAttribute("bkGreen", color.green());
 
2328
                frameSets.setAttribute("bkBlue", color.blue());
2595
2329
            }
2596
 
            frameSets.closeNode( "FRAME" );
2597
 
            frameSets.append( row.frameSets[k] );
2598
 
            frameSets.closeNode( "FRAMESET" );
 
2330
            frameSets.closeNode("FRAME");
 
2331
            frameSets.append(row.frameSets[k]);
 
2332
            frameSets.closeNode("FRAMESET");
2599
2333
            x1 = x2;
2600
2334
        }
2601
2335
        y1 = y2;
2602
2336
    }
2603
2337
    textState->table = 0;
2604
2338
    textState->rows.clear();
2605
 
    kDebug(30515) <<"Quitting TFImport::finishTable...";
 
2339
    kDebug(30515) << "Quitting TFImport::finishTable...";
2606
2340
}
2607
2341
 
2608
 
void RTFImport::writeOutPart( const char *name, const DomNode& node )
 
2342
void RTFImport::writeOutPart(const char *name, const DomNode& node)
2609
2343
{
2610
 
    KoStoreDevice* dev = m_chain->storageFile( name, KoStore::Write );
2611
 
    if ( dev )
2612
 
    {
2613
 
        QTextStream stream( dev );
2614
 
        stream.setCodec( "UTF-8" );
 
2344
    KoStoreDevice* dev = m_chain->storageFile(name, KoStore::Write);
 
2345
    if (dev) {
 
2346
        QTextStream stream(dev);
 
2347
        stream.setCodec("UTF-8");
2615
2348
        stream << node.toString();
2616
 
    }
2617
 
    else
 
2349
    } else
2618
2350
        kError(30515) << "Could not write part " << name;
2619
2351
}
2620
2352