1 /************************************************************************/
2 /* */
3 /* Read/Write document properties to/from RTF. */
4 /* */
5 /************************************************************************/
6
7 # include "docRtfConfig.h"
8
9 # include <stdio.h>
10 # include <ctype.h>
11
12 # include <appDebugon.h>
13
14 # include <textOfficeCharset.h>
15 # include "docRtfWriterImpl.h"
16 # include "docRtfTags.h"
17
18 /************************************************************************/
19 /* */
20 /* Save Document Properties to RTF. */
21 /* */
22 /************************************************************************/
23
docRtfSaveInfo(RtfWriter * rw,const char * tag,const MemoryBuffer * info)24 static int docRtfSaveInfo( RtfWriter * rw,
25 const char * tag,
26 const MemoryBuffer * info )
27 {
28 const int addSemicolon= 0;
29
30 docRtfWriteDocEncodedStringDestination( rw, tag,
31 (const char *)info->mbBytes,
32 info->mbSize, addSemicolon );
33
34 docRtfWriteNextLine( rw );
35
36 return 0;
37 }
38
docRtfSaveDate(RtfWriter * rw,const char * tag,const struct tm * tm)39 int docRtfSaveDate( RtfWriter * rw,
40 const char * tag,
41 const struct tm * tm )
42 {
43 docRtfWriteDestinationBegin( rw, tag );
44
45 if ( tm->tm_mday != 0 )
46 {
47 docRtfWriteArgTag( rw, "yr", tm->tm_year+ 1900 );
48 docRtfWriteArgTag( rw, "mo", tm->tm_mon+ 1 );
49 docRtfWriteArgTag( rw, "dy", tm->tm_mday );
50 docRtfWriteArgTag( rw, "hr", tm->tm_hour );
51 docRtfWriteArgTag( rw, "min", tm->tm_min );
52 docRtfWriteArgTag( rw, "sec", tm->tm_sec );
53 }
54
55 docRtfWriteDestinationEnd( rw );
56 docRtfWriteNextLine( rw );
57
58 return 0;
59 }
60
docRtfSaveDocumentProperties(RtfWriter * rw,int fet,const PropertyMask * dpMask,const DocumentProperties * dp)61 int docRtfSaveDocumentProperties( RtfWriter * rw,
62 int fet,
63 const PropertyMask * dpMask,
64 const DocumentProperties * dp )
65 {
66 const int anyway= 1;
67 const DocumentGeometry * dg= &(dp->dpGeometry);
68
69 /* NO! We always write ansi 1252 documents
70 int ansicpg= dp->dpAnsiCodepage;
71
72 if ( ansicpg >= 0 )
73 {
74 if ( docRtfSetAnsicpg( rw->rwRtfTextConverter, ansicpg ) )
75 { LDEB(ansicpg); }
76 }
77 */
78
79 if ( PROPmaskISSET( dpMask, DPpropDEFF ) )
80 {
81 int deff= docRtfWriteGetDefaultFont( rw, dp->dpDefaultFont );
82
83 if ( deff >= 0 )
84 { docRtfWriteArgTag( rw, "deff", deff ); }
85 }
86
87 if ( PROPmaskISSET( dpMask, DPpropDEFLANG ) )
88 { docRtfWriteArgTag( rw, "deflang", dp->dpDefaultLanguage ); }
89
90 if ( PROPmaskISSET( dpMask, DPpropRTOL ) )
91 {
92 docRtfWriteAltTag( rw, "rtldoc", "ltrdoc", dp->dpRToL );
93 }
94
95 /* Strictly spoken, this is not a document property */
96 docRtfWriteArgTag( rw, "uc", 1 );
97
98 if ( PROPmaskISSET( dpMask, DPpropFONTTABLE ) )
99 {
100 docRtfWriteNextLine( rw );
101 docRtfWriteFontTable( rw );
102 }
103
104 if ( PROPmaskISSET( dpMask, DPpropCOLORTABLE ) )
105 {
106 docRtfWriteNextLine( rw );
107 docRtfWriteColorTable( rw, dp );
108 }
109
110 if ( PROPmaskISSET( dpMask, DPpropSTYLESHEET ) )
111 {
112 docRtfWriteNextLine( rw );
113 docRtfWriteStyleSheet( rw, &(rw->rwDocument->bdStyleSheet) );
114 }
115
116 if ( PROPmaskISSET( dpMask, DPpropLISTTABLE ) )
117 {
118 docRtfWriteNextLine( rw );
119 docRtfWriteListTable( rw, &(dp->dpListAdmin->laListTable) );
120 }
121
122 if ( PROPmaskISSET( dpMask, DPpropLISTOVERRIDETABLE ) )
123 {
124 docRtfWriteNextLine( rw );
125 docRtfWriteListOverrideTable( rw,
126 &(dp->dpListAdmin->laListOverrideTable) );
127 }
128
129 if ( PROPmaskISSET( dpMask, DPpropGENERATOR ) )
130 { docRtfSaveInfo( rw, RTFtag__generator, &(dp->dpGeneratorWrite) ); }
131
132 if ( PROPmaskISSET( dpMask, DPpropTITLE ) ||
133 PROPmaskISSET( dpMask, DPpropAUTHOR ) ||
134 PROPmaskISSET( dpMask, DPpropCOMPANY ) ||
135 PROPmaskISSET( dpMask, DPpropSUBJECT ) ||
136 PROPmaskISSET( dpMask, DPpropKEYWORDS ) ||
137 PROPmaskISSET( dpMask, DPpropDOCCOMM ) ||
138 PROPmaskISSET( dpMask, DPpropHLINKBASE ) ||
139 PROPmaskISSET( dpMask, DPpropCREATIM ) ||
140 PROPmaskISSET( dpMask, DPpropREVTIM ) ||
141 PROPmaskISSET( dpMask, DPpropPRINTIM ) )
142 {
143 docRtfWriteNextLine( rw );
144 docRtfWriteDestinationBegin( rw, "info" );
145 docRtfWriteNextLine( rw );
146
147 if ( PROPmaskISSET( dpMask, DPpropTITLE ) )
148 { docRtfSaveInfo( rw, "title", &(dp->dpTitle) ); }
149 if ( PROPmaskISSET( dpMask, DPpropAUTHOR ) )
150 { docRtfSaveInfo( rw, "author", &(dp->dpAuthor) ); }
151 if ( PROPmaskISSET( dpMask, DPpropCOMPANY ) )
152 { docRtfSaveInfo( rw, "company", &(dp->dpCompany) ); }
153 if ( PROPmaskISSET( dpMask, DPpropSUBJECT ) )
154 { docRtfSaveInfo( rw, "subject", &(dp->dpSubject) ); }
155 if ( PROPmaskISSET( dpMask, DPpropKEYWORDS ) )
156 { docRtfSaveInfo( rw, "keywords", &(dp->dpKeywords) ); }
157 if ( PROPmaskISSET( dpMask, DPpropDOCCOMM ) )
158 { docRtfSaveInfo( rw, "doccomm", &(dp->dpDoccomm) ); }
159 if ( PROPmaskISSET( dpMask, DPpropHLINKBASE ) )
160 { docRtfSaveInfo( rw, RTFtag_hlinkbase, &(dp->dpHlinkbase) ); }
161
162 if ( PROPmaskISSET( dpMask, DPpropCREATIM ) )
163 { docRtfSaveDate( rw, "creatim", &(dp->dpCreatim) ); }
164 if ( PROPmaskISSET( dpMask, DPpropREVTIM ) )
165 { docRtfSaveDate( rw, RTFtag_revtim, &(dp->dpRevtim) ); }
166 if ( PROPmaskISSET( dpMask, DPpropPRINTIM ) )
167 { docRtfSaveDate( rw, "printim", &(dp->dpPrintim) ); }
168
169 docRtfWriteDestinationEnd( rw );
170 }
171
172 docRtfWriteNextLine( rw );
173
174 if ( PROPmaskISSET( dpMask, DGpropPAGE_WIDTH ) )
175 { docRtfWriteArgTag( rw, "paperw", dg->dgPageWideTwips ); }
176 if ( PROPmaskISSET( dpMask, DGpropPAGE_HEIGHT ) )
177 { docRtfWriteArgTag( rw, "paperh", dg->dgPageHighTwips ); }
178
179 if ( PROPmaskISSET( dpMask, DGpropLEFT_MARGIN ) )
180 { docRtfWriteArgTag( rw, "margl", dg->dgLeftMarginTwips ); }
181 if ( PROPmaskISSET( dpMask, DGpropRIGHT_MARGIN ) )
182 { docRtfWriteArgTag( rw, "margr", dg->dgRightMarginTwips ); }
183 if ( PROPmaskISSET( dpMask, DGpropTOP_MARGIN ) )
184 { docRtfWriteArgTag( rw, "margt", dg->dgTopMarginTwips ); }
185 if ( PROPmaskISSET( dpMask, DGpropBOTTOM_MARGIN ) )
186 { docRtfWriteArgTag( rw, "margb", dg->dgBottomMarginTwips ); }
187
188 if ( PROPmaskISSET( dpMask, DGpropGUTTER ) )
189 { docRtfWriteArgTag( rw, "gutter", dg->dgGutterTwips ); }
190 if ( PROPmaskISSET( dpMask, DGpropMARGMIR ) )
191 { docRtfWriteTag( rw, "margmirror" ); }
192
193 if ( PROPmaskISSET( dpMask, DPpropFACING_PAGES ) )
194 { docRtfWriteFlagTag( rw, "facingp", dp->dpHasFacingPages ); }
195 if ( PROPmaskISSET( dpMask, DPpropGUTTER_HORIZONTAL ) )
196 { docRtfWriteFlagTag( rw, "gutterprl", dp->dpGutterHorizontal ); }
197
198 if ( PROPmaskISSET( dpMask, DPpropWIDOWCTRL ) )
199 { docRtfWriteFlagTag( rw, "widowctrl", dp->dpWidowControl ); }
200
201 if ( PROPmaskISSET( dpMask, DPpropTWO_ON_ONE ) )
202 { docRtfWriteFlagTag( rw, "twoonone", dp->dpTwoOnOne ); }
203 if ( PROPmaskISSET( dpMask, DPpropDOCTEMP ) )
204 { docRtfWriteFlagTag( rw, "doctemp", dp->dpIsDocumentTemplate ); }
205
206 if ( dp->dpTabIntervalTwips > 0 && dp->dpTabIntervalTwips != 720 )
207 { docRtfWriteArgTag( rw, "deftab", dp->dpTabIntervalTwips ); }
208
209 docRtfWriteNextLine( rw );
210
211 if ( fet >= 0 )
212 { docRtfWriteArgTag( rw, RTFtag_fet, fet ); }
213
214 docRtfSaveNotesProperties( rw, dpMask,
215 &(dp->dpNotesProps.fepFootnotesProps),
216 DOCdocFOOTNOTE_PROP_MAP, "ftnstart",
217 DOCrtf_DocFootNotesJustificationTags,
218 DOCrtf_DocFootNotesJustificationTagCount,
219 DOCrtf_DocFootNotesPlacementTags,
220 DOCrtf_DocFootNotesPlacementTagCount,
221 DOCrtf_DocFootNotesRestartTags,
222 DOCrtf_DocFootNotesRestartTagCount,
223 DOCrtf_DocFootNotesNumberStyleTags,
224 DOCrtf_DocFootNotesNumberStyleTagCount );
225
226 docRtfSaveNotesProperties( rw, dpMask,
227 &(dp->dpNotesProps.fepEndnotesProps),
228 DOCdocENDNOTE_PROP_MAP, "aftnstart",
229 DOCrtf_DocEndNotesJustificationTags,
230 DOCrtf_DocEndNotesJustificationTagCount,
231 DOCrtf_DocEndNotesPlacementTags,
232 DOCrtf_DocEndNotesPlacementTagCount,
233 DOCrtf_DocEndNotesRestartTags,
234 DOCrtf_DocEndNotesRestartTagCount,
235 DOCrtf_DocEndNotesNumberStyleTags,
236 DOCrtf_DocEndNotesNumberStyleTagCount );
237
238 if ( PROPmaskISSET( dpMask, DPpropTOP_BORDER ) )
239 {
240 docRtfSaveBorderByNumber( rw, "pgbrdrt",
241 dp->dpTopBorderNumber, anyway );
242 }
243 if ( PROPmaskISSET( dpMask, DPpropBOTTOM_BORDER ) )
244 {
245 docRtfSaveBorderByNumber( rw, "pgbrdrb",
246 dp->dpBottomBorderNumber, anyway );
247 }
248 if ( PROPmaskISSET( dpMask, DPpropLEFT_BORDER ) )
249 {
250 docRtfSaveBorderByNumber( rw, "pgbrdrl",
251 dp->dpLeftBorderNumber, anyway );
252 }
253 if ( PROPmaskISSET( dpMask, DPpropRIGHT_BORDER ) )
254 {
255 docRtfSaveBorderByNumber( rw, "pgbrdrr",
256 dp->dpRightBorderNumber, anyway );
257 }
258 if ( PROPmaskISSET( dpMask, DPpropHEAD_BORDER ) )
259 {
260 docRtfSaveBorderByNumber( rw, "pgbrdrhead",
261 dp->dpHeadBorderNumber, anyway );
262 }
263 if ( PROPmaskISSET( dpMask, DPpropFOOT_BORDER ) )
264 {
265 docRtfSaveBorderByNumber( rw, "pgbrdrfoot",
266 dp->dpFootBorderNumber, anyway );
267 }
268
269 docRtfWriteNextLine( rw );
270
271 return 0;
272 }
273
274 /************************************************************************/
275 /* */
276 /* Save the various separators relating to notes. */
277 /* */
278 /************************************************************************/
279
docRtfSaveDocNotesSeparators(RtfWriter * rw,const BufferDocument * bd)280 int docRtfSaveDocNotesSeparators( RtfWriter * rw,
281 const BufferDocument * bd )
282 {
283 const int evenIfAbsent= 0;
284 const int forcePar= 0;
285
286 if ( docRtfSaveDocumentTree( rw, "ftnsep", &(bd->bdEiFtnsep),
287 evenIfAbsent, forcePar ) )
288 { LDEB(1); return -1; }
289
290 if ( docRtfSaveDocumentTree( rw, "ftnsepc", &(bd->bdEiFtnsepc),
291 evenIfAbsent, forcePar ) )
292 { LDEB(1); return -1; }
293
294 if ( docRtfSaveDocumentTree( rw, "ftncn", &(bd->bdEiFtncn),
295 evenIfAbsent, forcePar ) )
296 { LDEB(1); return -1; }
297
298 /******/
299
300 if ( docRtfSaveDocumentTree( rw, "aftnsep", &(bd->bdEiAftnsep),
301 evenIfAbsent, forcePar ) )
302 { LDEB(1); return -1; }
303
304 if ( docRtfSaveDocumentTree( rw, "aftnsepc", &(bd->bdEiAftnsepc),
305 evenIfAbsent, forcePar ) )
306 { LDEB(1); return -1; }
307
308 if ( docRtfSaveDocumentTree( rw, "aftncn", &(bd->bdEiAftncn),
309 evenIfAbsent, forcePar ) )
310 { LDEB(1); return -1; }
311
312 return 0;
313 }
314
315 /************************************************************************/
316 /* */
317 /* Determine the mask of scalar properties that differ from the */
318 /* defaults. */
319 /* */
320 /************************************************************************/
321
docRtfDocPropMask(PropertyMask * dpSaveMask,const DocumentProperties * dpDoc)322 int docRtfDocPropMask( PropertyMask * dpSaveMask,
323 const DocumentProperties * dpDoc )
324 {
325 int rval= 0;
326
327 PropertyMask dpSetMask;
328 DocumentProperties dpDef;
329
330 const DocumentAttributeMap * const dam0= (const DocumentAttributeMap *)0;
331
332 docInitDocumentProperties( &dpDef );
333
334 utilPropMaskClear( &dpSetMask );
335 utilPropMaskFill( &dpSetMask, DPprop_COUNT );
336 utilPropMaskClear( dpSaveMask );
337
338 if ( docUpdDocumentProperties( dpSaveMask, &dpDef,
339 &dpSetMask, dpDoc, dam0 ) )
340 { LDEB(1); rval= -1; goto ready; }
341
342 ready:
343
344 docCleanDocumentProperties( &dpDef );
345
346 return rval;
347 }
348