lvyue schrieb:
Hi, Daniel
Thanks for your reply, and sorry I did not reply on time,
there is something wrong with my mail box.
and I have attached a diff in issue 93789,
http://www.openoffice.org/issues/show_bug.cgi?id=93789
can you check it and tell me where is wrong?
Found the problem... See below. I have some more comments regarding the
patch:
1)
+BOOL lclConvertMoney( const String aSearchUnit, double& rfRate, int&
rnDec )
+{
+#define COUNT 16
+#define CURRENCY( name ) \
+ (String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( name ) ))
+ ConvertInfo aConvertTable[ COUNT ] = {
+ { CURRENCY( "EUR" ), 1.0, 2 },
I am not sure (->Eike?) but initializing the strings this way may fail
with certain compilers.
Please do not #define the COUNT but calculate the array size after the
array. In the future, more countries may convert to the Euro currency.
This may be the source of errors when the next developer forgets to
update the COUNT after adding a line to the list. Better:
const ConvertInfo aConvertTable[] = {
...
};
const int COUNT = sizeof( aConvertTable ) / sizeof( ConvertInfo );
This is the byte-size of the entire table, divided by the byte-size of
one entry, therefore always the number of entries.
2)
But now for the interesting part:
+
+ case xlExtEuroConvert:
+ {
+ aStack << aPool.Store( ocEuroConvert,
pExtName->GetName() );
+ }
+ break;
Here, you push the ocEuroConvert op-code together with the function name
pExtName->GetName(). This will be converted by the filter to a token
containing op-code and string. The interpreter finds the token with
ocEuroConvert, gets its function name "EUROCONVERT" from the resources.
Then it finds an additional string "EUROCONVERT" in the token, and
appends it to the already existing function name. EUROCONVERT is an
internal name, therefore the function name must not be part of the
token. This is only needed for the ocExternal add-in functions. I see...
we need some more "dirty" hacking of the formula import code. First,
change the line to
aStack << aPool.Store( ocEuroConvert, String() );
to pass an empty string. The code to convert the Excel tokens to Calc
tokens is located in sc/source/filter/excel/tokstack.cxx. This code is
more than old and has been the source of some issues regarding formula
import :-(
In line 371, you find a "case T_Ext:" which converts the token added
with the "aPool.Store" call above to a Calc token. To not break anything
else (hopefully), this has to be changed to (new lines marked with +):
case T_Ext:
{
UINT16 n = pElement[ nId ];
EXTCONT* p = ( n < nP_Ext )? ppP_Ext[ n ] : NULL;
if( p )
+ {
+ if( p->eId == ocExternal )
+ pScToken->AddOpCode( p->eId );
+ else
pScToken->AddExternal( p->aText, p->eId );
+ }
}
break;
3)
+ else if ( maName == String::CreateFromAscii(
RTL_CONSTASCII_STRINGPARAM("EUROCONVERT") ) )
+ meType = xlExtEuroConvert;
Better readable would be:
else if ( maName.EqualsIgnoreCaseAscii( "EUROCONVERT" ) )
Attention: The name "EUROCONVERT" may be used in other external names
than the EUROTOOL addin (example: a user does not have the EUROTOOL
addin, and defines the named range "EUROCONVERT" in one of his documents
and refers to it from another document). So the information that the
name is part of the EUROTOOL.XLA addin has to be transported to the
constructor of XclImpExtName. Please replace the "bool bAddIn" parameter
by something else able to transport both information. For example, pass
the enum XclSupbookType directly instead of a bool testing for the
add-in type only:
else if ( (eType == EXC_SBTYPE_EUROTOOL) &&
maName.EqualsIgnoreCaseAscii( "EUROCONVERT" ) )
4)
+ if( String( maXclUrl.GetBuffer() + 1 )
+ == String::CreateFromAscii(
RTL_CONSTASCII_STRINGPARAM("EUROTOOL.XLA") ) )
In general, please use String::Copy() instead of String::GetBuffer(), it
is more readable and faster. The String::Copy() function takes 0 to 2
parameters, if it gets 1, it copies and returns from the passed position
to the end of the string. So, in this example, "maXclUrl.Copy( 1 )"
would do the same as "String( maXclUrl.GetBuffer() + 1 )" *and* is save
against empty strings. :-)
But, in our case, we should not ignore the first byte, there may be
another external reference to the regular file "XEUROTOOL.XLA" which
would trigger this comparison too. Better to use a case-insensitive
comparison to the full name:
if( maXclUrl.EqualsIgnoreCaseAscii( "\008EUROTOOL.XLA" ) )
Note the characters \008 which encode the ASCII character 8.
Best regards
Daniel
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]