merge the formfield patch from ooo-build
[ooovba.git] / lotuswordpro / source / filter / lwptools.cxx
blob0bedffd41c69286c93b2904e684c9e856188a330
1 /*************************************************************************
3 * The Contents of this file are made available subject to the terms of
4 * either of the following licenses
6 * - GNU Lesser General Public License Version 2.1
7 * - Sun Industry Standards Source License Version 1.1
9 * Sun Microsystems Inc., October, 2000
11 * GNU Lesser General Public License Version 2.1
12 * =============================================
13 * Copyright 2000 by Sun Microsystems, Inc.
14 * 901 San Antonio Road, Palo Alto, CA 94303, USA
16 * This library is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU Lesser General Public
18 * License version 2.1, as published by the Free Software Foundation.
20 * This library is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 * Lesser General Public License for more details.
25 * You should have received a copy of the GNU Lesser General Public
26 * License along with this library; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
28 * MA 02111-1307 USA
31 * Sun Industry Standards Source License Version 1.1
32 * =================================================
33 * The contents of this file are subject to the Sun Industry Standards
34 * Source License Version 1.1 (the "License"); You may not use this file
35 * except in compliance with the License. You may obtain a copy of the
36 * License at http://www.openoffice.org/license.html.
38 * Software provided under this License is provided on an "AS IS" basis,
39 * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
40 * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
41 * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
42 * See the License for the specific provisions governing your rights and
43 * obligations concerning the Software.
45 * The Initial Developer of the Original Code is: IBM Corporation
47 * Copyright: 2008 by IBM Corporation
49 * All Rights Reserved.
51 * Contributor(s): _______________________________________
54 ************************************************************************/
55 /*************************************************************************
56 * @file
57 * For LWP filter architecture prototype
58 ************************************************************************/
59 /*************************************************************************
60 * Change History
61 Jan 2005 Created
62 ************************************************************************/
64 #include "lwptools.hxx"
65 #include <rtl/ustrbuf.hxx>
66 #include <osl/process.h>
67 #include <osl/thread.h>
68 #include <osl/file.hxx>
69 #include <vcl/svapp.hxx>
70 #include <vcl/settings.hxx>
71 #include <unicode/datefmt.h>
72 #include <unicode/udat.h>
74 #ifdef SAL_UNX
75 #define SEPARATOR '/'
76 #else
77 #define SEPARATOR '\\'
78 #endif
80 using namespace icu;
81 using namespace ::rtl;
82 using namespace ::osl;
84 /**
85 * @descr read lwp unicode string from stream to OUString per aEncoding
87 sal_uInt16 LwpTools::QuickReadUnicode(LwpObjectStream* pObjStrm,
88 OUString& str, sal_uInt16 strlen, rtl_TextEncoding aEncoding)
89 //strlen: length of bytes
92 sal_uInt16 readLen = 0;
93 OUStringBuffer strBuf(128);
94 sal_uInt16 len = 0;
96 if( !IsUnicodePacked(pObjStrm, strlen) )
98 sal_Char buf[1024];
100 while(strlen)
102 strlen>1023?len=1023 :len=strlen;
103 len = pObjStrm->QuickRead(buf, len);
104 buf[len] = '\0';
105 strBuf.append( OUString(buf, len, aEncoding) );
106 strlen -= len;
107 readLen += len;
108 if(!len) break;
110 str = strBuf.makeStringAndClear();
111 return readLen;
113 else
115 sal_Char buf[1024];
116 sal_Unicode unibuf[1024];
117 sal_uInt8 readbyte;
118 sal_uInt16 readword;
120 BOOL flag = sal_False; //switch if unicode part reached
121 sal_uInt16 sublen = 0;
123 while(readLen<strlen)
125 if(!flag) //Not unicode string
127 len = pObjStrm->QuickRead(&readbyte, sizeof(readbyte));
128 if(!len) break;
129 readLen+=len;
131 if(readbyte == 0x00)
133 flag = sal_True;
134 if(sublen>0) //add it to the strBuf
136 strBuf.append( OUString(buf, sublen, aEncoding) ); //try the aEncoding
137 sublen = 0;
140 else
142 buf[sublen++] = readbyte;
144 if(sublen>=1023 || readLen==strlen) //add it to the strBuf
146 strBuf.append( OUString(buf, sublen, aEncoding) ); //try the aEncoding
147 sublen = 0;
150 else //unicode string
152 len = pObjStrm->QuickRead(&readword, sizeof(readword));
153 if(!len) break;
154 readLen+=len;
156 if(readword == 0x0000)
158 flag = sal_False;
159 if(sublen)
161 unibuf[sublen] = sal_Unicode('\0');
162 strBuf.append( OUString(unibuf) );
163 sublen = 0;
166 else
168 unibuf[sublen++] = readword;
170 if(sublen>=1023 || readLen==strlen)
172 unibuf[sublen] = sal_Unicode('\0');
173 strBuf.append( OUString(unibuf) );
174 sublen = 0;
178 // if(sublen)
179 // {
180 // unibuf[sublen] = sal_Unicode('\0');
181 // strBuf.append( OUString(unibuf) );
182 // sublen = 0;
183 // }
184 str = strBuf.makeStringAndClear();
185 return readLen;
190 * @descr Judge if the data (len) in object stream is lwp unicode packed
192 BOOL LwpTools::IsUnicodePacked(LwpObjectStream* pObjStrm, sal_uInt16 len)
194 sal_uInt8 byte;
195 sal_uInt16 oldpos = pObjStrm->GetPos();
197 for (sal_uInt16 i = 0; i < len; i++)
199 pObjStrm->QuickRead(&byte, sizeof(byte));
200 if (byte == 0x00)
202 pObjStrm->Seek(oldpos);
203 return sal_True;
206 pObjStrm->Seek(oldpos);
207 return sal_False;
210 sal_Bool LwpTools::isFileUrl(const OString &fileName)
212 if (fileName.indexOf("file://") == 0 )
213 return sal_True;
214 return sal_False;
217 OUString LwpTools::convertToFileUrl(const OString &fileName)
219 if ( isFileUrl(fileName) )
221 return OStringToOUString(fileName, osl_getThreadTextEncoding());
224 OUString uUrlFileName;
225 OUString uFileName(fileName.getStr(), fileName.getLength(), osl_getThreadTextEncoding());
226 if ( fileName.indexOf('.') == 0 || fileName.indexOf(SEPARATOR) < 0 )
228 OUString uWorkingDir;
229 OSL_VERIFY( osl_getProcessWorkingDir(&uWorkingDir.pData) == osl_Process_E_None );
230 OSL_VERIFY( FileBase::getAbsoluteFileURL(uWorkingDir, uFileName, uUrlFileName) == FileBase::E_None );
231 } else
233 OSL_VERIFY( FileBase::getFileURLFromSystemPath(uFileName, uUrlFileName) == FileBase::E_None );
236 return uUrlFileName;
239 OUString LwpTools::DateTimeToOUString(LtTm & dt)
241 rtl::OUStringBuffer buf;
242 buf.append(dt.tm_year);
243 buf.append( A2OUSTR("-") );
244 buf.append(dt.tm_mon);
245 buf.append( A2OUSTR("-") );
246 buf.append(dt.tm_mday);
247 buf.append( A2OUSTR("T") );
248 buf.append(dt.tm_hour);
249 buf.append( A2OUSTR(":") );
250 buf.append(dt.tm_min);
251 buf.append( A2OUSTR(":") );
252 buf.append(dt.tm_sec);
254 return buf.makeStringAndClear();
258 * @descr get the system date format
260 XFDateStyle* LwpTools::GetSystemDateStyle(sal_Bool bLongFormat)
262 icu::DateFormat::EStyle style;
263 if (bLongFormat)
264 style = icu::DateFormat::FULL;//system full date format
265 else
266 style = icu::DateFormat::SHORT;//system short date format
267 /* ::com::sun::star::lang::Locale aLocale=Application::GetSettings().GetLocale();
268 rtl::OUString strLang = aLocale.Language;
269 rtl::OUString strCountry = aLocale.Country;
270 strLang = strLang + A2OUSTR("_");
271 rtl::OUString strLocale = strLang + strCountry;
273 int32_t nLength = 0;
274 int32_t nLengthNeed;
275 UErrorCode status = U_ZERO_ERROR;
276 UChar* pattern = NULL;
278 UDateFormat* fmt= udat_open(UDAT_FULL, UDAT_FULL,
279 (char*)(OUStringToOString(strLocale,RTL_TEXTENCODING_MS_1252).getStr()), NULL, 0, NULL, 0, &status);
281 nLengthNeed = udat_toPattern(fmt,true,NULL,nLength,&status);
282 if (status == U_BUFFER_OVERFLOW_ERROR)
284 status = U_ZERO_ERROR;
285 nLength = nLengthNeed +1;
286 pattern = (UChar*)malloc(sizeof(UChar)*nLength);
287 udat_toPattern(fmt,true,pattern,nLength,&status);
290 //1 get locale for system
291 ::com::sun::star::lang::Locale aLocale=Application::GetSettings().GetLocale();
292 rtl::OUString strLang = aLocale.Language;
293 rtl::OUString strCountry = aLocale.Country;
294 icu::Locale bLocale((char*)(OUStringToOString(strLang,RTL_TEXTENCODING_MS_1252).getStr()),
295 (char*)(OUStringToOString(strCountry,RTL_TEXTENCODING_MS_1252).getStr()));
296 //2 get icu format pattern by locale
297 icu::DateFormat* fmt = icu::DateFormat::createDateInstance(style,bLocale);
299 int32_t nLength = 0;
300 int32_t nLengthNeed;
301 UErrorCode status = U_ZERO_ERROR;
302 UChar* pattern = NULL;
304 nLengthNeed = udat_toPattern((void *const *)fmt,sal_False,NULL,nLength,&status);
305 if (status == U_BUFFER_OVERFLOW_ERROR)
307 status = U_ZERO_ERROR;
308 nLength = nLengthNeed +1;
309 pattern = (UChar*)malloc(sizeof(UChar)*nLength);
310 udat_toPattern((void *const *)fmt,sal_False,pattern,nLength,&status);
312 if (pattern == NULL)
313 return NULL;
314 // 3 parse pattern string,per icu date/time format syntax, there are 20 letters reserved
315 // as patter letter,each represent a element in date/time and its repeat numbers represent
316 // different format: for exampel: M produces '1',MM produces '01', MMM produces 'Jan', MMMM produces 'Januaray'
317 // letter other than these letters is regard as text in the format, for example ','in 'Jan,2005'
318 // we parse pattern string letter by letter and get the time format.
319 UChar cSymbol;
320 UChar cTmp;
321 XFDateStyle* pDateStyle = new XFDateStyle;
323 for (int32_t i=0;i<nLengthNeed;)
325 cSymbol = pattern[i];
326 int32_t j;
327 switch(cSymbol)
329 case 'G':
331 for (j=1;;j++)
333 cTmp = pattern[i+j];
334 if (cTmp != cSymbol)
336 i=i+j;
337 break;
340 pDateStyle->AddEra();
341 break;
343 case 'y':
345 for (j=1;;j++)
347 cTmp = pattern[i+j];
348 if (cTmp != cSymbol)
350 i=i+j;
351 break;
354 if (j <= 2)
355 pDateStyle->AddYear(sal_False);
356 else
357 pDateStyle->AddYear();
358 break;
360 case 'M':
362 for (j=1;;j++)
364 cTmp = pattern[i+j];
365 if (cTmp != cSymbol)
367 i=i+j;
368 break;
371 if (j==1)
372 pDateStyle->AddMonth(sal_False,sal_False);
373 else if (j==2)
374 pDateStyle->AddMonth(sal_True,sal_False);
375 else if (j==3)
376 pDateStyle->AddMonth(sal_False,sal_True);
377 else
378 pDateStyle->AddMonth(sal_True,sal_True);
379 break;
381 case 'd':
383 for (j=1;;j++)
385 cTmp = pattern[i+j];
386 if (cTmp != cSymbol)
388 i=i+j;
389 break;
392 if (j==1)
393 pDateStyle->AddMonthDay(sal_False);
394 else
395 pDateStyle->AddMonthDay();
396 break;
398 case 'h':
400 for (j=1;;j++)
402 cTmp = pattern[i+j];
403 if (cTmp != cSymbol)
405 i=i+j;
406 break;
409 if (j==1)
410 pDateStyle->AddHour(sal_False);
411 else
412 pDateStyle->AddHour();
413 break;
415 case 'H':
417 for (j=1;;j++)
419 cTmp = pattern[i+j];
420 if (cTmp != cSymbol)
422 i=i+j;
423 break;
426 if (j==1)
427 pDateStyle->AddHour(sal_False);
428 else
429 pDateStyle->AddHour();
430 break;
432 case 'm':
434 for (j=1;;j++)
436 cTmp = pattern[i+j];
437 if (cTmp != cSymbol)
439 i=i+j;
440 break;
443 if (j==1)
444 pDateStyle->AddMinute(sal_False);
445 else
446 pDateStyle->AddMinute();
447 break;
449 case 's':
451 for (j=1;;j++)
453 cTmp = pattern[i+j];
454 if (cTmp != cSymbol)
456 i=i+j;
457 break;
460 if (j==1)
461 pDateStyle->AddSecond(sal_False,0);
462 else
463 pDateStyle->AddSecond(sal_True,0);
464 break;
466 case 'S':
468 for (j=1;;j++)
470 cTmp = pattern[i+j];
471 if (cTmp != cSymbol)
473 i=i+j;
474 break;
477 /*if (j==1)
478 pDateStyle->AddSecond(sal_False);
479 else
480 pDateStyle->AddSecond();*/
481 break;
483 case 'E':
485 for (j=1;;j++)
487 cTmp = pattern[i+j];
488 if (cTmp != cSymbol)
490 i=i+j;
491 break;
494 if (j<=2)
495 pDateStyle->AddWeekDay(sal_False);
496 else
497 pDateStyle->AddWeekDay();
498 break;
500 case 'D':
502 for (j=1;;j++)
504 cTmp = pattern[i+j];
505 if (cTmp != cSymbol)
507 i=i+j;
508 break;
511 /*if (j==1)
512 pDateStyle->AddWeekDay(sal_False);
513 else
514 pDateStyle->AddWeekDay();*/
515 break;
517 case 'F':
519 for (j=1;;j++)
521 cTmp = pattern[i+j];
522 if (cTmp != cSymbol)
524 i=i+j;
525 break;
528 /*if (j==1)
529 pDateStyle->AddWeekDay(sal_False);
530 else
531 pDateStyle->AddWeekDay();*/
532 break;
534 case 'w':
536 for (j=1;;j++)
538 cTmp = pattern[i+j];
539 if (cTmp != cSymbol)
541 i=i+j;
542 break;
545 /*if (j==1)
546 pDateStyle->AddWeekDay(sal_False);
547 else
548 pDateStyle->AddWeekDay();*/
549 break;
551 case 'W':
553 for (j=1;;j++)
555 cTmp = pattern[i+j];
556 if (cTmp != cSymbol)
558 i=i+j;
559 break;
562 /*if (j==1)
563 pDateStyle->AddWeekDay(sal_False);
564 else
565 pDateStyle->AddWeekDay();*/
566 break;
568 case 'a':
570 for (j=1;;j++)
572 cTmp = pattern[i+j];
573 if (cTmp != cSymbol)
575 i=i+j;
576 break;
579 pDateStyle->AddAmPm(sal_True);
580 break;
582 case 'k':
584 for (j=1;;j++)
586 cTmp = pattern[i+j];
587 if (cTmp != cSymbol)
589 i=i+j;
590 break;
593 break;
595 case 'K':
597 for (j=1;;j++)
599 cTmp = pattern[i+j];
600 if (cTmp != cSymbol)
602 i=i+j;
603 break;
606 if (j==1)
607 pDateStyle->AddHour(sal_False);
608 else
609 pDateStyle->AddHour();
610 break;
612 case 'Z':
614 for (j=1;;j++)
616 cTmp = pattern[i+j];
617 if (cTmp != cSymbol)
619 i=i+j;
620 break;
623 break;
625 case '\''://'
627 for (j=1;;j++)
629 cTmp = pattern[i+j];
630 if (cTmp != cSymbol)
632 i=i+j;
633 break;
636 break;
638 case '"':
640 pDateStyle->AddText(OUString(A2OUSTR("'")));
641 break;
643 default:
645 if ((cSymbol>='A' && cSymbol<='Z') || (cSymbol>='a' && cSymbol<='z') )
646 return NULL;
647 else//TEXT
649 //UChar buffer[1024];
650 sal_Unicode buffer[1024];
651 buffer[0] = cSymbol;
652 for (j=1;;j++)
654 cTmp = pattern[i+j];
655 if ((cTmp>='A' && cTmp<='Z') || (cTmp>='a' && cTmp<='z') ||
656 cTmp=='\'' || cTmp=='"' )
658 i=i+j;
659 buffer[j]= '\0';
660 break;
662 else
663 buffer[j] = cTmp;
666 pDateStyle->AddText(OUString(buffer));//keep for all parsed
668 break;
672 // udat_close(fmt);
673 return pDateStyle;
676 * @descr get the system time format
678 XFTimeStyle* LwpTools::GetSystemTimeStyle()
680 /* ::com::sun::star::lang::Locale aLocale=Application::GetSettings().GetLocale();
681 rtl::OUString strLang = aLocale.Language;
682 rtl::OUString strCountry = aLocale.Country;
683 strLang = strLang + A2OUSTR("_");
684 rtl::OUString strLocale = strLang + strCountry;
686 int32_t nLength = 0;
687 int32_t nLengthNeed;
688 UErrorCode status = U_ZERO_ERROR;
689 UChar* pattern = NULL;
691 UDateFormat* fmt= udat_open(UDAT_FULL, UDAT_FULL,
692 (char*)(OUStringToOString(strLocale,RTL_TEXTENCODING_MS_1252).getStr()), NULL, 0, NULL, 0, &status);
694 nLengthNeed = udat_toPattern(fmt,true,NULL,nLength,&status);
695 if (status == U_BUFFER_OVERFLOW_ERROR)
697 status = U_ZERO_ERROR;
698 nLength = nLengthNeed +1;
699 pattern = (UChar*)malloc(sizeof(UChar)*nLength);
700 udat_toPattern(fmt,true,pattern,nLength,&status);
703 //1 get locale for system
704 ::com::sun::star::lang::Locale aLocale=Application::GetSettings().GetLocale();
705 rtl::OUString strLang = aLocale.Language;
706 rtl::OUString strCountry = aLocale.Country;
707 icu::Locale bLocale((char*)(OUStringToOString(strLang,RTL_TEXTENCODING_MS_1252).getStr()),
708 (char*)(OUStringToOString(strCountry,RTL_TEXTENCODING_MS_1252).getStr()));
710 icu::DateFormat* fmt = icu::DateFormat::createTimeInstance(icu::DateFormat::DEFAULT,bLocale);
711 //2 get icu format pattern by locale
712 int32_t nLength = 0;
713 int32_t nLengthNeed;
714 UErrorCode status = U_ZERO_ERROR;
715 UChar* pattern = NULL;
716 nLengthNeed = udat_toPattern((void *const *)fmt,false,NULL,nLength,&status);
717 if (status == U_BUFFER_OVERFLOW_ERROR)
719 status = U_ZERO_ERROR;
720 nLength = nLengthNeed +1;
721 pattern = (UChar*)malloc(sizeof(UChar)*nLength);
722 udat_toPattern((void *const *)fmt,false,pattern,nLength,&status);
725 if (pattern == NULL)
726 return NULL;
727 // 3 parse pattern string,per icu date/time format syntax, there are 20 letters reserved
728 // as patter letter,each represent a element in date/time and its repeat numbers represent
729 // different format: for exampel: M produces '1',MM produces '01', MMM produces 'Jan', MMMM produces 'Januaray'
730 // letter other than these letters is regard as text in the format, for example ','in 'Jan,2005'
731 // we parse pattern string letter by letter and get the time format.
732 // for time format ,for there is not date info,we can only parse the letter representing time.
733 UChar cSymbol;
734 UChar cTmp;
735 XFTimeStyle* pTimeStyle = new XFTimeStyle;
737 for (int32_t i=0;i<nLengthNeed;)
739 cSymbol = pattern[i];
740 int32_t j;
741 switch(cSymbol)
743 case 'h':
745 for (j=1;;j++)
747 cTmp = pattern[i+j];
748 if (cTmp != cSymbol)
750 i=i+j;
751 break;
754 if (j==1)
755 pTimeStyle->AddHour(sal_False);
756 else
757 pTimeStyle->AddHour();
758 break;
760 case 'H':
762 for (j=1;;j++)
764 cTmp = pattern[i+j];
765 if (cTmp != cSymbol)
767 i=i+j;
768 break;
771 if (j==1)
772 pTimeStyle->AddHour(sal_False);
773 else
774 pTimeStyle->AddHour();
775 break;
777 case 'm':
779 for (j=1;;j++)
781 cTmp = pattern[i+j];
782 if (cTmp != cSymbol)
784 i=i+j;
785 break;
788 if (j==1)
789 pTimeStyle->AddMinute(sal_False);
790 else
791 pTimeStyle->AddMinute();
792 break;
794 case 's':
796 for (j=1;;j++)
798 cTmp = pattern[i+j];
799 if (cTmp != cSymbol)
801 i=i+j;
802 break;
805 if (j==1)
806 pTimeStyle->AddSecond(sal_False,0);
807 else
808 pTimeStyle->AddSecond(sal_True,0);
809 break;
811 case 'S':
813 for (j=1;;j++)
815 cTmp = pattern[i+j];
816 if (cTmp != cSymbol)
818 i=i+j;
819 break;
822 /*if (j==1)
823 pDateStyle->AddSecond(sal_False);
824 else
825 pDateStyle->AddSecond();*/
826 break;
828 case 'a':
830 for (j=1;;j++)
832 cTmp = pattern[i+j];
833 if (cTmp != cSymbol)
835 i=i+j;
836 break;
839 pTimeStyle->SetAmPm(sal_True);
840 break;
842 case 'k':
844 for (j=1;;j++)
846 cTmp = pattern[i+j];
847 if (cTmp != cSymbol)
849 i=i+j;
850 break;
853 break;
855 case 'K':
857 for (j=1;;j++)
859 cTmp = pattern[i+j];
860 if (cTmp != cSymbol)
862 i=i+j;
863 break;
866 if (j==1)
867 pTimeStyle->AddHour(sal_False);
868 else
869 pTimeStyle->AddHour();
870 break;
872 case '\''://'
874 for (j=1;;j++)
876 cTmp = pattern[i+j];
877 if (cTmp != cSymbol)
879 i=i+j;
880 break;
883 break;
885 case '"':
887 pTimeStyle->AddText(OUString(A2OUSTR("'")));
888 break;
890 default:
892 if ((cSymbol>='A' && cSymbol<='Z') || (cSymbol>='a' && cSymbol<='z') )
893 return NULL;
894 else//TEXT
896 sal_Unicode buffer[1024];
897 buffer[0] = cSymbol;
898 //strBuffer.append(cSymbol);
899 for (j=1;;j++)
901 cTmp = pattern[i+j];
902 if ((cTmp>='A' && cTmp<='Z') || (cTmp>='a' && cTmp<='z') ||
903 cTmp=='\'' || cTmp=='"' )
905 i=i+j;
906 buffer[j]= '\0';
907 break;
909 else
910 buffer[j] = cTmp;
912 pTimeStyle->AddText(OUString(buffer));//keep for all parsed
914 break;
918 // udat_close(fmt);
919 return pTimeStyle;