forked from amazingfate/loongoffice
* commit 'ooo/DEV300_m101': (185 commits) masterfix DEV300: #i10000# usage of L10N build_type masterfix: #i10000# INT16 -> sal_Int16 fixed compile errors after resync to m100, part2 gridsort: post-rebase fixes CWS gnumake3: found another tools integer type removetooltypes01: Fix build problems after rebase to DEV300m99 in basctl, cui, reportdesign, sw native359: #i114398# changing mac langpack icon native359: #i115669# fixing package description for solaris packages gnumake3: remove comphelper version; fix including extract.hxx locales34: #i106785# add Haitian_Haiti [ht-HT] to language list and locale data; locale data contributed by <jcpoulard> sb138: #i116659# timely termination of OnLogRotateThread accfixes: removed include of obsolete header file accfixes: removed obsolete file removetooltypes01: #i112600# Fix build problems on non-pro accfixes: moved some shared strings to svx part2 accfixes: moved some shared strings to svx accfixes: added more accessibility information and fixed tab orders in multiple dialogs (cui module) removetooltypes01: #i112600# Remove tools types for Mac specific parts fixed tab order in BasicIDE, Library dialog tab page added some accessible names in BasicIDE ... Conflicts: UnoControls/source/base/registercontrols.cxx accessibility/inc/accessibility/standard/vclxaccessiblelistboxlist.hxx automation/inc/automation/communi.hxx automation/inc/automation/simplecm.hxx automation/source/communi/communi.cxx automation/source/inc/rcontrol.hxx automation/source/miniapp/servuid.hxx automation/source/server/XMLParser.cxx automation/source/server/cmdbasestream.cxx automation/source/server/profiler.hxx automation/source/server/recorder.cxx automation/source/server/retstrm.hxx automation/source/server/server.cxx automation/source/server/sta_list.cxx automation/source/server/statemnt.cxx automation/source/server/statemnt.hxx automation/source/simplecm/packethandler.cxx automation/source/simplecm/simplecm.cxx automation/source/simplecm/tcpio.cxx automation/source/simplecm/tcpio.hxx automation/source/testtool/comm_bas.hxx automation/source/testtool/cretstrm.hxx automation/source/testtool/httprequest.cxx automation/source/testtool/httprequest.hxx automation/source/testtool/objtest.cxx automation/source/testtool/objtest.hxx basctl/source/basicide/baside2.cxx basctl/source/basicide/baside2.hxx basctl/source/basicide/baside2b.cxx basctl/source/basicide/baside3.cxx basctl/source/basicide/basides1.cxx basctl/source/basicide/basides2.cxx basctl/source/basicide/basidesh.cxx basctl/source/basicide/basidesh.src basctl/source/basicide/basobj3.cxx basctl/source/basicide/bastype2.cxx basctl/source/basicide/bastype3.cxx basctl/source/basicide/bastypes.cxx basctl/source/basicide/brkdlg.cxx basctl/source/basicide/iderdll.cxx basctl/source/basicide/macrodlg.cxx basctl/source/basicide/moduldl2.cxx basctl/source/basicide/moduldlg.cxx basctl/source/basicide/objdlg.cxx basctl/source/basicide/scriptdocument.cxx basctl/source/basicide/tbxctl.cxx basctl/source/basicide/tbxctl.hxx basctl/source/basicide/tbxctl.src basctl/source/dlged/dlged.cxx basctl/source/dlged/dlgedfunc.cxx basctl/source/dlged/dlgedobj.cxx basctl/source/inc/basidesh.hxx basctl/source/inc/bastypes.hxx basctl/source/inc/dlgedmod.hxx basctl/source/inc/dlgedpage.hxx crashrep/prj/build.lst cui/inc/pch/precompiled_cui.hxx cui/source/customize/acccfg.cxx cui/source/customize/acccfg.hrc cui/source/customize/acccfg.src cui/source/customize/cfg.cxx cui/source/customize/cfgutil.cxx cui/source/customize/macropg.cxx cui/source/customize/macropg.src cui/source/customize/selector.cxx cui/source/dialogs/SpellDialog.cxx cui/source/dialogs/commonlingui.cxx cui/source/dialogs/cuicharmap.cxx cui/source/dialogs/cuifmsearch.cxx cui/source/dialogs/cuigaldlg.cxx cui/source/dialogs/cuigrfflt.cxx cui/source/dialogs/hldocntp.cxx cui/source/dialogs/hldoctp.cxx cui/source/dialogs/hlinettp.cxx cui/source/dialogs/hlmailtp.cxx cui/source/dialogs/hlmarkwn.cxx cui/source/dialogs/hlmarkwn.src cui/source/dialogs/hltpbase.cxx cui/source/dialogs/iconcdlg.cxx cui/source/dialogs/passwdomdlg.cxx cui/source/dialogs/pastedlg.cxx cui/source/dialogs/scriptdlg.cxx cui/source/dialogs/thesdlg.cxx cui/source/dialogs/zoom.cxx cui/source/factory/dlgfact.hxx cui/source/inc/SpellDialog.hxx cui/source/inc/autocdlg.hxx cui/source/inc/backgrnd.hxx cui/source/inc/bbdlg.hxx cui/source/inc/cfg.hxx cui/source/inc/cfgutil.hxx cui/source/inc/cuigaldlg.hxx cui/source/inc/cuigrfflt.hxx cui/source/inc/cuitabarea.hxx cui/source/inc/cuitabline.hxx cui/source/inc/hldocntp.hxx cui/source/inc/hltpbase.hxx cui/source/inc/iconcdlg.hxx cui/source/inc/numpages.hxx cui/source/inc/page.hxx cui/source/inc/postdlg.hxx cui/source/inc/scriptdlg.hxx cui/source/inc/transfrm.hxx cui/source/inc/zoom.hxx cui/source/options/cfgchart.cxx cui/source/options/cuisrchdlg.cxx cui/source/options/dbregister.cxx cui/source/options/dbregister.src cui/source/options/fontsubs.cxx cui/source/options/internationaloptions.cxx cui/source/options/optasian.cxx cui/source/options/optchart.cxx cui/source/options/optcolor.cxx cui/source/options/optcolor.src cui/source/options/optfltr.cxx cui/source/options/optfltr.src cui/source/options/optgdlg.cxx cui/source/options/optgdlg.src cui/source/options/optgenrl.cxx cui/source/options/opthtml.cxx cui/source/options/optimprove.cxx cui/source/options/optinet2.cxx cui/source/options/optinet2.hxx cui/source/options/optjava.cxx cui/source/options/optlingu.cxx cui/source/options/optsave.cxx cui/source/options/optsave.hxx cui/source/options/treeopt.cxx cui/source/options/webconninfo.cxx cui/source/tabpages/autocdlg.cxx cui/source/tabpages/backgrnd.cxx cui/source/tabpages/border.cxx cui/source/tabpages/chardlg.cxx cui/source/tabpages/dstribut.cxx cui/source/tabpages/grfpage.cxx cui/source/tabpages/macroass.cxx cui/source/tabpages/measure.cxx cui/source/tabpages/numfmt.cxx cui/source/tabpages/numpages.cxx cui/source/tabpages/page.cxx cui/source/tabpages/paragrph.cxx cui/source/tabpages/swpossizetabpage.cxx cui/source/tabpages/tabarea.src cui/source/tabpages/textanim.cxx cui/source/tabpages/textattr.cxx cui/source/tabpages/tparea.cxx cui/source/tabpages/tpbitmap.cxx cui/source/tabpages/tpcolor.cxx cui/source/tabpages/tpgradnt.cxx cui/source/tabpages/tphatch.cxx cui/source/tabpages/tpline.cxx cui/source/tabpages/tplnedef.cxx cui/source/tabpages/tplneend.cxx cui/source/tabpages/tpshadow.cxx cui/source/tabpages/transfrm.cxx embedserv/source/embed/register.cxx extensions/inc/pch/precompiled_extensions.hxx extensions/inc/propctrlr.hrc extensions/source/abpilot/abpservices.cxx extensions/source/bibliography/bibload.cxx extensions/source/bibliography/datman.cxx extensions/source/bibliography/general.cxx extensions/source/dbpilots/dbpservices.cxx extensions/source/inc/componentmodule.cxx extensions/source/nsplugin/source/so_env.cxx extensions/source/ole/oleobjw.cxx extensions/source/ole/oleobjw.hxx extensions/source/oooimprovement/invite_job.cxx extensions/source/oooimprovement/onlogrotate_job.cxx extensions/source/plugin/base/service.cxx extensions/source/plugin/inc/plugin/unx/mediator.hxx extensions/source/plugin/inc/plugin/unx/plugcon.hxx extensions/source/plugin/unx/mediator.cxx extensions/source/plugin/unx/nppapi.cxx extensions/source/plugin/unx/plugcon.cxx extensions/source/preload/services.cxx extensions/source/propctrlr/formmetadata.cxx extensions/source/propctrlr/pcrservices.cxx extensions/source/resource/resource.cxx extensions/source/scanner/sane.hxx extensions/source/scanner/sanedlg.cxx extensions/source/scanner/scanunx.cxx extensions/source/scanner/scanwin.cxx extensions/source/scanner/twain.cxx extensions/source/scanner/twain.hxx extensions/source/update/check/updatecheckconfig.cxx extensions/test/stm/datatest.cxx extensions/test/stm/marktest.cxx extensions/test/stm/pipetest.cxx extensions/test/stm/testfactreg.cxx extensions/workben/testpgp.cxx forms/qa/complex/forms/CheckOGroupBoxModel.java forms/qa/makefile.mk forms/source/component/Button.cxx forms/source/component/Button.hxx forms/source/component/ListBox.cxx forms/source/inc/forms_module_impl.hxx forms/source/misc/services.cxx forms/source/solar/control/navtoolbar.cxx javainstaller2/prj/build.lst javainstaller2/src/JavaSetup/org/openoffice/setup/Util/ModuleCtrl.java lingucomponent/prj/build.lst lingucomponent/source/hyphenator/altlinuxhyph/hyphen/hyphenimp.cxx lingucomponent/source/spellcheck/spell/sreg.cxx lingucomponent/source/spellcheck/spell/sspellimp.cxx package/source/manifest/ManifestExport.cxx package/source/manifest/UnoRegister.cxx package/source/xstor/owriteablestream.cxx package/source/xstor/owriteablestream.hxx package/source/xstor/xstorage.hxx package/source/zippackage/ZipPackageFolder.cxx package/source/zippackage/ZipPackageStream.cxx setup_native/source/mac/ooo/DS_Store setup_native/source/win32/customactions/shellextensions/registerextensions.cxx xmlsecurity/prj/build.lst xmlsecurity/source/component/registerservices.cxx xmlsecurity/source/dialogs/stbcontrl.cxx xmlsecurity/source/framework/xsec_framework.cxx xmlsecurity/source/xmlsec/xsec_xmlsec.cxx xmlsecurity/tools/demo/util.hxx xmlsecurity/workben/signaturetest.cxx
571 lines
20 KiB
C++
571 lines
20 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*************************************************************************
|
|
*
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* Copyright 2000, 2010 Oracle and/or its affiliates.
|
|
*
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
|
*
|
|
* This file is part of OpenOffice.org.
|
|
*
|
|
* OpenOffice.org is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License version 3
|
|
* only, as published by the Free Software Foundation.
|
|
*
|
|
* OpenOffice.org is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Lesser General Public License version 3 for more details
|
|
* (a copy is included in the LICENSE file that accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* version 3 along with OpenOffice.org. If not, see
|
|
* <http://www.openoffice.org/license.html>
|
|
* for a copy of the LGPLv3 License.
|
|
*
|
|
************************************************************************/
|
|
|
|
|
|
// MARKER(update_precomp.py): autogen include statement, do not remove
|
|
#include "precompiled_forms.hxx"
|
|
#include <string.h>
|
|
#include <sal/types.h>
|
|
#include <rtl/alloc.h>
|
|
#include <rtl/ustring.hxx>
|
|
#include <rtl/string.hxx>
|
|
#include <rtl/ustrbuf.hxx>
|
|
#include <rtl/strbuf.hxx>
|
|
#include <tools/date.hxx>
|
|
#include <tools/time.hxx>
|
|
#include <tools/datetime.hxx>
|
|
|
|
#include <com/sun/star/uno/Reference.hxx>
|
|
#include <com/sun/star/uno/Sequence.hxx>
|
|
#include <com/sun/star/uno/Any.hxx>
|
|
#include <com/sun/star/xforms/XModel.hpp>
|
|
#include <com/sun/star/xml/dom/XNode.hpp>
|
|
#include <com/sun/star/xml/dom/XDocument.hpp>
|
|
#include <com/sun/star/lang/XUnoTunnel.hpp>
|
|
|
|
#include "xpathlib.hxx"
|
|
|
|
#include "extension.hxx"
|
|
|
|
// C interface
|
|
|
|
using namespace com::sun::star::uno;
|
|
using namespace com::sun::star::xml::dom;
|
|
using namespace com::sun::star::xforms;
|
|
using namespace com::sun::star::lang;
|
|
|
|
xmlXPathFunction xforms_lookupFunc(void *, const xmlChar *xname, const xmlChar *)
|
|
{
|
|
|
|
const char *name = (char *)xname;
|
|
if (strcmp("boolean-from-string", name)==0)
|
|
return xforms_booleanFromStringFunction;
|
|
else if ((strcmp("if", name))==0)
|
|
return xforms_ifFunction;
|
|
else if ((strcmp("avg", name))==0)
|
|
return xforms_avgFunction;
|
|
else if ((strcmp("min", name))==0)
|
|
return xforms_minFunction;
|
|
else if ((strcmp("max", name))==0)
|
|
return xforms_maxFunction;
|
|
else if ((strcmp("count-non-empty", name))==0)
|
|
return xforms_countNonEmptyFunction;
|
|
else if ((strcmp("index", name))==0)
|
|
return xforms_indexFunction;
|
|
else if ((strcmp("property", name))==0)
|
|
return xforms_propertyFunction;
|
|
else if ((strcmp("now", name))==0)
|
|
return xforms_nowFunction;
|
|
else if ((strcmp("days-from-date", name))==0)
|
|
return xforms_daysFromDateFunction;
|
|
else if ((strcmp("seconds-from-dateTime", name))==0)
|
|
return xforms_secondsFromDateTimeFunction;
|
|
else if ((strcmp("seconds", name))==0)
|
|
return xforms_secondsFuction;
|
|
else if ((strcmp("months", name))==0)
|
|
return xforms_monthsFuction;
|
|
else if ((strcmp("instance", name))==0)
|
|
return xforms_instanceFuction;
|
|
else if ((strcmp("current", name))==0)
|
|
return xforms_currentFunction;
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
// boolean functions
|
|
void xforms_booleanFromStringFunction(xmlXPathParserContextPtr ctxt, int nargs)
|
|
{
|
|
if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
|
|
xmlChar *pString = xmlXPathPopString(ctxt);
|
|
if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
|
|
::rtl::OUString aString((char*)pString, strlen((char*)pString), RTL_TEXTENCODING_UTF8);
|
|
if (aString.equalsIgnoreAsciiCaseAscii("true") || aString.equalsIgnoreAsciiCaseAscii("1"))
|
|
xmlXPathReturnTrue(ctxt);
|
|
else if (aString.equalsIgnoreAsciiCaseAscii("false") || aString.equalsIgnoreAsciiCaseAscii("0"))
|
|
xmlXPathReturnFalse(ctxt);
|
|
else
|
|
XP_ERROR(XPATH_NUMBER_ERROR);
|
|
}
|
|
|
|
void xforms_ifFunction(xmlXPathParserContextPtr ctxt, int nargs)
|
|
{
|
|
if (nargs != 3) XP_ERROR(XPATH_INVALID_ARITY);
|
|
xmlChar *s2 = xmlXPathPopString(ctxt);
|
|
|
|
if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
|
|
xmlChar *s1 = xmlXPathPopString(ctxt);
|
|
if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
|
|
bool aBool = xmlXPathPopBoolean(ctxt);
|
|
if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
|
|
|
|
if (aBool)
|
|
xmlXPathReturnString(ctxt, s1);
|
|
else
|
|
xmlXPathReturnString(ctxt, s2);
|
|
|
|
}
|
|
|
|
// Number Functions
|
|
void xforms_avgFunction(xmlXPathParserContextPtr ctxt, int nargs)
|
|
{
|
|
// use sum(), div() and count()
|
|
if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
|
|
|
|
// save nodeset
|
|
xmlXPathObjectPtr pObject = valuePop(ctxt);
|
|
if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
|
|
//push back a copy
|
|
valuePush(ctxt, xmlXPathObjectCopy(pObject));
|
|
// get the Sum
|
|
xmlXPathSumFunction(ctxt, 1);
|
|
double nSum = xmlXPathPopNumber(ctxt);
|
|
// push a copy once more
|
|
valuePush(ctxt, xmlXPathObjectCopy(pObject));
|
|
xmlXPathCountFunction(ctxt, 1);
|
|
double nCount = xmlXPathPopNumber(ctxt);
|
|
// push args for div()
|
|
xmlXPathReturnNumber(ctxt, nSum);
|
|
xmlXPathReturnNumber(ctxt, nCount);
|
|
xmlXPathDivValues(ctxt);
|
|
// the result is now on the ctxt stack
|
|
xmlXPathFreeObject(pObject);
|
|
}
|
|
|
|
void xforms_minFunction(xmlXPathParserContextPtr ctxt, int nargs)
|
|
{
|
|
if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
|
|
xmlNodeSetPtr pNodeSet = xmlXPathPopNodeSet(ctxt);
|
|
if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
|
|
double nMinimum = 0;
|
|
double nNumber = 0;
|
|
for (int i = 0; i < xmlXPathNodeSetGetLength(pNodeSet); i++)
|
|
{
|
|
nNumber = xmlXPathCastNodeToNumber(xmlXPathNodeSetItem(pNodeSet, i));
|
|
if (xmlXPathIsNaN(nNumber))
|
|
{
|
|
xmlXPathReturnNumber(ctxt, xmlXPathNAN);
|
|
return;
|
|
}
|
|
if (i == 0)
|
|
nMinimum = nNumber;
|
|
else if (nNumber < nMinimum)
|
|
nMinimum = nNumber;
|
|
}
|
|
xmlXPathReturnNumber(ctxt, nMinimum);
|
|
}
|
|
|
|
void xforms_maxFunction(xmlXPathParserContextPtr ctxt, int nargs)
|
|
{
|
|
if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
|
|
xmlNodeSetPtr pNodeSet = xmlXPathPopNodeSet(ctxt);
|
|
if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
|
|
double nMaximum = 0;
|
|
double nNumber = 0;
|
|
for (int i = 0; i < xmlXPathNodeSetGetLength(pNodeSet); i++)
|
|
{
|
|
nNumber = xmlXPathCastNodeToNumber(xmlXPathNodeSetItem(pNodeSet, i));
|
|
if (xmlXPathIsNaN(nNumber))
|
|
{
|
|
xmlXPathReturnNumber(ctxt, xmlXPathNAN);
|
|
return;
|
|
}
|
|
if (i == 0)
|
|
nMaximum = nNumber;
|
|
else if (nNumber > nMaximum)
|
|
nMaximum = nNumber;
|
|
}
|
|
xmlXPathReturnNumber(ctxt, nMaximum);
|
|
}
|
|
void xforms_countNonEmptyFunction(xmlXPathParserContextPtr ctxt, int nargs)
|
|
{
|
|
if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
|
|
xmlNodeSetPtr pNodeSet = xmlXPathPopNodeSet(ctxt);
|
|
if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
|
|
xmlChar *aString;
|
|
sal_Int32 nNotEmpty = 0;
|
|
for (int i = 0; i < xmlXPathNodeSetGetLength(pNodeSet); i++)
|
|
{
|
|
aString = xmlXPathCastNodeToString(xmlXPathNodeSetItem(pNodeSet, i));
|
|
if (*aString != 0) nNotEmpty++;
|
|
}
|
|
xmlXPathReturnNumber(ctxt, nNotEmpty);
|
|
}
|
|
void xforms_indexFunction(xmlXPathParserContextPtr /*ctxt*/, int /*nargs*/)
|
|
{
|
|
// function index takes a string argument that is the IDREF of a
|
|
// 'repeat' and returns the current 1-based position of the repeat
|
|
// index of the identified repeat -- see xforms/9.3.1
|
|
|
|
// doc.getElementByID
|
|
// (...)
|
|
}
|
|
|
|
// String Functions
|
|
static const char* _version = "1.0";
|
|
static const char* _conformance = "conformance";
|
|
void xforms_propertyFunction(xmlXPathParserContextPtr ctxt, int nargs)
|
|
{
|
|
if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
|
|
xmlChar* pString = xmlXPathPopString(ctxt);
|
|
if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
|
|
::rtl::OUString aString((char*)pString, strlen((char*)pString), RTL_TEXTENCODING_UTF8);
|
|
if (aString.equalsIgnoreAsciiCaseAscii("version"))
|
|
xmlXPathReturnString(ctxt, (xmlChar*)_version);
|
|
else if (aString.equalsIgnoreAsciiCaseAscii("conformance-level"))
|
|
xmlXPathReturnString(ctxt, (xmlChar*)_conformance);
|
|
else
|
|
xmlXPathReturnEmptyString(ctxt);
|
|
}
|
|
|
|
// Date and Time Functions
|
|
|
|
static ::rtl::OString makeDateTimeString (const DateTime& aDateTime, sal_Bool bUTC = sal_True)
|
|
{
|
|
::rtl::OStringBuffer aDateTimeString;
|
|
aDateTimeString.append((sal_Int32)aDateTime.GetYear());
|
|
aDateTimeString.append("-");
|
|
if (aDateTime.GetMonth()<10) aDateTimeString.append("0");
|
|
aDateTimeString.append((sal_Int32)aDateTime.GetMonth());
|
|
aDateTimeString.append("-");
|
|
if (aDateTime.GetDay()<10) aDateTimeString.append("0");
|
|
aDateTimeString.append((sal_Int32)aDateTime.GetDay());
|
|
aDateTimeString.append("T");
|
|
if (aDateTime.GetHour()<10) aDateTimeString.append("0");
|
|
aDateTimeString.append((sal_Int32)aDateTime.GetHour());
|
|
aDateTimeString.append(":");
|
|
if (aDateTime.GetMin()<10) aDateTimeString.append("0");
|
|
aDateTimeString.append((sal_Int32)aDateTime.GetMin());
|
|
aDateTimeString.append(":");
|
|
if (aDateTime.GetSec()<10) aDateTimeString.append("0");
|
|
aDateTimeString.append((sal_Int32)aDateTime.GetSec());
|
|
if (bUTC) aDateTimeString.append("Z");
|
|
|
|
return aDateTimeString.makeStringAndClear();
|
|
}
|
|
|
|
// returns current system date and time in canonical xsd:dateTime
|
|
// format
|
|
void xforms_nowFunction(xmlXPathParserContextPtr ctxt, int /*nargs*/)
|
|
{
|
|
/*
|
|
A single lexical representation, which is a subset of the lexical representations
|
|
allowed by [ISO 8601], is allowed for dateTime. This lexical representation is the
|
|
[ISO 8601] extended format CCYY-MM-DDThh:mm:ss where "CC" represents the century,
|
|
"YY" the year, "MM" the month and "DD" the day, preceded by an optional leading "-"
|
|
sign to indicate a negative number. If the sign is omitted, "+" is assumed. The letter
|
|
"T" is the date/time separator and "hh", "mm", "ss" represent hour, minute and second
|
|
respectively.
|
|
*/
|
|
|
|
/*
|
|
3.2.7.2 Canonical representation
|
|
The canonical representation for dateTime is defined by prohibiting certain options
|
|
from the Lexical representation (par.3.2.7.1). Specifically, either the time zone must
|
|
be omitted or, if present, the time zone must be Coordinated Universal Time (UTC)
|
|
indicated by a "Z".
|
|
*/
|
|
DateTime aDateTime;
|
|
::rtl::OString aDateTimeString = makeDateTimeString(aDateTime);
|
|
xmlChar *pString = static_cast<xmlChar*>(xmlMalloc(aDateTimeString.getLength()+1));
|
|
strncpy((char*)pString, (char*)aDateTimeString.getStr(), aDateTimeString.getLength());
|
|
pString[aDateTimeString.getLength()] = 0;
|
|
xmlXPathReturnString(ctxt, pString);
|
|
}
|
|
|
|
static sal_Bool parseDateTime(const ::rtl::OUString& aString, DateTime& aDateTime)
|
|
{
|
|
// take apart a canonical literal xsd:dateTime string
|
|
//CCYY-MM-DDThh:mm:ss(Z)
|
|
|
|
::rtl::OUString aDateTimeString = aString.trim();
|
|
|
|
// check length
|
|
if (aDateTimeString.getLength() < 19 || aDateTimeString.getLength() > 20)
|
|
return sal_False;
|
|
|
|
sal_Int32 nDateLength = 10;
|
|
sal_Int32 nTimeLength = 8;
|
|
|
|
::rtl::OUString aDateTimeSep(RTL_CONSTASCII_USTRINGPARAM("T"));
|
|
::rtl::OUString aDateSep(RTL_CONSTASCII_USTRINGPARAM("-"));
|
|
::rtl::OUString aTimeSep(RTL_CONSTASCII_USTRINGPARAM(":"));
|
|
::rtl::OUString aUTCString(RTL_CONSTASCII_USTRINGPARAM("Z"));
|
|
|
|
::rtl::OUString aDateString = aDateTimeString.copy(0, nDateLength);
|
|
::rtl::OUString aTimeString = aDateTimeString.copy(nDateLength+1, nTimeLength);
|
|
|
|
sal_Int32 nIndex = 0;
|
|
sal_Int32 nYear = aDateString.getToken(0, '-', nIndex).toInt32();
|
|
sal_Int32 nMonth = aDateString.getToken(0, '-', nIndex).toInt32();
|
|
sal_Int32 nDay = aDateString.getToken(0, '-', nIndex).toInt32();
|
|
nIndex = 0;
|
|
sal_Int32 nHour = aTimeString.getToken(0, ':', nIndex).toInt32();
|
|
sal_Int32 nMinute = aTimeString.getToken(0, ':', nIndex).toInt32();
|
|
sal_Int32 nSecond = aTimeString.getToken(0, ':', nIndex).toInt32();
|
|
|
|
Date tmpDate((sal_uInt16)nDay, (sal_uInt16)nMonth, (sal_uInt16)nYear);
|
|
Time tmpTime(nHour, nMinute, nSecond);
|
|
DateTime tmpDateTime(tmpDate, tmpTime);
|
|
if (aString.indexOf(aUTCString) < 0)
|
|
tmpDateTime.ConvertToUTC();
|
|
|
|
aDateTime = tmpDateTime;
|
|
|
|
return sal_True;
|
|
}
|
|
|
|
|
|
void xforms_daysFromDateFunction(xmlXPathParserContextPtr ctxt, int nargs)
|
|
{
|
|
// number of days from 1970-01-01 to supplied xsd:date(Time)
|
|
|
|
if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
|
|
xmlChar* pString = xmlXPathPopString(ctxt);
|
|
if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
|
|
::rtl::OUString aString((char*)pString, strlen((char*)pString), RTL_TEXTENCODING_UTF8);
|
|
|
|
DateTime aDateTime;
|
|
if (parseDateTime(aString, aDateTime))
|
|
{
|
|
Date aReferenceDate(1, 1, 1970);
|
|
sal_Int32 nDays = aDateTime - aReferenceDate;
|
|
xmlXPathReturnNumber(ctxt, nDays);
|
|
}
|
|
else
|
|
xmlXPathReturnNumber(ctxt, xmlXPathNAN);
|
|
|
|
|
|
}
|
|
|
|
|
|
void xforms_secondsFromDateTimeFunction(xmlXPathParserContextPtr ctxt, int nargs)
|
|
{
|
|
// number of seconds from 1970-01-01T00:00:00Z to supplied xsd:date(Time)
|
|
|
|
if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
|
|
xmlChar* pString = xmlXPathPopString(ctxt);
|
|
if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
|
|
::rtl::OUString aString((char*)pString, strlen((char*)pString), RTL_TEXTENCODING_UTF8);
|
|
|
|
DateTime aDateTime;
|
|
|
|
if (parseDateTime(aString, aDateTime))
|
|
{
|
|
Date aReferenceDate(1, 1, 1970);
|
|
Time aReferenceTime(0, 0, 0);
|
|
sal_Int32 nDays = aDateTime - aReferenceDate;
|
|
sal_Int32 nSeconds = nDays * 24 * 60 * 60;
|
|
nSeconds += aDateTime.GetHour() * 60 * 60;
|
|
nSeconds += aDateTime.GetMin() * 60;
|
|
nSeconds += aDateTime.GetSec();
|
|
xmlXPathReturnNumber(ctxt, nSeconds);
|
|
}
|
|
else
|
|
xmlXPathReturnNumber(ctxt, xmlXPathNAN);
|
|
|
|
}
|
|
|
|
static sal_Bool parseDuration(const xmlChar* aString, sal_Bool& bNegative, sal_Int32& nYears, sal_Int32& nMonth, sal_Int32& nDays,
|
|
sal_Int32& nHours, sal_Int32& nMinutes, sal_Int32& nSeconds)
|
|
{
|
|
sal_Bool bTime = sal_False; // in part after T
|
|
sal_Int32 nLength = strlen((char*)aString)+1;
|
|
char *pString = (char*)rtl_allocateMemory(nLength);
|
|
char *pString0 = pString;
|
|
strncpy(pString, (char*)aString, nLength);
|
|
|
|
if (pString[0] == '-') {
|
|
bNegative = sal_True;
|
|
pString++;
|
|
}
|
|
|
|
if (pString[0] != 'P')
|
|
return sal_False;
|
|
pString++;
|
|
char* pToken = pString;
|
|
while(pToken[0] != 0)
|
|
{
|
|
switch(pToken[0]) {
|
|
case 'Y':
|
|
pToken[0] = 0;
|
|
nYears = atoi(pString);
|
|
pString = ++pToken;
|
|
break;
|
|
case 'M':
|
|
pToken[0] = 0;
|
|
if (!bTime)
|
|
nMonth = atoi(pString);
|
|
else
|
|
nMinutes = atoi(pString);
|
|
pString = ++pToken;
|
|
break;
|
|
case 'D':
|
|
pToken[0] = 0;
|
|
nDays = atoi(pString);
|
|
pString = ++pToken;
|
|
break;
|
|
case 'H':
|
|
pToken[0] = 0;
|
|
nHours = atoi(pString);
|
|
pString = ++pToken;
|
|
break;
|
|
case 'S':
|
|
pToken[0] = 0;
|
|
nSeconds = atoi(pString);
|
|
pString = ++pToken;
|
|
break;
|
|
case 'T':
|
|
bTime = sal_True;
|
|
pString = ++pToken;
|
|
break;
|
|
default:
|
|
pToken++;
|
|
}
|
|
}
|
|
rtl_freeMemory(pString0);
|
|
return sal_True;
|
|
}
|
|
|
|
void xforms_secondsFuction(xmlXPathParserContextPtr ctxt, int nargs)
|
|
{
|
|
// convert a xsd:duration to seconds
|
|
// (-)PnYnMnDTnHnMnS
|
|
if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
|
|
xmlChar* pString = xmlXPathPopString(ctxt);
|
|
if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
|
|
|
|
sal_Bool bNegative = sal_False;
|
|
sal_Int32 nYears = 0;
|
|
sal_Int32 nMonths = 0;
|
|
sal_Int32 nDays = 0;
|
|
sal_Int32 nHours = 0;
|
|
sal_Int32 nMinutes = 0;
|
|
sal_Int32 nSeconds = 0;
|
|
|
|
if (parseDuration(pString, bNegative, nYears, nMonths, nDays, nHours, nMinutes, nSeconds))
|
|
{
|
|
nSeconds += nMinutes*60;
|
|
nSeconds += nHours*60*60;
|
|
nSeconds += nDays*24*60*60;
|
|
// year and month are ignored according to spec
|
|
if (bNegative)
|
|
nSeconds = 0 - nSeconds;
|
|
xmlXPathReturnNumber(ctxt, nSeconds);
|
|
}
|
|
else
|
|
xmlXPathReturnNumber(ctxt, xmlXPathNAN);
|
|
}
|
|
|
|
void xforms_monthsFuction(xmlXPathParserContextPtr ctxt, int nargs)
|
|
{
|
|
// convert a xsd:duration to seconds
|
|
// (-)PnYnMnDTnHnMnS
|
|
if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
|
|
xmlChar* pString = xmlXPathPopString(ctxt);
|
|
if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
|
|
|
|
sal_Bool bNegative = sal_False;
|
|
sal_Int32 nYears = 0;
|
|
sal_Int32 nMonths = 0;
|
|
sal_Int32 nDays = 0;
|
|
sal_Int32 nHours = 0;
|
|
sal_Int32 nMinutes = 0;
|
|
sal_Int32 nSeconds = 0;
|
|
|
|
if (parseDuration(pString, bNegative, nYears, nMonths, nDays, nHours, nMinutes, nSeconds))
|
|
{
|
|
nMonths += nYears*12;
|
|
// Days, Houres, Minutes and seconds are ignored, see spec
|
|
if (bNegative)
|
|
nMonths = 0 - nMonths;
|
|
xmlXPathReturnNumber(ctxt, nMonths);
|
|
}
|
|
else
|
|
xmlXPathReturnNumber(ctxt, xmlXPathNAN);
|
|
|
|
}
|
|
|
|
// Node-set Functions
|
|
void xforms_instanceFuction(xmlXPathParserContextPtr ctxt, int nargs)
|
|
{
|
|
if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
|
|
xmlChar *pString = xmlXPathPopString(ctxt);
|
|
if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
|
|
::rtl::OUString aString((char*)pString, strlen((char*)pString), RTL_TEXTENCODING_UTF8);
|
|
|
|
Reference< XModel > aModel = ((CLibxml2XFormsExtension*)ctxt->context->funcLookupData)->getModel();
|
|
if (aModel.is())
|
|
{
|
|
Reference< XDocument > aInstance = aModel->getInstanceDocument(aString);
|
|
if (aInstance.is())
|
|
{
|
|
try {
|
|
// xmlXPathObjectPtr xmlXPathNewNodeSet (xmlNodePtr val);
|
|
Reference< XUnoTunnel > aTunnel(aInstance, UNO_QUERY_THROW);
|
|
xmlNodePtr pNode = reinterpret_cast< xmlNodePtr >( aTunnel->getSomething(Sequence< sal_Int8 >()) );
|
|
xmlXPathObjectPtr pObject = xmlXPathNewNodeSet(pNode);
|
|
xmlXPathReturnNodeSet(ctxt, pObject->nodesetval);
|
|
} catch (RuntimeException&)
|
|
{
|
|
xmlXPathReturnEmptyNodeSet(ctxt);
|
|
}
|
|
}
|
|
else
|
|
xmlXPathReturnEmptyNodeSet(ctxt);
|
|
}
|
|
else
|
|
xmlXPathReturnEmptyNodeSet(ctxt);
|
|
|
|
}
|
|
|
|
// Node-set Functions, XForms 1.1
|
|
void xforms_currentFunction(xmlXPathParserContextPtr ctxt, int nargs)
|
|
{
|
|
if (nargs != 0) XP_ERROR(XPATH_INVALID_ARITY);
|
|
|
|
Reference< XNode > aNode = ((CLibxml2XFormsExtension*)ctxt->context->funcLookupData)->getContextNode();
|
|
|
|
if (aNode.is())
|
|
{
|
|
try {
|
|
Reference< XUnoTunnel > aTunnel(aNode, UNO_QUERY_THROW);
|
|
xmlNodePtr pNode = reinterpret_cast< xmlNodePtr >( aTunnel->getSomething(Sequence< sal_Int8 >()) );
|
|
xmlXPathObjectPtr pObject = xmlXPathNewNodeSet(pNode);
|
|
xmlXPathReturnNodeSet(ctxt, pObject->nodesetval);
|
|
}
|
|
catch (RuntimeException&)
|
|
{
|
|
xmlXPathReturnEmptyNodeSet(ctxt);
|
|
}
|
|
}
|
|
else
|
|
xmlXPathReturnEmptyNodeSet(ctxt);
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|