merge the formfield patch from ooo-build
[ooovba.git] / framework / collector / uicmdstohtml.cxx
blob8b685b3e3d1b7670d90845a3a15f31db181fb401
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: uicmdstohtml.cxx,v $
10 * $Revision: 1.7 $
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_framework.hxx"
34 #include <sal/main.h>
35 #include <osl/file.hxx>
36 #include <osl/thread.h>
37 #include "tools/getprocessworkingdir.hxx"
38 #include <rtl/ustring.hxx>
39 #include <rtl/ustrbuf.hxx>
40 #include <rtl/strbuf.hxx>
41 #include <rtl/string.hxx>
43 #include <hash_map>
44 #include <vector>
45 #include <algorithm>
47 using namespace rtl;
49 enum MODULES
51 MODULE_GLOBAL,
52 MODULE_WRITER,
53 MODULE_CALC,
54 MODULE_DRAWIMPRESS,
55 MODULE_CHART,
56 MODULE_MATH,
57 MODULE_BASIC,
58 MODULE_BIBLIO,
59 MODULE_BACKINGCOMP,
60 MODULE_DBACCESS,
61 MODULE_COUNT
64 enum APPMODULES
66 APPMODULE_BACKINGCOMP,
67 APPMODULE_WRITER,
68 APPMODULE_WRITERWEB,
69 APPMODULE_WRITERGLOBAL,
70 APPMODULE_CALC,
71 APPMODULE_DRAW,
72 APPMODULE_IMPRESS,
73 APPMODULE_CHART,
74 APPMODULE_BIBLIOGRAPHY,
75 APPMODULE_BASICIDE,
76 APPMODULE_DBAPP,
77 APPMODULE_DBBROWSER,
78 APPMODULE_DBQUERY,
79 APPMODULE_DBRELATION,
80 APPMODULE_DBTABLE,
81 APPMODULE_COUNT
84 enum UIELEMENTTYPE
86 UITYPE_TOOLBAR,
87 UITYPE_MENUBAR,
88 UITYPE_STATUSBAR,
89 UITYPE_ACCELERATOR,
90 UITYPE_COUNT
93 struct Projects
95 const char* pProjectFolder;
96 const char* pResPrefix;
97 const char* pCSVPrefix;
98 bool bSlotCommands;
99 MODULES eBelongsTo;
102 struct AppModules
104 const char* pModuleName;
105 const char* pModuleIdentifier;
106 const char* pProjectFolder;
107 const char* pSubFolder;
110 struct UIElementTypeName
112 const char* Name;
113 const char* ShortName;
116 Projects ProjectModule_Mapping[] =
118 { "sfx2" , "sfx", "sfx2", true, MODULE_GLOBAL },
119 { "svx" , "svx", "svx", true, MODULE_GLOBAL },
120 { "svx" , "ofa", "ofa", true, MODULE_GLOBAL },
121 { "sw" , "sw", "sw", true, MODULE_WRITER },
122 { "sd" , "sd", "sd", true, MODULE_DRAWIMPRESS },
123 { "sc" , "sc", "sc", true, MODULE_CALC },
124 { "sch" , "sch", "sch", true, MODULE_CHART },
125 { "starmath" , "sm", "starmath", true, MODULE_MATH },
126 { "basctl" , "basctl", "bastctl", true, MODULE_BASIC },
127 { "extensions" , "bib", "", false, MODULE_BIBLIO },
128 { "framework" , "fwk", "", false, MODULE_BACKINGCOMP },
129 { "dbaccess" , "dbu", "", false, MODULE_DBACCESS },
130 { 0 , 0, "", false, MODULE_BASIC }
133 AppModules AppModules_Mapping[] =
135 { "Backing Component" , "startmodule" ,"framework" , 0 },
136 { "Writer" , "swriter" ,"sw" , 0 },
137 { "Writer Web" , "sweb" ,"sw" , 0 },
138 { "Writer Global" , "sglobal" ,"sw" , 0 },
139 { "Calc" , "scalc" ,"sc" , 0 },
140 { "Draw" , "sdraw" ,"sd" , 0 },
141 { "Impress" , "simpress" ,"sd" , 0 },
142 { "Chart" , "schart" ,"sch" , 0 },
143 { "Bibliography" , "sbibliography" ,"extensions", "source/bibliography" },
144 { "Basic IDE" , "basicide" ,"basctl" , 0 },
145 { "Database Application" , "dbapp" ,"dbaccess" , 0 },
146 { "Database Browser" , "dbbrowser" ,"dbaccess" , 0 },
147 { "Database Query" , "dbquery" ,"dbaccess" , 0 },
148 { "Database Relation" , "dbrelation" ,"dbaccess" , 0 },
149 { "Database Table" , "dbtable" ,"dbaccess" , 0 },
150 { 0 , 0 ,0 , 0 }
153 UIElementTypeName UIElementTypeFolderName[] =
155 { "toolbar", "T" },
156 { "menubar", "M" },
157 { "statusbar", "S" },
158 { "accelerator","A" },
159 { 0 }
162 const char UICONFIGFOLDER[] = "uiconfig";
164 const char XMLFileExtension[] = ".xcu";
165 const char* ModuleName[] =
167 "Global commands",
168 "Writer commands",
169 "Calc commands",
170 "Draw/Impress commands",
171 "Chart commands",
172 "Math commands",
173 "BasicIDE commands",
174 "Bibliography commands",
175 "Startmodule commands",
176 "Database commands",
180 const char* ModuleToXML_Mapping[] =
182 "GenericCommands",
183 "WriterCommands",
184 "CalcCommands",
185 "DrawImpressCommands",
186 "ChartCommands",
187 "MathCommands",
188 "BasicIDECommands",
189 "BibliographyCommands",
190 "StartModuleCommands",
191 "DbuCommands",
195 struct CommandLabels
197 unsigned short nID;
198 rtl::OUString aCommand;
199 rtl::OUString aDefine;
200 unsigned long nModules;
201 rtl::OUString aLabels;
202 unsigned long nProperties;
203 rtl::OUString aUIAvailable;
205 CommandLabels() :
206 nID( 0 ),
207 nModules( 0 ),
208 nProperties( 0 )
212 bool CommandLabels::operator< ( const CommandLabels& aCmdLabel ) const
214 return ( aCommand.compareTo( aCmdLabel.aCommand ) <= 0 );
218 struct CommandInfo
220 rtl::OUString aCommand;
221 unsigned long nAppModules; // bit field for every app module
222 unsigned long nUIElements; // bit field for every ui element type
224 bool CommandInfo::operator< ( const CommandInfo& aCmdInfo ) const
226 return ( aCommand.compareTo( aCmdInfo.aCommand ) <= 0 );
230 struct OUStringHashCode
232 size_t operator()( const ::rtl::OUString& sString ) const
234 return sString.hashCode();
238 typedef std::hash_map< rtl::OUString, CommandInfo, OUStringHashCode, ::std::equal_to< OUString > > CommandToCommandInfoMap;
239 typedef std::hash_map< int, CommandLabels > CommandIDToLabelsMap;
240 typedef std::vector< CommandLabels > CommandLabelsVector;
241 typedef std::vector< CommandInfo > CommandInfoVector;
243 static CommandIDToLabelsMap moduleMapFiles[MODULE_COUNT];
244 static CommandLabelsVector moduleCmdVector[MODULE_COUNT];
245 static CommandToCommandInfoMap commandInfoMap;
246 static CommandInfoVector commandInfoVector;
248 bool ExtractVersionNumber( const OUString& rVersion, OUString& rVersionNumber )
250 bool bCheckNumOnly( false );
252 OUStringBuffer aBuf;
254 rVersionNumber = OUString();
255 for ( int i = 0; i < rVersion.getLength(); i++ )
257 if ( rVersion[i] >= sal_Unicode( '0' ) && rVersion[i] <= sal_Unicode( '9' ))
259 bCheckNumOnly = true;
260 aBuf.append( rVersion[i] );
262 else if ( bCheckNumOnly )
263 return false;
266 rVersionNumber = aBuf.makeStringAndClear();
267 return true;
270 bool ReadCSVFile( const OUString& aCVSFileURL, MODULES eModule, const OUString& aProjectName )
272 osl::File aCSVFile( aCVSFileURL );
273 fprintf(stdout, "############ read csv \"%s\" ... ", ::rtl::OUStringToOString(aCVSFileURL, RTL_TEXTENCODING_UTF8).getStr());
274 if ( aCSVFile.open( OpenFlag_Read ) != osl::FileBase::E_None )
276 fprintf(stdout, "failed!\n");
277 return false;
279 fprintf(stdout, "OK!\n");
282 sal_Bool bEOF;
283 ::rtl::ByteSequence aCSVLine;
284 OUString aUnoCmd( RTL_CONSTASCII_USTRINGPARAM( ".uno:" ));
286 while ( aCSVFile.isEndOfFile( &bEOF ) == osl::FileBase::E_None && !bEOF )
288 aCSVFile.readLine( aCSVLine );
290 OString aLine( (const char *)aCSVLine.getConstArray(), aCSVLine.getLength() );
291 OString aDefine;
292 OString aID;
293 OString aAccelState;
294 OString aMenuState;
295 OString aStatusState;
296 OString aToolbarState;
297 OString aCmdName;
298 OString aSlotName;
299 OString aImageRotationState;
300 OString aImageReflectionState;
302 sal_Int32 nIndex = 0;
303 aDefine = aLine.getToken( 1, ',', nIndex );
304 aID = aLine.getToken( 0, ',', nIndex );
305 aAccelState = aLine.getToken( 2, ',', nIndex );
306 aMenuState = aLine.getToken( 0, ',', nIndex );
307 aStatusState = aLine.getToken( 0, ',', nIndex );
308 aToolbarState = aLine.getToken( 0, ',', nIndex );
309 aImageRotationState = aLine.getToken( 8, ',', nIndex );
310 aImageReflectionState = aLine.getToken( 0, ',', nIndex );
311 aCmdName = aLine.getToken( 10, ',', nIndex );
312 aSlotName = aLine.getToken( 1, ',', nIndex );
314 if ( aCmdName.getLength() == 0 )
315 aCmdName = aSlotName;
317 int nID = aID.toInt32();
319 if ( nID > 5000 && ( aAccelState.equalsIgnoreAsciiCase( "TRUE" ) ||
320 aMenuState.equalsIgnoreAsciiCase( "TRUE" ) ||
321 aStatusState.equalsIgnoreAsciiCase( "TRUE" ) ||
322 aToolbarState.equalsIgnoreAsciiCase( "TRUE" ) ))
324 CommandLabels aCmdLabel;
326 aCmdLabel.nID = nID;
327 aCmdLabel.aCommand += OStringToOUString( aCmdName, RTL_TEXTENCODING_ASCII_US );
328 aCmdLabel.nModules |= ( 1 << (unsigned long)( eModule ));
329 aCmdLabel.aDefine = OStringToOUString( aDefine, RTL_TEXTENCODING_ASCII_US );
331 OUString aUIAvailable;
332 if ( aAccelState.equalsIgnoreAsciiCase( "TRUE" ) ||
333 aMenuState.equalsIgnoreAsciiCase( "TRUE" ) ||
334 aToolbarState.equalsIgnoreAsciiCase( "TRUE" ))
335 aUIAvailable = OUString::createFromAscii( "AMT" );
336 else if ( aStatusState.equalsIgnoreAsciiCase( "TRUE" ))
337 aUIAvailable = OUString::createFromAscii( "S" );
338 aCmdLabel.aUIAvailable = aUIAvailable;
340 // Set bitfield
341 aCmdLabel.nProperties = (( aImageRotationState.equalsIgnoreAsciiCase( "TRUE" ) ? 1 : 0 ) << 1 );
342 aCmdLabel.nProperties |= (( aImageReflectionState.equalsIgnoreAsciiCase( "TRUE" ) ? 1 : 0 ) << 2 );
344 moduleMapFiles[int(eModule)].insert( CommandIDToLabelsMap::value_type( nID, aCmdLabel ));
348 aCSVFile.close();
351 return true;
354 bool ReadXMLFile( const OUString& aFileURL, APPMODULES eAppModule, UIELEMENTTYPE eUIType, const char* pItemTag, const char* pAttributeTag, sal_Int32 nAttributeTagSize )
356 osl::File aXMLFile( aFileURL );
357 if ( aXMLFile.open( OpenFlag_Read ) != osl::FileBase::E_None )
359 fprintf(stdout, "failed!\n");
360 return false;
363 sal_Bool bEOF;
364 ::rtl::ByteSequence aXMLLine;
366 while ( aXMLFile.isEndOfFile( &bEOF ) == osl::FileBase::E_None && !bEOF )
368 aXMLFile.readLine( aXMLLine );
370 OString aLine( (const char *)aXMLLine.getConstArray(), aXMLLine.getLength() );
372 if ( aLine.indexOf( pItemTag ) >= 0 )
374 sal_Int32 nIndex = aLine.indexOf( pAttributeTag );
375 if (( nIndex >= 0 ) && (( nIndex+nAttributeTagSize+1 ) < aLine.getLength() ))
377 sal_Int32 nIndex2 = aLine.indexOf( "\"", nIndex+nAttributeTagSize );
378 OString aCmd = aLine.copy( nIndex+nAttributeTagSize, (nIndex2-(nIndex+nAttributeTagSize)) );
380 OUString aCmdString = OStringToOUString( aCmd, RTL_TEXTENCODING_ASCII_US );
382 CommandToCommandInfoMap::iterator pIter = commandInfoMap.find( aCmdString );
383 if ( pIter != commandInfoMap.end() )
385 pIter->second.nAppModules |= ( 1 << eAppModule );
386 pIter->second.nUIElements |= ( 1 << eUIType );
388 else
390 CommandInfo aCmdInfo;
391 aCmdInfo.aCommand = aCmdString;
392 aCmdInfo.nAppModules = ( 1 << eAppModule );
393 aCmdInfo.nUIElements = ( 1 << eUIType );
394 commandInfoMap.insert( CommandToCommandInfoMap::value_type( aCmdString, aCmdInfo ));
400 return true;
403 bool ReadMenuBarXML( const OUString& aFileURL, APPMODULES eAppModule )
405 static char MENUITEM_TAG[] = "<menu:menuitem";
406 static char MENUITEM_ID[] = "menu:id=\"";
407 static int MENUITEM_ID_SIZE = strlen( MENUITEM_ID );
409 return ReadXMLFile( aFileURL, eAppModule, UITYPE_MENUBAR, MENUITEM_TAG, MENUITEM_ID, MENUITEM_ID_SIZE );
412 bool ReadToolBarXML( const OUString& aFileURL, APPMODULES eAppModule )
414 static char TOOLBARITEM_TAG[] = "<toolbar:toolbaritem";
415 static char TOOLBARITEM_ID[] = "xlink:href=\"";
416 static int TOOLBARITEM_ID_SIZE = strlen( TOOLBARITEM_ID );
418 return ReadXMLFile( aFileURL, eAppModule, UITYPE_TOOLBAR, TOOLBARITEM_TAG, TOOLBARITEM_ID, TOOLBARITEM_ID_SIZE );
421 bool ReadStatusBarXML( const rtl::OUString& aFileURL, APPMODULES eAppModule )
423 static char STATUSBARITEM_TAG[] = "<statusbar:statusbaritem";
424 static char STATUSBARITEM_ID[] = "xlink:href=\"";
425 static int STATUSBARITEM_ID_SIZE = strlen( STATUSBARITEM_ID );
427 return ReadXMLFile( aFileURL, eAppModule, UITYPE_STATUSBAR, STATUSBARITEM_TAG, STATUSBARITEM_ID, STATUSBARITEM_ID_SIZE );
430 bool ReadAcceleratorXML( const rtl::OUString& aFileURL, APPMODULES eAppModule )
432 static char ACCELERATORITEM_TAG[] = "<accel:item";
433 static char ACCELERATORITEM_ID[] = "xlink:href=\"";
434 static int ACCELERATORITEM_ID_SIZE = strlen( ACCELERATORITEM_ID );
436 return ReadXMLFile( aFileURL, eAppModule, UITYPE_ACCELERATOR, ACCELERATORITEM_TAG, ACCELERATORITEM_ID, ACCELERATORITEM_ID_SIZE );
439 bool ReadXMLFile( const rtl::OUString& aFileURL, APPMODULES eAppModule, UIELEMENTTYPE eUIElementType )
441 switch ( eUIElementType )
443 case UITYPE_TOOLBAR:
444 return ReadToolBarXML( aFileURL, eAppModule );
445 case UITYPE_MENUBAR:
446 return ReadMenuBarXML( aFileURL, eAppModule );
447 case UITYPE_STATUSBAR:
448 return ReadStatusBarXML( aFileURL, eAppModule );
449 case UITYPE_ACCELERATOR:
450 return ReadAcceleratorXML( aFileURL, eAppModule );
451 default:
452 return false;
456 bool ReadXMLFilesForAppModule( const rtl::OUString& aFolderURL, APPMODULES eAppModule )
458 osl::Directory aDir( aFolderURL );
459 if ( aDir.open() == osl::FileBase::E_None )
461 osl::DirectoryItem aFolderItem;
462 while ( aDir.getNextItem( aFolderItem ) == osl::FileBase::E_None )
464 osl::FileStatus aFileStatus( FileStatusMask_FileName );
466 aFolderItem.getFileStatus( aFileStatus );
468 OUString aFolderName = aFileStatus.getFileName();
469 int i=0;
470 while ( i < UITYPE_COUNT )
472 if ( aFolderName.equalsAscii( UIElementTypeFolderName[i].Name ))
474 OUStringBuffer aBuf( aFolderURL );
475 aBuf.appendAscii( "/" );
476 aBuf.append( aFolderName );
478 OUString aUIElementFolderURL( aBuf.makeStringAndClear() );
479 osl::Directory aUIElementTypeDir( aUIElementFolderURL );
480 if ( aUIElementTypeDir.open() == osl::FileBase::E_None )
482 osl::DirectoryItem aItem;
483 while ( aUIElementTypeDir.getNextItem( aItem ) == osl::FileBase::E_None )
485 osl::FileStatus aFileStatus( FileStatusMask_FileName );
487 aItem.getFileStatus( aFileStatus );
488 if ( aFileStatus.getFileType() == osl_File_Type_Regular )
490 OUStringBuffer aBuf( aUIElementFolderURL );
491 aBuf.appendAscii( "/" );
492 aBuf.append( aFileStatus.getFileName() );
494 ReadXMLFile( aBuf.makeStringAndClear(), eAppModule, (UIELEMENTTYPE)i );
496 else if (( aFileStatus.getFileType() == osl_File_Type_Directory ) &&
497 ( aFileStatus.getFileName().equalsAscii( "en-US" )))
499 // Accelerators are language-dependent
500 OUStringBuffer aBuf( aUIElementFolderURL );
501 aBuf.appendAscii( "/" );
502 aBuf.append( aFileStatus.getFileName() );
503 aBuf.appendAscii( "/default.xml" );
505 ReadXMLFile( aBuf.makeStringAndClear(), eAppModule, (UIELEMENTTYPE)i );
509 break;
511 ++i;
516 return true;
519 void SortCommandTable( MODULES eModule )
521 // copy entries from hash_map to vector
522 CommandIDToLabelsMap::iterator pIter = moduleMapFiles[int( eModule)].begin();
523 while ( pIter != moduleMapFiles[int( eModule )].end() )
525 CommandLabels& rCmdLabels = pIter->second;
526 moduleCmdVector[int( eModule )].push_back( rCmdLabels );
527 ++pIter;
530 CommandLabelsVector::iterator pIterStart = moduleCmdVector[int(eModule)].begin();
531 CommandLabelsVector::iterator pIterEnd = moduleCmdVector[int(eModule)].end();
533 std::sort( pIterStart, pIterEnd );
536 void SortCommandInfoVector()
538 // copy entries from hash_map to vector
539 CommandToCommandInfoMap::iterator pIter = commandInfoMap.begin();
540 while ( pIter != commandInfoMap.end() )
542 CommandInfo& rCmdInfo = pIter->second;
543 commandInfoVector.push_back( rCmdInfo );
544 ++pIter;
547 CommandInfoVector::iterator pIterStart = commandInfoVector.begin();
548 CommandInfoVector::iterator pIterEnd = commandInfoVector.end();
550 std::sort( pIterStart, pIterEnd );
553 CommandLabels* RetrieveCommandLabelsFromID( unsigned short nId, MODULES eModule )
555 CommandIDToLabelsMap::iterator pIter = moduleMapFiles[MODULE_GLOBAL].find( nId );
556 if ( pIter != moduleMapFiles[MODULE_GLOBAL].end() )
557 return &(pIter->second);
558 else if ( eModule != MODULE_GLOBAL )
560 CommandIDToLabelsMap::iterator pIter = moduleMapFiles[eModule].find( nId );
561 if ( pIter != moduleMapFiles[eModule].end() )
562 return &(pIter->second);
565 return NULL;
568 static const char ENCODED_AMPERSAND[] = "&amp;";
569 static const char ENCODED_LESS[] = "&lt;";
570 static const char ENCODED_GREATER[] = "&gt;";
571 static const char ENCODED_QUOTE[] = "&quot;";
572 static const char ENCODED_APOS[] = "&apos;";
574 struct EncodeChars
576 char cChar;
577 const char* pEncodedChars;
580 EncodeChars EncodeChar_Map[] =
582 { '&', ENCODED_AMPERSAND },
583 { '<', ENCODED_LESS },
584 { '>', ENCODED_GREATER },
585 { '"', ENCODED_QUOTE },
586 { '\'', ENCODED_APOS },
587 { ' ', 0 }
590 // Encodes a string to UTF-8 and uses "Built-in entity reference" to
591 // to escape character data that is not markup!
592 OString EncodeString( const OUString& aToEncodeStr )
594 OString aString = OUStringToOString( aToEncodeStr, RTL_TEXTENCODING_UTF8 );
596 int i = 0;
597 bool bMustCopy( sal_False );
598 while ( EncodeChar_Map[i].pEncodedChars != 0 )
600 OStringBuffer aBuf;
601 bool bEncoded( false );
603 sal_Int32 nCurIndex = 0;
604 sal_Int32 nIndex = 0;
605 while ( nIndex < aString.getLength() )
607 nIndex = aString.indexOf( EncodeChar_Map[i].cChar, nIndex );
608 if ( nIndex > 0 )
610 bEncoded = true;
611 if ( nIndex > nCurIndex )
612 aBuf.append( aString.copy( nCurIndex, nIndex-nCurIndex ));
613 aBuf.append( EncodeChar_Map[i].pEncodedChars );
614 nCurIndex = nIndex+1;
616 else if ( nIndex == 0 )
618 bEncoded = true;
619 aBuf.append( EncodeChar_Map[i].pEncodedChars );
620 nCurIndex = nIndex+1;
622 else
624 if ( bEncoded && nCurIndex < aString.getLength() )
625 aBuf.append( aString.copy( nCurIndex ));
626 break;
628 ++nIndex;
631 if ( bEncoded )
632 aString = aBuf.makeStringAndClear();
633 ++i;
636 return aString;
639 static const char HTMLStart[] = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n";
640 static const char HTMLHead[] = "<html>\n \
641 <head>\n \
642 \n \
643 <meta http-equiv=\"CONTENT-TYPE\"\n \
644 content=\"text/html; charset=windows-1252\">\n \
645 <title>OpenOffice.org 2.0 : Index of command names</title>\n \
646 \n \
647 <style>\n \
648 <!-- \n \
649 BODY,DIV,TABLE,THEAD,TBODY,TFOOT,TR,TH,TD,P { font-family:\"Albany\"; font-size:x-small }\n \
650 -->\n \
651 </style>\n \
652 \n \
653 </head>\n \
654 <body text=\"#000000\">";
656 static const char HTMLJumpTable[] = "<h1><b>Command tables for OpenOffice.org 2.0<br/>\n \
657 </b></h1>\n \
658 <br/>\n \
659 <p>The following tables list all available commands that are\n \
660 accessible through the GUI. The command names are used with the \".uno:\"\n \
661 protocol scheme to define framework commands. These command URLs can be\n \
662 used to dispatch/execute, like \".uno:About\" shows the about box.\n \
663 Please keep in mind that slot-URLs are deprecated for OpenOffice.org 2.0 and\n \
664 shouldn't be used anymore.<br/>\n \
665 <br/>\n \
666 Abbreviations:<br/>\n \
667 A = accelerator<br/>\n \
668 M = menu<br/>\n \
669 T = toolbox<br/>\n \
670 S = status bar<br/>\n \
671 </p>\n \
672 <br/>\n";
674 bool WriteLevel( osl::File& rFile, int nLevel )
676 const char cTab[] = "\t";
678 sal_uInt64 nWritten;
679 for ( int i = 0; i < nLevel; i++ )
680 rFile.write( cTab, strlen( cTab ), nWritten );
682 return true;
685 bool WriteJumpTable( osl::File& rFile )
687 static const char JUMP_ENTRY_1[] = "- ";
688 static const char JUMP_LINK_1[] = "<a href=\"#";
689 static const char JUMP_LINK_2[] = "\">";
690 static const char JUMP_LINK_3[] = "</a>";
691 static const char JUMP_ENTRY_2[] = "<br/>\n";
693 sal_uInt64 nWritten;
695 rFile.write( HTMLJumpTable, strlen( HTMLJumpTable ), nWritten );
697 sal_uInt32 i = 0;
698 while ( ModuleName[i] != 0 )
700 if ( !moduleMapFiles[i].empty() )
702 OString aTableNameStr( ModuleName[i] );
703 OStringBuffer aJumpMark( aTableNameStr );
705 // convert jump mark
706 for ( sal_Int32 j = 0; j < aJumpMark.getLength(); j++ )
707 if ( aJumpMark[j] == ' ' )
708 aJumpMark.setCharAt( j, '_' );
710 rFile.write( JUMP_ENTRY_1, strlen( JUMP_ENTRY_1 ), nWritten );
711 rFile.write( JUMP_LINK_1, strlen( JUMP_LINK_1 ), nWritten );
712 rFile.write( aJumpMark, aJumpMark.getLength(), nWritten );
713 rFile.write( JUMP_LINK_2, strlen( JUMP_LINK_2 ), nWritten );
714 rFile.write( aTableNameStr, aTableNameStr.getLength(), nWritten );
715 rFile.write( JUMP_LINK_3, strlen( JUMP_LINK_3 ), nWritten );
716 rFile.write( JUMP_ENTRY_2, strlen( JUMP_ENTRY_2 ), nWritten );
718 i++;
721 return true;
724 bool WriteHTMLTable( osl::File& rFile, const rtl::OUString& aTableName )
726 static const char TABLE_NAME1[] = "<h2>";
727 static const char TABLE_NAME2[] = "</h2>\n";
728 static const char ANCHOR_1[] = "<a name=\"";
729 static const char ANCHOR_2[] = "\"></a>";
730 static const char TABLE_FRAME[] = "<table frame=\"box\" cellspacing=\"0\" cols=\"4\" rules=\"groups\" border=\"1\">\n";
731 static const char COLGROUPS1[] = "<colgroup><col width=\"189\"></colgroup> <colgroup><col width=\"93\"></colgroup>\n";
732 static const char COLGROUPS2[] = "<colgroup><col width=\"277\"></colgroup> <colgroup><col width=\"47\"></colgroup>\n";
733 static const char TBODY_1[] = "<tbody>\n\t<tr>\n";
734 static const char TBODY_2[] = "\t</tr>\n</tbody>\n";
735 static const char TD_1[] = "<td width=\"189\" height=\"17\" align=\"left\"><b>Commands</b></td>\n";
736 static const char TD_2[] = "<td width=\"93\" align=\"left\"><b>GUI Elements</b></td>\n";
737 static const char TD_3[] = "<td width=\"277\" align=\"left\"><b>Internal definitions of commands ID</b></td>\n";
738 static const char TD_4[] = "<td width=\"47\" align=\"left\"><b>ID</b></td>\n";
740 if ( aTableName.getLength() > 0 )
742 sal_uInt64 nWritten;
743 OString aTableNameStr = OUStringToOString( aTableName, RTL_TEXTENCODING_ASCII_US );
744 OStringBuffer aJumpMark( aTableNameStr );
746 // convert jump mark
747 for ( sal_Int32 j = 0; j < aJumpMark.getLength(); j++ )
748 if ( aJumpMark[j] == ' ' )
749 aJumpMark.setCharAt( j, '_' );
751 rFile.write( TABLE_NAME1, strlen( TABLE_NAME1 ), nWritten );
752 rFile.write( ANCHOR_1, strlen( ANCHOR_1 ), nWritten );
753 rFile.write( aJumpMark, aJumpMark.getLength(), nWritten );
754 rFile.write( ANCHOR_2, strlen( ANCHOR_2 ), nWritten );
755 rFile.write( aTableNameStr, aTableNameStr.getLength(), nWritten );
756 rFile.write( TABLE_NAME2, strlen( TABLE_NAME2 ), nWritten );
757 rFile.write( TABLE_FRAME, strlen( TABLE_FRAME ), nWritten );
758 rFile.write( COLGROUPS1, strlen( COLGROUPS1 ), nWritten );
759 rFile.write( COLGROUPS2, strlen( COLGROUPS2 ), nWritten );
760 rFile.write( TBODY_1, strlen( TBODY_1 ), nWritten );
761 rFile.write( TD_1, strlen( TD_1 ), nWritten );
762 rFile.write( TD_2, strlen( TD_2 ), nWritten );
763 rFile.write( TD_3, strlen( TD_3 ), nWritten );
764 rFile.write( TD_4, strlen( TD_4 ), nWritten );
767 return true;
770 bool WriteHTMLTableRow( osl::File& rFile, const CommandLabels& rCmdLabels )
772 static const char TBODY_1[] = "<tbody>\n\t<tr>\n";
773 static const char TBODY_2[] = "\t</tr>\n</tbody>\n";
774 static const char TD_FIRST[] = "\t<td height=\"17\" align=\"left\">";
775 static const char TD_L[] = "\t<td align=\"left\">";
776 static const char TD_R[] = "\t<td align=\"right\">";
777 static const char TD_CLOSE[] = "</td>\n";
779 OString aCmdStr = OUStringToOString( rCmdLabels.aCommand, RTL_TEXTENCODING_UTF8 );
780 OString aUIStr = OUStringToOString( rCmdLabels.aUIAvailable, RTL_TEXTENCODING_UTF8 );
781 OString aDefStr = OUStringToOString( rCmdLabels.aDefine, RTL_TEXTENCODING_UTF8 );
782 OString aIDStr = OString::valueOf( sal_Int32( rCmdLabels.nID ));
784 sal_uInt64 nWritten;
785 rFile.write( TBODY_1, strlen( TBODY_1 ), nWritten );
787 rFile.write( TD_FIRST, strlen( TD_FIRST ), nWritten );
788 rFile.write( aCmdStr, aCmdStr.getLength(), nWritten );
789 rFile.write( TD_CLOSE, strlen( TD_CLOSE ), nWritten );
791 rFile.write( TD_L, strlen( TD_L ), nWritten );
792 rFile.write( aUIStr, aUIStr.getLength(), nWritten );
793 rFile.write( TD_CLOSE, strlen( TD_CLOSE ), nWritten );
795 rFile.write( TD_L, strlen( TD_L ), nWritten );
796 rFile.write( aDefStr, aDefStr.getLength(), nWritten );
797 rFile.write( TD_CLOSE, strlen( TD_CLOSE ), nWritten );
799 rFile.write( TD_R, strlen( TD_R ), nWritten );
800 rFile.write( aIDStr, aIDStr.getLength(), nWritten );
801 rFile.write( TD_CLOSE, strlen( TD_CLOSE ), nWritten );
803 rFile.write( TBODY_2, strlen( TBODY_2 ), nWritten );
805 return true;
808 bool WriteHTMLTableClose( osl::File& rFile )
810 static const char TBODY_CLOSE[] = "\t</tr>\n</tbody>\n";
811 static const char TABLE_CLOSE[] = "</table>\n";
812 static const char BR[] = "<br/>\n";
814 sal_uInt64 nWritten;
815 rFile.write( TBODY_CLOSE, strlen( TBODY_CLOSE ), nWritten );
816 rFile.write( TABLE_CLOSE, strlen( TABLE_CLOSE ), nWritten );
817 rFile.write( BR, strlen( BR ), nWritten );
819 return true;
822 bool WriteHTMLFile( const OUString& aOutputDirURL)
824 OUString aOutputDirectoryURL( aOutputDirURL );
825 if ( aOutputDirectoryURL.getLength() > 0 && aOutputDirectoryURL[aOutputDirectoryURL.getLength()-1] != '/' )
826 aOutputDirectoryURL += OUString::createFromAscii( "/" );
828 OUString aOutputFileURL( aOutputDirectoryURL );
829 aOutputFileURL += OUString::createFromAscii( "commandsReference.html" );
831 osl::File aHTMLFile( aOutputFileURL );
832 osl::File::RC nRet = aHTMLFile.open( OpenFlag_Create|OpenFlag_Write );
833 if ( nRet == osl::File::E_EXIST )
835 nRet = aHTMLFile.open( OpenFlag_Write );
836 if ( nRet == osl::File::E_None )
837 nRet = aHTMLFile.setSize( 0 );
840 if ( nRet == osl::FileBase::E_None )
842 sal_uInt64 nWritten;
844 aHTMLFile.write( HTMLStart, strlen( HTMLStart ), nWritten );
845 aHTMLFile.write( HTMLHead, strlen( HTMLHead ), nWritten );
847 WriteJumpTable( aHTMLFile );
849 int i = 0;
850 while ( ModuleToXML_Mapping[i] != 0 )
852 SortCommandTable( MODULES( i ));
853 if ( !moduleCmdVector[i].empty() )
855 WriteHTMLTable( aHTMLFile, OUString::createFromAscii( ModuleName[i] ));
857 for ( sal_uInt32 j = 0; j < moduleCmdVector[i].size(); j++ )
859 CommandLabels& rCmdLabels = (moduleCmdVector[i])[j];
860 WriteHTMLTableRow( aHTMLFile, rCmdLabels );
863 WriteHTMLTableClose( aHTMLFile );
865 ++i;
867 aHTMLFile.close();
870 return true;
873 bool WriteUICommand( osl::File& rFile, const CommandInfo& rCmdInfo )
875 static const char MODULE_HAS_COMMAND[] = ",1";
876 static const char MODULE_NOT_COMMAND[] = ",0";
877 static const char NEWLINE[] = "\n";
878 static const char COMMA[] = ",";
880 sal_uInt64 nWritten;
882 OString aCommand = OUStringToOString( rCmdInfo.aCommand, RTL_TEXTENCODING_ASCII_US );
884 rFile.write( aCommand, aCommand.getLength(), nWritten );
885 rFile.write( COMMA, strlen( COMMA ), nWritten );
887 if ( rCmdInfo.nUIElements & ( 1<<UITYPE_ACCELERATOR ))
888 rFile.write( UIElementTypeFolderName[UITYPE_ACCELERATOR].ShortName, strlen( UIElementTypeFolderName[UITYPE_ACCELERATOR].ShortName ), nWritten );
889 if ( rCmdInfo.nUIElements & ( 1<<UITYPE_TOOLBAR))
890 rFile.write( UIElementTypeFolderName[UITYPE_TOOLBAR].ShortName, strlen( UIElementTypeFolderName[UITYPE_TOOLBAR].ShortName ), nWritten );
891 if ( rCmdInfo.nUIElements & ( 1<<UITYPE_MENUBAR ))
892 rFile.write( UIElementTypeFolderName[UITYPE_MENUBAR].ShortName, strlen( UIElementTypeFolderName[UITYPE_MENUBAR].ShortName ), nWritten );
893 if ( rCmdInfo.nUIElements & ( 1<<UITYPE_STATUSBAR ))
894 rFile.write( UIElementTypeFolderName[UITYPE_STATUSBAR].ShortName, strlen( UIElementTypeFolderName[UITYPE_STATUSBAR].ShortName ), nWritten );
896 sal_Int32 nApps = rCmdInfo.nAppModules;
897 for ( sal_Int32 i = 0; i < APPMODULE_COUNT; i++ )
899 if ( nApps & ( 1 << i ))
900 rFile.write( MODULE_HAS_COMMAND, strlen( MODULE_HAS_COMMAND ), nWritten );
901 else
902 rFile.write( MODULE_NOT_COMMAND, strlen( MODULE_NOT_COMMAND ), nWritten );
904 rFile.write( NEWLINE, strlen( NEWLINE ), nWritten );
906 return true;
909 bool WriteUICommands( const OUString& aOutputDirURL )
911 static const char COMMA[] = ",";
912 static const char HEADER[] = "User interface command, GUI Element";
913 static const char NEWLINE[] = "\n";
915 OUString aOutputDirectoryURL( aOutputDirURL );
916 if ( aOutputDirectoryURL.getLength() > 0 && aOutputDirectoryURL[aOutputDirectoryURL.getLength()-1] != '/' )
917 aOutputDirectoryURL += OUString::createFromAscii( "/" );
919 OUString aOutputFileURL( aOutputDirectoryURL );
920 aOutputFileURL += OUString::createFromAscii( "UsedCommands.csv" );
922 osl::File aCSVFile( aOutputFileURL );
923 osl::File::RC nRet = aCSVFile.open( OpenFlag_Create|OpenFlag_Write );
924 if ( nRet == osl::File::E_EXIST )
926 nRet = aCSVFile.open( OpenFlag_Write );
927 if ( nRet == osl::File::E_None )
928 nRet = aCSVFile.setSize( 0 );
931 if ( nRet == osl::FileBase::E_None )
933 sal_uInt64 nWritten;
935 aCSVFile.write( HEADER, strlen( HEADER ), nWritten );
936 for ( sal_Int32 i = 0; i < APPMODULE_COUNT; i++ )
938 aCSVFile.write( COMMA, strlen( COMMA ), nWritten );
939 aCSVFile.write( AppModules_Mapping[i].pModuleName, strlen( AppModules_Mapping[i].pModuleName ), nWritten );
941 aCSVFile.write( NEWLINE, strlen( NEWLINE ), nWritten );
943 for ( sal_uInt32 j = 0; j < commandInfoVector.size(); j++ )
945 const CommandInfo& rCmdInfo = commandInfoVector[j];
946 WriteUICommand( aCSVFile, rCmdInfo );
949 aCSVFile.close();
952 return true;
955 bool Convert( sal_Bool bUseProduct,
956 const OUString& aUseRes,
957 const OUString& rVersion,
958 const OUString& rOutputDirName,
959 const OUString& rPlatformName,
960 const std::vector< OUString >& rInDirVector,
961 const OUString& rErrOutputFileName )
963 OUString aWorkDir;
965 tools::getProcessWorkingDir( &aWorkDir );
967 // Try to find xx*.csv file and put all commands into hash table
968 for ( int i = 0; i < (int)rInDirVector.size(); i++ )
970 OUString aAbsInDirURL;
971 OUString aInDirURL;
972 OUString aInDir( rInDirVector[i] );
974 osl::FileBase::getFileURLFromSystemPath( aInDir, aInDirURL );
975 osl::FileBase::getAbsoluteFileURL( aWorkDir, aInDirURL, aAbsInDirURL );
976 osl::Directory aDir( aAbsInDirURL );
977 if ( aDir.open() == osl::FileBase::E_None )
979 osl::DirectoryItem aItem;
980 while ( aDir.getNextItem( aItem ) == osl::FileBase::E_None )
982 osl::FileStatus aFileStatus( FileStatusMask_FileName );
984 aItem.getFileStatus( aFileStatus );
986 int j=0;
987 OUString aFileName = aFileStatus.getFileName();
989 while ( ProjectModule_Mapping[j].pProjectFolder != 0 &&
990 ProjectModule_Mapping[j].bSlotCommands == true )
992 if ( aFileName.equalsAscii( ProjectModule_Mapping[j].pProjectFolder ))
994 OUStringBuffer aBuf( aAbsInDirURL );
996 aBuf.appendAscii( "/" );
997 aBuf.append( aFileStatus.getFileName() );
998 aBuf.appendAscii( "/" );
999 aBuf.append( rPlatformName );
1000 if ( bUseProduct )
1001 aBuf.appendAscii( ".pro" );
1002 aBuf.appendAscii( "/misc/xx" );
1003 aBuf.appendAscii( ProjectModule_Mapping[j].pCSVPrefix );
1004 aBuf.appendAscii( ".csv" );
1006 OUString aCSVFileURL( aBuf.makeStringAndClear() );
1007 ReadCSVFile( aCSVFileURL, ProjectModule_Mapping[j].eBelongsTo, OUString::createFromAscii( ProjectModule_Mapping[j].pProjectFolder ));
1008 break;
1010 ++j;
1013 j = 0;
1014 while ( AppModules_Mapping[j].pModuleIdentifier != 0 )
1016 if ( aFileName.equalsAscii( AppModules_Mapping[j].pProjectFolder ))
1018 OUStringBuffer aBuf( aAbsInDirURL );
1020 aBuf.appendAscii( "/" );
1021 aBuf.append( aFileName );
1022 aBuf.appendAscii( "/" );
1023 if ( AppModules_Mapping[j].pSubFolder != 0 )
1025 aBuf.appendAscii( AppModules_Mapping[j].pSubFolder );
1026 aBuf.appendAscii( "/" );
1028 aBuf.appendAscii( UICONFIGFOLDER );
1029 aBuf.appendAscii( "/" );
1030 aBuf.appendAscii( AppModules_Mapping[j].pModuleIdentifier );
1032 OUString aXMLAppModuleFolder( aBuf.makeStringAndClear() );
1033 ReadXMLFilesForAppModule( aXMLAppModuleFolder, (APPMODULES)j );
1035 ++j;
1039 aDir.close();
1043 OUString aOutDirURL;
1044 osl::FileBase::getFileURLFromSystemPath( rOutputDirName, aOutDirURL );
1045 osl::FileBase::getAbsoluteFileURL( aWorkDir, aOutDirURL, aOutDirURL );
1047 WriteHTMLFile( aOutDirURL );
1049 SortCommandInfoVector();
1050 WriteUICommands( aOutDirURL );
1052 return true;
1055 bool GetCommandOption( const ::std::vector< OUString >& rArgs, const OUString& rSwitch, OUString& rParam )
1057 bool bRet = false;
1058 OUString aSwitch( OUString::createFromAscii( "-" ));
1060 aSwitch += rSwitch;
1061 for( int i = 0, nCount = rArgs.size(); ( i < nCount ) && !bRet; i++ )
1063 for( int n = 0; ( n < 2 ) && !bRet; n++ )
1065 if ( aSwitch.equalsIgnoreAsciiCase( rArgs[ i ] ))
1067 bRet = true;
1069 if( i < ( nCount - 1 ) )
1070 rParam = rArgs[ i + 1 ];
1071 else
1072 rParam = OUString();
1077 return bRet;
1080 // -----------------------------------------------------------------------
1082 bool GetCommandOptions( const ::std::vector< OUString >& rArgs, const OUString& rSwitch, ::std::vector< OUString >& rParams )
1084 bool bRet = false;
1086 OUString aSwitch( OUString::createFromAscii( "-" ));
1088 aSwitch += rSwitch;
1089 for( int i = 0, nCount = rArgs.size(); ( i < nCount ); i++ )
1091 for( int n = 0; ( n < 2 ) && !bRet; n++ )
1093 if ( aSwitch.equalsIgnoreAsciiCase( rArgs[ i ] ))
1095 if( i < ( nCount - 1 ) )
1096 rParams.push_back( rArgs[ i + 1 ] );
1097 else
1098 rParams.push_back( OUString() );
1100 break;
1105 return( rParams.size() > 0 );
1108 void ShowUsage()
1110 fprintf( stderr, "Usage: uicmdxml output_dir -r res -v version [-p] -s platform -i input_dir [-i input_dir] [-f errfile]\n" );
1111 fprintf( stderr, "Options:" );
1112 fprintf( stderr, " -r [oo|so] use resources from ooo, so\n" );
1113 fprintf( stderr, " -v name of the version used, f.e. SRX645, SRC680\n" );
1114 fprintf( stderr, " -p use product version\n" );
1115 fprintf( stderr, " -s name of the system to use, f.e. wntmsci8, unxsols4, unxlngi5\n" );
1116 fprintf( stderr, " -i ... name of directory to be searched for input files [multiple occurence is possible]\n" );
1117 fprintf( stderr, " -f name of file, error output should be written to\n" );
1118 fprintf( stderr, "Examples:\n" );
1119 fprintf( stderr, " uicmd2html /home/out -r so -v SRC680 -p unxlngi5 -i /home/res -f /home/out/log.err\n" );
1122 // -----------------------------------------------------------------------
1124 int main ( int argc, char ** argv)
1126 ::std::vector< OUString > aArgs;
1128 sal_uInt32 nCmds = argc;
1129 if ( nCmds >= 8 )
1131 for ( sal_Int32 i=0; i < sal_Int32( nCmds ); i++ )
1133 OUString aArg = OStringToOUString( argv[i], osl_getThreadTextEncoding() );
1134 aArgs.push_back( aArg );
1137 ::std::vector< OUString > aInDirVector;
1138 OUString aErrOutputFileName;
1139 OUString aOutputDirName( aArgs[0] );
1140 OUString aOutDirURL;
1141 OUString aPlatformName;
1142 OUString aVersion;
1143 OUString aUseRes;
1144 bool bUseProduct;
1145 OUString aDummy;
1147 osl::FileBase::getFileURLFromSystemPath( aOutputDirName, aOutDirURL );
1148 sal_Int32 j = aOutDirURL.lastIndexOf( '/' );
1149 if ( j > 0 )
1150 aOutDirURL = aOutDirURL.copy( 0, j+1 );
1151 osl::FileBase::getSystemPathFromFileURL( aOutDirURL, aOutputDirName );
1153 GetCommandOption( aArgs, OUString::createFromAscii( "v" ), aVersion );
1154 bUseProduct = GetCommandOption( aArgs, OUString::createFromAscii( "p" ), aDummy );
1155 GetCommandOption( aArgs, OUString::createFromAscii( "s" ), aPlatformName );
1156 GetCommandOptions( aArgs, OUString::createFromAscii( "i" ), aInDirVector );
1157 GetCommandOption( aArgs, OUString::createFromAscii( "f" ), aErrOutputFileName );
1158 GetCommandOption( aArgs, OUString::createFromAscii( "r" ), aUseRes );
1160 if ( aVersion.getLength() > 0 &&
1161 aPlatformName.getLength() > 0 &&
1162 aUseRes.getLength() > 0 &&
1163 aInDirVector.size() > 0 )
1165 Convert( bUseProduct, aUseRes, aVersion, aOutputDirName, aPlatformName, aInDirVector, aErrOutputFileName );
1167 else
1169 ShowUsage();
1170 exit( -1 );
1173 else
1175 ShowUsage();
1176 exit( -1 );