bump product version to 4.1.6.2
[LibreOffice.git] / lotuswordpro / source / filter / lwptools.cxx
blob77eb3dc7bf636a259bc988ada6f4d7ec2a0da538
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * The Contents of this file are made available subject to the terms of
5 * either of the following licenses
7 * - GNU Lesser General Public License Version 2.1
8 * - Sun Industry Standards Source License Version 1.1
10 * Sun Microsystems Inc., October, 2000
12 * GNU Lesser General Public License Version 2.1
13 * =============================================
14 * Copyright 2000 by Sun Microsystems, Inc.
15 * 901 San Antonio Road, Palo Alto, CA 94303, USA
17 * This library is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU Lesser General Public
19 * License version 2.1, as published by the Free Software Foundation.
21 * This library is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 * Lesser General Public License for more details.
26 * You should have received a copy of the GNU Lesser General Public
27 * License along with this library; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
29 * MA 02111-1307 USA
32 * Sun Industry Standards Source License Version 1.1
33 * =================================================
34 * The contents of this file are subject to the Sun Industry Standards
35 * Source License Version 1.1 (the "License"); You may not use this file
36 * except in compliance with the License. You may obtain a copy of the
37 * License at http://www.openoffice.org/license.html.
39 * Software provided under this License is provided on an "AS IS" basis,
40 * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
41 * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
42 * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
43 * See the License for the specific provisions governing your rights and
44 * obligations concerning the Software.
46 * The Initial Developer of the Original Code is: IBM Corporation
48 * Copyright: 2008 by IBM Corporation
50 * All Rights Reserved.
52 * Contributor(s): _______________________________________
55 ************************************************************************/
56 /*************************************************************************
57 * @file
58 * For LWP filter architecture prototype
59 ************************************************************************/
60 /*************************************************************************
61 * Change History
62 Jan 2005 Created
63 ************************************************************************/
65 #include "lwptools.hxx"
66 #include <rtl/ustrbuf.hxx>
67 #include <osl/process.h>
68 #include <osl/thread.h>
69 #include <osl/file.hxx>
70 #include <vcl/svapp.hxx>
71 #include <vcl/settings.hxx>
72 #include <unicode/datefmt.h>
73 #include <unicode/udat.h>
74 #include <i18nlangtag/languagetagicu.hxx>
76 #ifdef SAL_UNX
77 #define SEPARATOR '/'
78 #else
79 #define SEPARATOR '\\'
80 #endif
82 using namespace icu;
83 using namespace ::rtl;
84 using namespace ::osl;
86 /**
87 * @descr read lwp unicode string from stream to OUString per aEncoding
89 sal_uInt16 LwpTools::QuickReadUnicode(LwpObjectStream* pObjStrm,
90 OUString& str, sal_uInt16 strlen, rtl_TextEncoding aEncoding)
91 //strlen: length of bytes
94 sal_uInt16 readLen = 0;
95 OUStringBuffer strBuf(128);
97 if( !IsUnicodePacked(pObjStrm, strlen) )
99 sal_uInt16 len = 0;
100 sal_Char buf[1024];
102 while(strlen)
104 strlen>1023?len=1023 :len=strlen;
105 len = pObjStrm->QuickRead(buf, len);
106 buf[len] = '\0';
107 strBuf.append( OUString(buf, len, aEncoding) );
108 strlen -= len;
109 readLen += len;
110 if(!len) break;
112 str = strBuf.makeStringAndClear();
113 return readLen;
115 else
117 sal_Char buf[1024];
118 sal_Unicode unibuf[1024];
119 sal_uInt8 readbyte;
120 sal_uInt16 readword;
122 sal_Bool flag = sal_False; //switch if unicode part reached
123 sal_uInt16 sublen = 0;
125 while(readLen<strlen)
127 if(!flag) //Not unicode string
129 bool bFailure;
130 readbyte = pObjStrm->QuickReaduInt8(&bFailure);
131 if(bFailure) break;
132 readLen+=sizeof(readbyte);
134 if(readbyte == 0x00)
136 flag = sal_True;
137 if(sublen>0) //add it to the strBuf
139 strBuf.append( OUString(buf, sublen, aEncoding) ); //try the aEncoding
140 sublen = 0;
143 else
145 buf[sublen++] = readbyte;
147 if(sublen>=1023 || readLen==strlen) //add it to the strBuf
149 strBuf.append( OUString(buf, sublen, aEncoding) ); //try the aEncoding
150 sublen = 0;
153 else //unicode string
155 bool bFailure;
156 readword = pObjStrm->QuickReaduInt16(&bFailure);
157 if(bFailure) break;
158 readLen+=sizeof(readword);
160 if(readword == 0x0000)
162 flag = sal_False;
163 if(sublen)
165 unibuf[sublen] = sal_Unicode('\0');
166 strBuf.append( OUString(unibuf) );
167 sublen = 0;
170 else
172 unibuf[sublen++] = readword;
174 if(sublen>=1023 || readLen==strlen)
176 unibuf[sublen] = sal_Unicode('\0');
177 strBuf.append( OUString(unibuf) );
178 sublen = 0;
182 str = strBuf.makeStringAndClear();
183 return readLen;
188 * @descr Judge if the data (len) in object stream is lwp unicode packed
190 sal_Bool LwpTools::IsUnicodePacked(LwpObjectStream* pObjStrm, sal_uInt16 len)
192 sal_uInt8 byte;
193 sal_uInt16 oldpos = pObjStrm->GetPos();
195 for (sal_uInt16 i = 0; i < len; i++)
197 byte = pObjStrm->QuickReaduInt8();
198 if (byte == 0x00)
200 pObjStrm->Seek(oldpos);
201 return sal_True;
204 pObjStrm->Seek(oldpos);
205 return sal_False;
208 sal_Bool LwpTools::isFileUrl(const OString &fileName)
210 if (fileName.indexOf("file://") == 0 )
211 return sal_True;
212 return sal_False;
215 OUString LwpTools::convertToFileUrl(const OString &fileName)
217 if ( isFileUrl(fileName) )
219 return OStringToOUString(fileName, osl_getThreadTextEncoding());
222 OUString uUrlFileName;
223 OUString uFileName(fileName.getStr(), fileName.getLength(), osl_getThreadTextEncoding());
224 if ( fileName.indexOf('.') == 0 || fileName.indexOf(SEPARATOR) < 0 )
226 OUString uWorkingDir;
227 OSL_VERIFY( osl_getProcessWorkingDir(&uWorkingDir.pData) == osl_Process_E_None );
228 OSL_VERIFY( FileBase::getAbsoluteFileURL(uWorkingDir, uFileName, uUrlFileName) == FileBase::E_None );
229 } else
231 OSL_VERIFY( FileBase::getFileURLFromSystemPath(uFileName, uUrlFileName) == FileBase::E_None );
234 return uUrlFileName;
237 OUString LwpTools::DateTimeToOUString(LtTm & dt)
239 OUStringBuffer buf;
240 buf.append(dt.tm_year);
241 buf.append( A2OUSTR("-") );
242 buf.append(dt.tm_mon);
243 buf.append( A2OUSTR("-") );
244 buf.append(dt.tm_mday);
245 buf.append( A2OUSTR("T") );
246 buf.append(dt.tm_hour);
247 buf.append( A2OUSTR(":") );
248 buf.append(dt.tm_min);
249 buf.append( A2OUSTR(":") );
250 buf.append(dt.tm_sec);
252 return buf.makeStringAndClear();
256 * @descr get the system date format
258 XFDateStyle* LwpTools::GetSystemDateStyle(sal_Bool bLongFormat)
260 icu::DateFormat::EStyle style;
261 if (bLongFormat)
262 style = icu::DateFormat::FULL;//system full date format
263 else
264 style = icu::DateFormat::SHORT;//system short date format
266 //1 get locale for system
267 icu::Locale aLocale( LanguageTagIcu::getIcuLocale( Application::GetSettings().GetLanguageTag()));
268 //2 get icu format pattern by locale
269 icu::DateFormat* fmt = icu::DateFormat::createDateInstance(style,aLocale);
271 int32_t nLength = 0;
272 int32_t nLengthNeed;
273 UErrorCode status = U_ZERO_ERROR;
274 UChar* pattern = NULL;
276 nLengthNeed = udat_toPattern((void *const *)fmt,sal_False,NULL,nLength,&status);
277 if (status == U_BUFFER_OVERFLOW_ERROR)
279 status = U_ZERO_ERROR;
280 nLength = nLengthNeed +1;
281 pattern = (UChar*)malloc(sizeof(UChar)*nLength);
282 udat_toPattern((void *const *)fmt,sal_False,pattern,nLength,&status);
284 if (pattern == NULL)
285 return NULL;
286 // 3 parse pattern string,per icu date/time format syntax, there are 20 letters reserved
287 // as patter letter,each represent a element in date/time and its repeat numbers represent
288 // different format: for exampel: M produces '1',MM produces '01', MMM produces 'Jan', MMMM produces 'Januaray'
289 // letter other than these letters is regard as text in the format, for example ','in 'Jan,2005'
290 // we parse pattern string letter by letter and get the time format.
291 UChar cSymbol;
292 UChar cTmp;
293 XFDateStyle* pDateStyle = new XFDateStyle;
295 for (int32_t i=0;i<nLengthNeed;)
297 cSymbol = pattern[i];
298 int32_t j;
299 switch(cSymbol)
301 case 'G':
303 for (j=1;;j++)
305 cTmp = pattern[i+j];
306 if (cTmp != cSymbol)
308 i=i+j;
309 break;
312 pDateStyle->AddEra();
313 break;
315 case 'y':
317 for (j=1;;j++)
319 cTmp = pattern[i+j];
320 if (cTmp != cSymbol)
322 i=i+j;
323 break;
326 if (j <= 2)
327 pDateStyle->AddYear(sal_False);
328 else
329 pDateStyle->AddYear();
330 break;
332 case 'M':
334 for (j=1;;j++)
336 cTmp = pattern[i+j];
337 if (cTmp != cSymbol)
339 i=i+j;
340 break;
343 if (j==1)
344 pDateStyle->AddMonth(sal_False,sal_False);
345 else if (j==2)
346 pDateStyle->AddMonth(sal_True,sal_False);
347 else if (j==3)
348 pDateStyle->AddMonth(sal_False,sal_True);
349 else
350 pDateStyle->AddMonth(sal_True,sal_True);
351 break;
353 case 'd':
355 for (j=1;;j++)
357 cTmp = pattern[i+j];
358 if (cTmp != cSymbol)
360 i=i+j;
361 break;
364 if (j==1)
365 pDateStyle->AddMonthDay(sal_False);
366 else
367 pDateStyle->AddMonthDay();
368 break;
370 case 'h':
372 for (j=1;;j++)
374 cTmp = pattern[i+j];
375 if (cTmp != cSymbol)
377 i=i+j;
378 break;
381 if (j==1)
382 pDateStyle->AddHour(sal_False);
383 else
384 pDateStyle->AddHour();
385 break;
387 case 'H':
389 for (j=1;;j++)
391 cTmp = pattern[i+j];
392 if (cTmp != cSymbol)
394 i=i+j;
395 break;
398 if (j==1)
399 pDateStyle->AddHour(sal_False);
400 else
401 pDateStyle->AddHour();
402 break;
404 case 'm':
406 for (j=1;;j++)
408 cTmp = pattern[i+j];
409 if (cTmp != cSymbol)
411 i=i+j;
412 break;
415 if (j==1)
416 pDateStyle->AddMinute(sal_False);
417 else
418 pDateStyle->AddMinute();
419 break;
421 case 's':
423 for (j=1;;j++)
425 cTmp = pattern[i+j];
426 if (cTmp != cSymbol)
428 i=i+j;
429 break;
432 if (j==1)
433 pDateStyle->AddSecond(sal_False,0);
434 else
435 pDateStyle->AddSecond(sal_True,0);
436 break;
438 case 'S':
440 for (j=1;;j++)
442 cTmp = pattern[i+j];
443 if (cTmp != cSymbol)
445 i=i+j;
446 break;
449 /*if (j==1)
450 pDateStyle->AddSecond(sal_False);
451 else
452 pDateStyle->AddSecond();*/
453 break;
455 case 'E':
457 for (j=1;;j++)
459 cTmp = pattern[i+j];
460 if (cTmp != cSymbol)
462 i=i+j;
463 break;
466 if (j<=2)
467 pDateStyle->AddWeekDay(sal_False);
468 else
469 pDateStyle->AddWeekDay();
470 break;
472 case 'D':
474 for (j=1;;j++)
476 cTmp = pattern[i+j];
477 if (cTmp != cSymbol)
479 i=i+j;
480 break;
483 /*if (j==1)
484 pDateStyle->AddWeekDay(sal_False);
485 else
486 pDateStyle->AddWeekDay();*/
487 break;
489 case 'F':
491 for (j=1;;j++)
493 cTmp = pattern[i+j];
494 if (cTmp != cSymbol)
496 i=i+j;
497 break;
500 /*if (j==1)
501 pDateStyle->AddWeekDay(sal_False);
502 else
503 pDateStyle->AddWeekDay();*/
504 break;
506 case 'w':
508 for (j=1;;j++)
510 cTmp = pattern[i+j];
511 if (cTmp != cSymbol)
513 i=i+j;
514 break;
517 /*if (j==1)
518 pDateStyle->AddWeekDay(sal_False);
519 else
520 pDateStyle->AddWeekDay();*/
521 break;
523 case 'W':
525 for (j=1;;j++)
527 cTmp = pattern[i+j];
528 if (cTmp != cSymbol)
530 i=i+j;
531 break;
534 /*if (j==1)
535 pDateStyle->AddWeekDay(sal_False);
536 else
537 pDateStyle->AddWeekDay();*/
538 break;
540 case 'a':
542 for (j=1;;j++)
544 cTmp = pattern[i+j];
545 if (cTmp != cSymbol)
547 i=i+j;
548 break;
551 pDateStyle->AddAmPm(sal_True);
552 break;
554 case 'k':
556 for (j=1;;j++)
558 cTmp = pattern[i+j];
559 if (cTmp != cSymbol)
561 i=i+j;
562 break;
565 break;
567 case 'K':
569 for (j=1;;j++)
571 cTmp = pattern[i+j];
572 if (cTmp != cSymbol)
574 i=i+j;
575 break;
578 if (j==1)
579 pDateStyle->AddHour(sal_False);
580 else
581 pDateStyle->AddHour();
582 break;
584 case 'Z':
586 for (j=1;;j++)
588 cTmp = pattern[i+j];
589 if (cTmp != cSymbol)
591 i=i+j;
592 break;
595 break;
597 case '\''://'
599 for (j=1;;j++)
601 cTmp = pattern[i+j];
602 if (cTmp != cSymbol)
604 i=i+j;
605 break;
608 break;
610 case '"':
612 pDateStyle->AddText(OUString(A2OUSTR("'")));
613 break;
615 default:
617 if ((cSymbol>='A' && cSymbol<='Z') || (cSymbol>='a' && cSymbol<='z') )
618 return NULL;
619 else//TEXT
621 //UChar buffer[1024];
622 sal_Unicode buffer[1024];
623 buffer[0] = cSymbol;
624 for (j=1;;j++)
626 cTmp = pattern[i+j];
627 if ((cTmp>='A' && cTmp<='Z') || (cTmp>='a' && cTmp<='z') ||
628 cTmp=='\'' || cTmp=='"' )
630 i=i+j;
631 buffer[j]= '\0';
632 break;
634 else
635 buffer[j] = cTmp;
638 pDateStyle->AddText(OUString(buffer));//keep for all parsed
640 break;
644 // udat_close(fmt);
645 return pDateStyle;
648 * @descr get the system time format
650 XFTimeStyle* LwpTools::GetSystemTimeStyle()
652 //1 get locale for system
653 icu::Locale aLocale( LanguageTagIcu::getIcuLocale( Application::GetSettings().GetLanguageTag()));
654 //2 get icu format pattern by locale
655 icu::DateFormat* fmt = icu::DateFormat::createTimeInstance(icu::DateFormat::DEFAULT,aLocale);
657 int32_t nLength = 0;
658 int32_t nLengthNeed;
659 UErrorCode status = U_ZERO_ERROR;
660 UChar* pattern = NULL;
661 nLengthNeed = udat_toPattern((void *const *)fmt,false,NULL,nLength,&status);
662 if (status == U_BUFFER_OVERFLOW_ERROR)
664 status = U_ZERO_ERROR;
665 nLength = nLengthNeed +1;
666 pattern = (UChar*)malloc(sizeof(UChar)*nLength);
667 udat_toPattern((void *const *)fmt,false,pattern,nLength,&status);
670 if (pattern == NULL)
671 return NULL;
672 // 3 parse pattern string,per icu date/time format syntax, there are 20 letters reserved
673 // as patter letter,each represent a element in date/time and its repeat numbers represent
674 // different format: for exampel: M produces '1',MM produces '01', MMM produces 'Jan', MMMM produces 'Januaray'
675 // letter other than these letters is regard as text in the format, for example ','in 'Jan,2005'
676 // we parse pattern string letter by letter and get the time format.
677 // for time format ,for there is not date info,we can only parse the letter representing time.
678 UChar cSymbol;
679 UChar cTmp;
680 XFTimeStyle* pTimeStyle = new XFTimeStyle;
682 for (int32_t i=0;i<nLengthNeed;)
684 cSymbol = pattern[i];
685 int32_t j;
686 switch(cSymbol)
688 case 'h':
690 for (j=1;;j++)
692 cTmp = pattern[i+j];
693 if (cTmp != cSymbol)
695 i=i+j;
696 break;
699 if (j==1)
700 pTimeStyle->AddHour(sal_False);
701 else
702 pTimeStyle->AddHour();
703 break;
705 case 'H':
707 for (j=1;;j++)
709 cTmp = pattern[i+j];
710 if (cTmp != cSymbol)
712 i=i+j;
713 break;
716 if (j==1)
717 pTimeStyle->AddHour(sal_False);
718 else
719 pTimeStyle->AddHour();
720 break;
722 case 'm':
724 for (j=1;;j++)
726 cTmp = pattern[i+j];
727 if (cTmp != cSymbol)
729 i=i+j;
730 break;
733 if (j==1)
734 pTimeStyle->AddMinute(sal_False);
735 else
736 pTimeStyle->AddMinute();
737 break;
739 case 's':
741 for (j=1;;j++)
743 cTmp = pattern[i+j];
744 if (cTmp != cSymbol)
746 i=i+j;
747 break;
750 if (j==1)
751 pTimeStyle->AddSecond(sal_False,0);
752 else
753 pTimeStyle->AddSecond(sal_True,0);
754 break;
756 case 'S':
758 for (j=1;;j++)
760 cTmp = pattern[i+j];
761 if (cTmp != cSymbol)
763 i=i+j;
764 break;
767 /*if (j==1)
768 pDateStyle->AddSecond(sal_False);
769 else
770 pDateStyle->AddSecond();*/
771 break;
773 case 'a':
775 for (j=1;;j++)
777 cTmp = pattern[i+j];
778 if (cTmp != cSymbol)
780 i=i+j;
781 break;
784 pTimeStyle->SetAmPm(sal_True);
785 break;
787 case 'k':
789 for (j=1;;j++)
791 cTmp = pattern[i+j];
792 if (cTmp != cSymbol)
794 i=i+j;
795 break;
798 break;
800 case 'K':
802 for (j=1;;j++)
804 cTmp = pattern[i+j];
805 if (cTmp != cSymbol)
807 i=i+j;
808 break;
811 if (j==1)
812 pTimeStyle->AddHour(sal_False);
813 else
814 pTimeStyle->AddHour();
815 break;
817 case '\''://'
819 for (j=1;;j++)
821 cTmp = pattern[i+j];
822 if (cTmp != cSymbol)
824 i=i+j;
825 break;
828 break;
830 case '"':
832 pTimeStyle->AddText(OUString(A2OUSTR("'")));
833 break;
835 default:
837 if ((cSymbol>='A' && cSymbol<='Z') || (cSymbol>='a' && cSymbol<='z') )
838 return NULL;
839 else//TEXT
841 sal_Unicode buffer[1024];
842 buffer[0] = cSymbol;
843 //strBuffer.append(cSymbol);
844 for (j=1;;j++)
846 cTmp = pattern[i+j];
847 if ((cTmp>='A' && cTmp<='Z') || (cTmp>='a' && cTmp<='z') ||
848 cTmp=='\'' || cTmp=='"' )
850 i=i+j;
851 buffer[j]= '\0';
852 break;
854 else
855 buffer[j] = cTmp;
857 pTimeStyle->AddText(OUString(buffer));//keep for all parsed
859 break;
863 // udat_close(fmt);
864 return pTimeStyle;
867 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */