merge the formfield patch from ooo-build
[ooovba.git] / svtools / source / misc / imap2.cxx
blob09af492a4f7e1eb66b2e7e9cf65c14c908db2fe0
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: imap2.cxx,v $
10 * $Revision: 1.12 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svtools.hxx"
34 #ifdef WIN
35 #include <sysdep.hxx>
36 #endif
37 #include <string.h>
38 // #include <math.h>
39 #include <vcl/svapp.hxx>
40 #include <tools/urlobj.hxx>
41 #ifndef _WRKWIN_HXX //autogen
42 #include <vcl/wrkwin.hxx>
43 #endif
44 #include <sot/formats.hxx>
46 #include "urihelper.hxx"
47 #include <svtools/imap.hxx>
48 #include <svtools/imap.hxx>
49 #include <svtools/imapobj.hxx>
50 #include <svtools/imaprect.hxx>
51 #include <svtools/imapcirc.hxx>
52 #include <svtools/imappoly.hxx>
54 #ifdef WIN
55 #include <sysdep.hxx>
56 #endif
57 #include <string.h>
58 #include <math.h>
60 #define NOTEOL(c) ((c)!='\0')
63 TYPEINIT0_AUTOFACTORY( ImageMap );
66 /******************************************************************************/
67 /******************************************************************************/
70 /******************************************************************************
74 \******************************************************************************/
76 void IMapObject::AppendCERNCoords( const Point& rPoint100, ByteString& rStr ) const
78 const Point aPixPt( Application::GetDefaultDevice()->LogicToPixel( rPoint100, MapMode( MAP_100TH_MM ) ) );
80 rStr += '(';
81 rStr += ByteString::CreateFromInt32( aPixPt.X() );
82 rStr += ',';
83 rStr += ByteString::CreateFromInt32( aPixPt.Y() );
84 rStr += ") ";
88 /******************************************************************************
92 \******************************************************************************/
94 void IMapObject::AppendNCSACoords( const Point& rPoint100, ByteString& rStr ) const
96 const Point aPixPt( Application::GetDefaultDevice()->LogicToPixel( rPoint100, MapMode( MAP_100TH_MM ) ) );
98 rStr += ByteString::CreateFromInt32( aPixPt.X() );
99 rStr += ',';
100 rStr += ByteString::CreateFromInt32( aPixPt.Y() );
101 rStr += ' ';
105 /******************************************************************************
109 \******************************************************************************/
111 void IMapObject::AppendCERNURL( ByteString& rStr, const String& rBaseURL ) const
113 rStr += ByteString( String(URIHelper::simpleNormalizedMakeRelative( rBaseURL, aURL )), gsl_getSystemTextEncoding() );
117 /******************************************************************************
121 \******************************************************************************/
123 void IMapObject::AppendNCSAURL( ByteString& rStr, const String& rBaseURL ) const
125 rStr += ByteString( String(URIHelper::simpleNormalizedMakeRelative( rBaseURL, aURL )), gsl_getSystemTextEncoding() );
126 rStr += ' ';
130 /******************************************************************************/
131 /******************************************************************************/
134 /******************************************************************************
138 \******************************************************************************/
140 void IMapRectangleObject::WriteCERN( SvStream& rOStm, const String& rBaseURL ) const
142 ByteString aStr( "rectangle " );
144 AppendCERNCoords( aRect.TopLeft(), aStr );
145 AppendCERNCoords( aRect.BottomRight(), aStr );
146 AppendCERNURL( aStr, rBaseURL );
148 rOStm.WriteLine( aStr );
152 /******************************************************************************
156 \******************************************************************************/
158 void IMapRectangleObject::WriteNCSA( SvStream& rOStm, const String& rBaseURL ) const
160 ByteString aStr( "rect " );
162 AppendNCSAURL( aStr, rBaseURL );
163 AppendNCSACoords( aRect.TopLeft(), aStr );
164 AppendNCSACoords( aRect.BottomRight(), aStr );
166 rOStm.WriteLine( aStr );
170 /******************************************************************************/
171 /******************************************************************************/
174 /******************************************************************************
178 \******************************************************************************/
180 void IMapCircleObject::WriteCERN( SvStream& rOStm, const String& rBaseURL ) const
182 ByteString aStr( "circle " );
184 AppendCERNCoords( aCenter, aStr );
185 aStr += ByteString::CreateFromInt32(nRadius);
186 aStr += ' ';
187 AppendCERNURL( aStr, rBaseURL );
189 rOStm.WriteLine( aStr );
193 /******************************************************************************
197 \******************************************************************************/
199 void IMapCircleObject::WriteNCSA( SvStream& rOStm, const String& rBaseURL ) const
201 ByteString aStr( "circle " );
203 AppendNCSAURL( aStr, rBaseURL );
204 AppendNCSACoords( aCenter, aStr );
205 AppendNCSACoords( aCenter + Point( nRadius, 0 ), aStr );
207 rOStm.WriteLine( aStr );
211 /******************************************************************************/
212 /******************************************************************************/
215 /******************************************************************************
219 \******************************************************************************/
221 void IMapPolygonObject::WriteCERN( SvStream& rOStm, const String& rBaseURL ) const
223 ByteString aStr( "polygon " );
224 const USHORT nCount = aPoly.GetSize();
226 for ( USHORT i = 0; i < nCount; i++ )
227 AppendCERNCoords( aPoly[ i ], aStr );
229 AppendCERNURL( aStr, rBaseURL );
231 rOStm.WriteLine( aStr );
235 /******************************************************************************
239 \******************************************************************************/
241 void IMapPolygonObject::WriteNCSA( SvStream& rOStm, const String& rBaseURL ) const
243 ByteString aStr( "poly " );
244 const USHORT nCount = Min( aPoly.GetSize(), (USHORT) 100 );
246 AppendNCSAURL( aStr, rBaseURL );
248 for ( USHORT i = 0; i < nCount; i++ )
249 AppendNCSACoords( aPoly[ i ], aStr );
251 rOStm.WriteLine( aStr );
255 /******************************************************************************/
256 /******************************************************************************/
259 /******************************************************************************
263 \******************************************************************************/
265 void ImageMap::Write( SvStream& rOStm, ULONG nFormat, const String& rBaseURL ) const
267 switch( nFormat )
269 case( IMAP_FORMAT_BIN ) : Write( rOStm, rBaseURL );
270 case( IMAP_FORMAT_CERN ) : ImpWriteCERN( rOStm, rBaseURL ); break;
271 case( IMAP_FORMAT_NCSA ) : ImpWriteNCSA( rOStm, rBaseURL ); break;
273 default:
274 break;
279 /******************************************************************************
283 \******************************************************************************/
285 void ImageMap::ImpWriteCERN( SvStream& rOStm, const String& rBaseURL ) const
287 IMapObject* pObj;
288 USHORT nCount = (USHORT) maList.Count();
290 for ( USHORT i = 0; i < nCount; i++ )
292 pObj = GetIMapObject( i );
294 switch( pObj->GetType() )
296 case( IMAP_OBJ_RECTANGLE ):
297 ( (IMapRectangleObject*) pObj )->WriteCERN( rOStm, rBaseURL );
298 break;
300 case( IMAP_OBJ_CIRCLE ):
301 ( (IMapCircleObject*) pObj )->WriteCERN( rOStm, rBaseURL );
302 break;
304 case( IMAP_OBJ_POLYGON ):
305 ( (IMapPolygonObject*) pObj )->WriteCERN( rOStm, rBaseURL );
306 break;
308 default:
309 break;
315 /******************************************************************************
319 \******************************************************************************/
321 void ImageMap::ImpWriteNCSA( SvStream& rOStm, const String& rBaseURL ) const
323 IMapObject* pObj;
324 USHORT nCount = (USHORT) maList.Count();
326 for ( USHORT i = 0; i < nCount; i++ )
328 pObj = GetIMapObject( i );
330 switch( pObj->GetType() )
332 case( IMAP_OBJ_RECTANGLE ):
333 ( (IMapRectangleObject*) pObj )->WriteNCSA( rOStm, rBaseURL );
334 break;
336 case( IMAP_OBJ_CIRCLE ):
337 ( (IMapCircleObject*) pObj )->WriteNCSA( rOStm, rBaseURL );
338 break;
340 case( IMAP_OBJ_POLYGON ):
341 ( (IMapPolygonObject*) pObj )->WriteNCSA( rOStm, rBaseURL );
342 break;
344 default:
345 break;
351 /******************************************************************************
355 \******************************************************************************/
357 ULONG ImageMap::Read( SvStream& rIStm, ULONG nFormat, const String& rBaseURL )
359 ULONG nRet = IMAP_ERR_FORMAT;
361 if ( nFormat == IMAP_FORMAT_DETECT )
362 nFormat = ImpDetectFormat( rIStm );
364 switch ( nFormat )
366 case ( IMAP_FORMAT_BIN ) : Read( rIStm, rBaseURL ); break;
367 case ( IMAP_FORMAT_CERN ) : nRet = ImpReadCERN( rIStm, rBaseURL ); break;
368 case ( IMAP_FORMAT_NCSA ) : nRet = ImpReadNCSA( rIStm, rBaseURL ); break;
370 default:
371 break;
374 if ( !rIStm.GetError() )
375 nRet = IMAP_ERR_OK;
377 return nRet;
381 /******************************************************************************
385 \******************************************************************************/
387 ULONG ImageMap::ImpReadCERN( SvStream& rIStm, const String& rBaseURL )
389 ByteString aStr;
391 // alten Inhalt loeschen
392 ClearImageMap();
394 while ( rIStm.ReadLine( aStr ) )
395 ImpReadCERNLine( aStr, rBaseURL );
397 return IMAP_ERR_OK;
401 /******************************************************************************
405 \******************************************************************************/
407 void ImageMap::ImpReadCERNLine( const ByteString& rLine, const String& rBaseURL )
409 ByteString aStr( rLine );
410 ByteString aToken;
412 aStr.EraseLeadingChars( ' ' );
413 aStr.EraseLeadingChars( '\t' );
414 aStr.EraseAllChars( ';' );
415 aStr.ToLowerAscii();
417 const char* pStr = aStr.GetBuffer();
418 char cChar = *pStr++;
420 // Anweisung finden
421 while( ( cChar >= 'a' ) && ( cChar <= 'z' ) && NOTEOL( cChar ) )
423 aToken += cChar;
424 cChar = *pStr++;
427 if ( NOTEOL( cChar ) )
429 if ( ( aToken == "rectangle" ) || ( aToken == "rect" ) )
431 const Point aTopLeft( ImpReadCERNCoords( &pStr ) );
432 const Point aBottomRight( ImpReadCERNCoords( &pStr ) );
433 const String aURL( ImpReadCERNURL( &pStr, rBaseURL ) );
434 const Rectangle aRect( aTopLeft, aBottomRight );
436 IMapRectangleObject* pObj = new IMapRectangleObject( aRect, aURL, String(), String(), String(), String() );
437 maList.Insert( pObj, LIST_APPEND );
439 else if ( ( aToken == "circle" ) || ( aToken == "circ" ) )
441 const Point aCenter( ImpReadCERNCoords( &pStr ) );
442 const long nRadius = ImpReadCERNRadius( &pStr );
443 const String aURL( ImpReadCERNURL( &pStr, rBaseURL ) );
445 IMapCircleObject* pObj = new IMapCircleObject( aCenter, nRadius, aURL, String(), String(), String(), String() );
446 maList.Insert( pObj, LIST_APPEND );
448 else if ( ( aToken == "polygon" ) || ( aToken == "poly" ) )
450 const USHORT nCount = aStr.GetTokenCount( '(' ) - 1;
451 Polygon aPoly( nCount );
452 String aURL;
454 for ( USHORT i = 0; i < nCount; i++ )
455 aPoly[ i ] = ImpReadCERNCoords( &pStr );
457 aURL = ImpReadCERNURL( &pStr, rBaseURL );
459 IMapPolygonObject* pObj = new IMapPolygonObject( aPoly, aURL, String(), String(), String(), String() );
460 maList.Insert( pObj, LIST_APPEND );
466 /******************************************************************************
470 \******************************************************************************/
472 Point ImageMap::ImpReadCERNCoords( const char** ppStr )
474 String aStrX;
475 String aStrY;
476 Point aPt;
477 char cChar = *(*ppStr)++;
479 while( NOTEOL( cChar ) && ( ( cChar < '0' ) || ( cChar > '9' ) ) )
480 cChar = *(*ppStr)++;
482 if ( NOTEOL( cChar ) )
484 while( NOTEOL( cChar ) && ( cChar >= '0' ) && ( cChar <= '9' ) )
486 aStrX += cChar;
487 cChar = *(*ppStr)++;
490 if ( NOTEOL( cChar ) )
492 while( NOTEOL( cChar ) && ( ( cChar < '0' ) || ( cChar > '9' ) ) )
493 cChar = *(*ppStr)++;
495 while( NOTEOL( cChar ) && ( cChar >= '0' ) && ( cChar <= '9' ) )
497 aStrY += cChar;
498 cChar = *(*ppStr)++;
501 if ( NOTEOL( cChar ) )
502 while( NOTEOL( cChar ) && ( cChar != ')' ) )
503 cChar = *(*ppStr)++;
505 aPt = Point( aStrX.ToInt32(), aStrY.ToInt32() );
509 return aPt;
513 /******************************************************************************
517 \******************************************************************************/
519 long ImageMap::ImpReadCERNRadius( const char** ppStr )
521 String aStr;
522 char cChar = *(*ppStr)++;
524 while( NOTEOL( cChar ) && ( ( cChar < '0' ) || ( cChar > '9' ) ) )
525 cChar = *(*ppStr)++;
527 if ( NOTEOL( cChar ) )
529 while( NOTEOL( cChar ) && ( cChar >= '0' ) && ( cChar <= '9' ) )
531 aStr += cChar;
532 cChar = *(*ppStr)++;
536 return aStr.ToInt32();
540 /******************************************************************************
544 \******************************************************************************/
546 String ImageMap::ImpReadCERNURL( const char** ppStr, const String& rBaseURL )
548 String aStr( String::CreateFromAscii( *ppStr ) );
550 aStr.EraseLeadingChars( ' ' );
551 aStr.EraseLeadingChars( '\t' );
552 aStr.EraseTrailingChars( ' ' );
553 aStr.EraseTrailingChars( '\t' );
555 return INetURLObject::GetAbsURL( rBaseURL, aStr );
559 /******************************************************************************
563 \******************************************************************************/
565 ULONG ImageMap::ImpReadNCSA( SvStream& rIStm, const String& rBaseURL )
567 ByteString aStr;
569 // alten Inhalt loeschen
570 ClearImageMap();
572 while ( rIStm.ReadLine( aStr ) )
573 ImpReadNCSALine( aStr, rBaseURL );
575 return IMAP_ERR_OK;
579 /******************************************************************************
583 \******************************************************************************/
585 void ImageMap::ImpReadNCSALine( const ByteString& rLine, const String& rBaseURL )
587 ByteString aStr( rLine );
588 ByteString aToken;
590 aStr.EraseLeadingChars( ' ' );
591 aStr.EraseLeadingChars( '\t' );
592 aStr.EraseAllChars( ';' );
593 aStr.ToLowerAscii();
595 const char* pStr = aStr.GetBuffer();
596 char cChar = *pStr++;
598 // Anweisung finden
599 while( ( cChar >= 'a' ) && ( cChar <= 'z' ) && NOTEOL( cChar ) )
601 aToken += cChar;
602 cChar = *pStr++;
605 if ( NOTEOL( cChar ) )
607 if ( aToken == "rect" )
609 const String aURL( ImpReadNCSAURL( &pStr, rBaseURL ) );
610 const Point aTopLeft( ImpReadNCSACoords( &pStr ) );
611 const Point aBottomRight( ImpReadNCSACoords( &pStr ) );
612 const Rectangle aRect( aTopLeft, aBottomRight );
614 IMapRectangleObject* pObj = new IMapRectangleObject( aRect, aURL, String(), String(), String(), String() );
615 maList.Insert( pObj, LIST_APPEND );
617 else if ( aToken == "circle" )
619 const String aURL( ImpReadNCSAURL( &pStr, rBaseURL ) );
620 const Point aCenter( ImpReadNCSACoords( &pStr ) );
621 const Point aDX( aCenter - ImpReadNCSACoords( &pStr ) );
622 long nRadius = (long) sqrt( (double) aDX.X() * aDX.X() +
623 (double) aDX.Y() * aDX.Y() );
625 IMapCircleObject* pObj = new IMapCircleObject( aCenter, nRadius, aURL, String(), String(), String(), String() );
626 maList.Insert( pObj, LIST_APPEND );
628 else if ( aToken == "poly" )
630 const USHORT nCount = aStr.GetTokenCount( ',' ) - 1;
631 const String aURL( ImpReadNCSAURL( &pStr, rBaseURL ) );
632 Polygon aPoly( nCount );
634 for ( USHORT i = 0; i < nCount; i++ )
635 aPoly[ i ] = ImpReadNCSACoords( &pStr );
637 IMapPolygonObject* pObj = new IMapPolygonObject( aPoly, aURL, String(), String(), String(), String() );
638 maList.Insert( pObj, LIST_APPEND );
644 /******************************************************************************
648 \******************************************************************************/
650 String ImageMap::ImpReadNCSAURL( const char** ppStr, const String& rBaseURL )
652 String aStr;
653 char cChar = *(*ppStr)++;
655 while( NOTEOL( cChar ) && ( ( cChar == ' ' ) || ( cChar == '\t' ) ) )
656 cChar = *(*ppStr)++;
658 if ( NOTEOL( cChar ) )
660 while( NOTEOL( cChar ) && ( cChar != ' ' ) && ( cChar != '\t' ) )
662 aStr += cChar;
663 cChar = *(*ppStr)++;
667 return INetURLObject::GetAbsURL( rBaseURL, aStr );
671 /******************************************************************************
675 \******************************************************************************/
677 Point ImageMap::ImpReadNCSACoords( const char** ppStr )
679 String aStrX;
680 String aStrY;
681 Point aPt;
682 char cChar = *(*ppStr)++;
684 while( NOTEOL( cChar ) && ( ( cChar < '0' ) || ( cChar > '9' ) ) )
685 cChar = *(*ppStr)++;
687 if ( NOTEOL( cChar ) )
689 while( NOTEOL( cChar ) && ( cChar >= '0' ) && ( cChar <= '9' ) )
691 aStrX += cChar;
692 cChar = *(*ppStr)++;
695 if ( NOTEOL( cChar ) )
697 while( NOTEOL( cChar ) && ( ( cChar < '0' ) || ( cChar > '9' ) ) )
698 cChar = *(*ppStr)++;
700 while( NOTEOL( cChar ) && ( cChar >= '0' ) && ( cChar <= '9' ) )
702 aStrY += cChar;
703 cChar = *(*ppStr)++;
706 aPt = Point( aStrX.ToInt32(), aStrY.ToInt32() );
710 return aPt;
714 /******************************************************************************
718 \******************************************************************************/
720 ULONG ImageMap::ImpDetectFormat( SvStream& rIStm )
722 ULONG nPos = rIStm.Tell();
723 ULONG nRet = IMAP_FORMAT_BIN;
724 char cMagic[6];
726 rIStm.Read( cMagic, sizeof( cMagic ) );
728 // Falls wir kein internes Format haben,
729 // untersuchen wir das Format
730 if ( memcmp( cMagic, IMAPMAGIC, sizeof( cMagic ) ) )
732 ByteString aStr;
733 long nCount = 128;
735 rIStm.Seek( nPos );
736 while ( rIStm.ReadLine( aStr ) && nCount-- )
738 aStr.ToLowerAscii();
740 if ( ( aStr.Search( "rect" ) != STRING_NOTFOUND ) ||
741 ( aStr.Search( "circ" ) != STRING_NOTFOUND ) ||
742 ( aStr.Search( "poly" ) != STRING_NOTFOUND ) )
744 if ( ( aStr.Search( '(' ) != STRING_NOTFOUND ) &&
745 ( aStr.Search( ')' ) != STRING_NOTFOUND ) )
747 nRet = IMAP_FORMAT_CERN;
749 else
750 nRet = IMAP_FORMAT_NCSA;
752 break;
757 rIStm.Seek( nPos );
759 return nRet;