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 #   include	<stdlib.h>
12 
13 #   include	<appDebugon.h>
14 
15 #   include	<appUnit.h>
16 #   include	<textOfficeCharset.h>
17 #   include	<textConverter.h>
18 #   include	"docRtfReaderImpl.h"
19 #   include	"docRtfTagEnum.h"
20 
21 /************************************************************************/
22 /*									*/
23 /*  Remember Document Properties.					*/
24 /*									*/
25 /************************************************************************/
26 
27 /************************************************************************/
28 /*									*/
29 /*  Remember the code page for the document.				*/
30 /*  = All values from the Word 2003 spec explicitly included.		*/
31 /*  = String values checked against GNU iconv 'iconv (GNU libc) 2.3.6'	*/
32 /*  = Check strings against iconv -l					*/
33 /*									*/
34 /************************************************************************/
35 
docRtfSetAnsicpg(struct TextConverter * tc,int ansicpg)36 static int docRtfSetAnsicpg(	struct TextConverter *	tc,
37 				int			ansicpg )
38     {
39     char			scratch[20];
40 
41     switch( ansicpg )
42 	{
43 	case 437: case 819: case 850: case 852:
44 	case 460: case 862: case 863: case 864:
45 	case 465: case 866: case 874: case 932:
46 	case 936: case 949: case 950:
47 	case 1361:
48 	    sprintf( scratch, "CP%d", ansicpg );
49 	    textConverterSetNativeEncodingName( tc, scratch );
50 	    return 0;
51 
52 	case 708:
53 	    textConverterSetNativeEncodingName( tc, "ASMO-708" );
54 	    return 0;
55 	case 709:
56 	    textConverterSetNativeEncodingName( tc, "ASMO_449" );
57 	    return 0;
58 
59 	case 1250: case 1251: case 1252: case 1253:
60 	case 1254: case 1255: case 1256: case 1257:
61 	case 1258:
62 	    /* sprintf( scratch, "WINDOWS-%d", ansicpg ); */ /* GNU? */
63 	    sprintf( scratch, "CP%d", ansicpg );
64 	    textConverterSetNativeEncodingName( tc, scratch );
65 	    return 0;
66 
67 	case 10000:
68 	    textConverterSetNativeEncodingName( tc, "MACINTOSH" );
69 	    return 0;
70 
71 	case 710:
72 	case 711:
73 	case 720:
74 	default:
75 	    LDEB(ansicpg);
76 	    textConverterSetNativeEncodingName( tc, DOC_RTF_AnsiCharsetName );
77 	    return -1;
78 	}
79     }
80 
81 /************************************************************************/
82 /*									*/
83 /*  Remember the document charset. It is translated to a code page	*/
84 /*  where possible.							*/
85 /*									*/
86 /************************************************************************/
87 
docRtfReadSetDocumentCharset(RtfReader * rrc,int arg)88 static int docRtfReadSetDocumentCharset(
89 				RtfReader *		rrc,
90 				int			arg )
91     {
92     struct TextConverter *	tc= rrc->rrRtfTextConverter;
93 
94     switch( arg )
95 	{
96 	case DOCcharsetANSI:
97 	    if  ( docRtfSetAnsicpg( tc, 1252 ) )
98 		{ LDEB(arg); return -1;	}
99 	    return 0;
100 
101 	case DOCcharsetPC:
102 	    if  ( docRtfSetAnsicpg( tc, 437 ) )
103 		{ LDEB(arg); return -1;	}
104 	    return 0;
105 
106 	case DOCcharsetPCA:
107 	    if  ( docRtfSetAnsicpg( tc, 850 ) )
108 		{ LDEB(arg); return -1;	}
109 	    return 0;
110 
111 	case DOCcharsetMAC:
112 	    if  ( docRtfSetAnsicpg( tc, 10000 ) )
113 		{ LDEB(arg); return -1;	}
114 	    return 0;
115 
116 	default:
117 	    LDEB(arg); return -1;
118 	}
119     }
120 
docRtfRememberDocProperty(const RtfControlWord * rcw,int arg,RtfReader * rrc)121 int docRtfRememberDocProperty(	const RtfControlWord *	rcw,
122 				int			arg,
123 				RtfReader *		rrc )
124     {
125     SectionProperties *		sp= &(rrc->rrcSectionProperties);
126 
127     int				charset= -1;
128 
129     switch( rcw->rcwID )
130 	{
131 	case DGpropLEFT_MARGIN:
132 	    sp->spDocumentGeometry.dgLeftMarginTwips= arg;
133 	    rrc->rrcGotDocGeometry= 1;
134 	    break;
135 	case DGpropTOP_MARGIN:
136 	    sp->spDocumentGeometry.dgTopMarginTwips= arg;
137 	    rrc->rrcGotDocGeometry= 1;
138 	    break;
139 	case DGpropRIGHT_MARGIN:
140 	    sp->spDocumentGeometry.dgRightMarginTwips= arg;
141 	    rrc->rrcGotDocGeometry= 1;
142 	    break;
143 	case DGpropBOTTOM_MARGIN:
144 	    sp->spDocumentGeometry.dgBottomMarginTwips= arg;
145 	    break;
146 	case DGpropPAGE_WIDTH:
147 	    sp->spDocumentGeometry.dgPageWideTwips= arg;
148 	    rrc->rrcGotDocGeometry= 1;
149 	    break;
150 	case DGpropPAGE_HEIGHT:
151 	    sp->spDocumentGeometry.dgPageHighTwips= arg;
152 	    rrc->rrcGotDocGeometry= 1;
153 	    break;
154 	case DGpropGUTTER:
155 	    sp->spDocumentGeometry.dgGutterTwips= arg;
156 	    rrc->rrcGotDocGeometry= 1;
157 	    break;
158 	case DGpropMARGMIR:
159 	    arg= arg != 0;
160 	    sp->spDocumentGeometry.dgMirrorMargins= arg;
161 	    rrc->rrcGotDocGeometry= 1;
162 	    break;
163 
164 	case DPpropFACING_PAGES:
165 	    arg= arg != 0;
166 	    break;
167 	case DPpropGUTTER_HORIZONTAL:
168 	    arg= arg != 0;
169 	    break;
170 	case DPpropWIDOWCTRL:
171 	    arg= arg != 0;
172 	    break;
173 	case DPpropTWO_ON_ONE:
174 	    arg= arg != 0;
175 	    break;
176 	case DPpropDOCTEMP:
177 	    arg= arg != 0;
178 	    break;
179 
180 	case DPpropDEFF:
181 	    rrc->rrcDefaultFont= arg;
182 	    if  ( docRtfReadMapFont( rrc, &arg, &charset,
183 						rrc->rrcDefaultFont ) < 0 )
184 		{ SLDEB(rcw->rcwWord,arg);	}
185 	    break;
186 	case DPpropSTSHFDBCH:
187 	    rrc->rrcDefaultFontDbch= arg;
188 	    if  ( docRtfReadMapFont( rrc, &arg, &charset,
189 						rrc->rrcDefaultFontDbch ) < 0 )
190 		{ SLDEB(rcw->rcwWord,arg);	}
191 	    break;
192 	case DPpropSTSHFLOCH:
193 	    rrc->rrcDefaultFontLoch= arg;
194 	    if  ( docRtfReadMapFont( rrc, &arg, &charset,
195 						rrc->rrcDefaultFontLoch ) < 0 )
196 		{ SLDEB(rcw->rcwWord,arg);	}
197 	    break;
198 	case DPpropSTSHFHICH:
199 	    rrc->rrcDefaultFontHich= arg;
200 	    if  ( docRtfReadMapFont( rrc, &arg, &charset,
201 						rrc->rrcDefaultFontHich ) < 0 )
202 		{ SLDEB(rcw->rcwWord,arg);	}
203 	    break;
204 	case DPpropSTSHFBI:
205 	    rrc->rrcDefaultFontBi= arg;
206 	    if  ( docRtfReadMapFont( rrc, &arg, &charset,
207 						rrc->rrcDefaultFontBi ) < 0 )
208 		{ SLDEB(rcw->rcwWord,arg);	}
209 	    break;
210 
211 	case DPpropDOC_CHARSET:
212 	    if  ( docRtfReadSetDocumentCharset( rrc, arg ) )
213 		{ SLDEB(rcw->rcwWord,arg); return 0;	}
214 	    break;
215 	case DPpropANSICPG:
216 	    if  ( docRtfSetAnsicpg( rrc->rrRtfTextConverter, arg ) )
217 		{ SLDEB(rcw->rcwWord,arg); return 0;	}
218 	    break;
219 
220 	case DPpropTOP_BORDER:
221 	case DPpropBOTTOM_BORDER:
222 	case DPpropLEFT_BORDER:
223 	case DPpropRIGHT_BORDER:
224 	case DPpropHEAD_BORDER:
225 	case DPpropFOOT_BORDER:
226 	    arg= docRtfReadGetBorderNumber( rrc );
227 	    if  ( arg < 0 )
228 		{ SLDEB(rcw->rcwWord,arg); return -1;	}
229 	    break;
230 
231 	case DPpropNOTETYPES:
232 	    docInitFootEndNotesProperties(
233 			    &(rrc->rrDocument->bdProperties.dpNotesProps) );
234 	    break;
235 
236 	case DPprop_IGNORED:
237 	    return 0;
238 
239 	default:
240 	    break;
241 	}
242 
243     if  ( rrc->rrcTraceInProps )
244 	{
245 	/*  Working copy for undo */
246 	if  ( docSetDocumentProperty( &(rrc->rrcDocumentProperties),
247 						    rcw->rcwID, arg ) < 0 )
248 	    { SLDEB(rcw->rcwWord,arg); return 0;	}
249 
250 	PROPmaskADD( &(rrc->rrcDocPropertyMask), rcw->rcwID );
251 	}
252     else{
253 	/*  Document */
254 	if  ( docSetDocumentProperty( &(rrc->rrDocument->bdProperties),
255 						    rcw->rcwID, arg ) < 0 )
256 	    { SLDEB(rcw->rcwWord,arg); return 0;	}
257 	}
258 
259     return 0;
260     }
261 
262 /************************************************************************/
263 /*									*/
264 /*  Remember a document property that has a string value.		*/
265 /*									*/
266 /************************************************************************/
267 
docRtfCommitDocPropText(const RtfControlWord * rcw,RtfReader * rrc)268 int docRtfCommitDocPropText(	const RtfControlWord *	rcw,
269 				RtfReader *		rrc )
270     {
271     int		rval= 0;
272     const int	removeSemicolon= rcw->rcwID == DPpropGENERATOR;
273 
274     char *	text= (char *)0;
275     int		size;
276 
277     if  ( docRtfStoreSavedText( &text, &size, rrc, removeSemicolon ) )
278 	{ SDEB(rcw->rcwWord); rval= -1; goto ready;	}
279 
280     if  ( rrc->rrcTraceInProps )
281 	{
282 	if  ( docSetDocumentPropertyString( &(rrc->rrcDocumentProperties),
283 						    rcw->rcwID, text, size ) )
284 	    { SDEB(rcw->rcwWord); rval= -1; goto ready;	}
285 
286 	PROPmaskADD( &(rrc->rrcDocPropertyMask), rcw->rcwID );
287 	}
288     else{
289 	if  ( docSetDocumentPropertyString( &(rrc->rrDocument->bdProperties),
290 						    rcw->rcwID, text, size ) )
291 	    { SDEB(rcw->rcwWord); rval= -1; goto ready;	}
292 	}
293 
294   ready:
295 
296     if  ( text )
297 	{ free( text );		}
298 
299     return rval;
300     }
301 
302 /************************************************************************/
303 /*									*/
304 /*  A date/time field in the info group.				*/
305 /*									*/
306 /************************************************************************/
307 
docRtfDocTimeGroup(const RtfControlWord * rcw,int arg,RtfReader * rrc)308 int docRtfDocTimeGroup(	const RtfControlWord *	rcw,
309 			int			arg,
310 			RtfReader *		rrc )
311     {
312     utilInvalidateTime( &(rrc->rrcTm) );
313 
314     if  ( docRtfReadGroup( rcw, 0, 0, rrc,
315 		(RtfControlWord *)0, docRtfRefuseText, (RtfCommitGroup)0 ) )
316 	{ SLDEB(rcw->rcwWord,arg); return -1;	}
317 
318     if  ( rrc->rrcTraceInProps )
319 	{
320 	if  ( docSetDocumentPropertyTime( &(rrc->rrcDocumentProperties),
321 						rcw->rcwID, &(rrc->rrcTm) ) )
322 	    { SDEB(rcw->rcwWord); return -1;	}
323 
324 	PROPmaskADD( &(rrc->rrcDocPropertyMask), rcw->rcwID );
325 	}
326     else{
327 	if  ( docSetDocumentPropertyTime( &(rrc->rrDocument->bdProperties),
328 						rcw->rcwID, &(rrc->rrcTm) ) )
329 	    { SDEB(rcw->rcwWord); return -1;	}
330 	}
331 
332     return 0;
333     }
334 
335 /************************************************************************/
336 /*									*/
337 /*  Remember fields from dates and times.				*/
338 /*									*/
339 /************************************************************************/
340 
docRtfReadTimeField(const RtfControlWord * rcw,int arg,RtfReader * rrc)341 int docRtfReadTimeField(	const RtfControlWord *	rcw,
342 				int			arg,
343 				RtfReader *		rrc )
344     {
345     switch( rcw->rcwID )
346 	{
347 	case RTFidHR:
348 	    rrc->rrcTm.tm_hour= arg;
349 	    break;
350 	case RTFidMIN:
351 	    rrc->rrcTm.tm_min= arg;
352 	    break;
353 	case RTFidSEC:
354 	    rrc->rrcTm.tm_sec= arg;
355 	    break;
356 	case RTFidDY:
357 	    rrc->rrcTm.tm_mday= arg;
358 	    break;
359 	case RTFidMO:
360 	    rrc->rrcTm.tm_mon= arg- 1;
361 	    break;
362 	case RTFidYR:
363 	    rrc->rrcTm.tm_year= arg- 1900;
364 	    break;
365 	}
366 
367     return 0;
368     }
369 
370 /************************************************************************/
371 /*									*/
372 /*  Remember fields from dates and times.				*/
373 /*									*/
374 /************************************************************************/
375 
docRtfSelectionOpen(const RtfControlWord * rcw,int arg,RtfReader * rrc)376 int docRtfSelectionOpen(	const RtfControlWord *	rcw,
377 				int			arg,
378 				RtfReader *		rrc )
379     {
380     DocumentProperties *	dp= &(rrc->rrDocument->bdProperties);
381 
382     dp->dpHasOpenEnd= 1;
383 
384     if  ( docRtfReadGroup( rcw, 0, 0, rrc, (RtfControlWord *)0,
385 				(RtfAddTextParticule)0, (RtfCommitGroup)0 ) )
386 	{ SLDEB(rcw->rcwWord,arg); return -1;	}
387 
388     return 0;
389     }
390