Merge remote-tracking branch 'upstream/master' into experiment/upstream-sync
Change-Id: I77c2bb8abdef222cf0fc2f7016e34da1554653cb
This commit is contained in:
@@ -206,7 +206,6 @@ $(WORKDIR)/download: $(BUILDDIR)/config_$(gb_Side).mk $(SRCDIR)/download.lst $(S
|
||||
$(call fetch_Optional,MORE_FONTS,FONT_ALEF_TARBALL) \
|
||||
$(call fetch_Optional,MORE_FONTS,FONT_AMIRI_TARBALL) \
|
||||
$(call fetch_Optional,MORE_FONTS,FONT_REEM_TARBALL) \
|
||||
$(call fetch_Optional,MORE_FONTS,FONT_SCHEHERAZADE_TARBALL) \
|
||||
$(call fetch_Optional,MESON,MESON_TARBALL) \
|
||||
$(call fetch_Optional,MSPUB,MSPUB_TARBALL) \
|
||||
$(call fetch_Optional,MWAW,MWAW_TARBALL) \
|
||||
|
||||
@@ -1080,7 +1080,6 @@ $(eval $(call gb_Helper_register_packages_for_install,ooo_fonts,\
|
||||
fonts_noto_serif_hebrew \
|
||||
fonts_noto_serif_lao \
|
||||
fonts_reem \
|
||||
fonts_scheherazade \
|
||||
) \
|
||||
))
|
||||
|
||||
|
||||
@@ -1388,7 +1388,7 @@ endif
|
||||
define gb_LinkTarget__use_cairo
|
||||
$(call gb_LinkTarget_use_package,$(1),cairo)
|
||||
$(call gb_LinkTarget_use_package,$(1),pixman)
|
||||
$(call gb_LinkTarget_use_external,$(1),freetype_headers)
|
||||
$(call gb_LinkTarget_use_external,$(1),freetype)
|
||||
$(call gb_LinkTarget_set_include,$(1),\
|
||||
-I$(gb_UnpackedTarball_workdir)/cairo \
|
||||
-I$(gb_UnpackedTarball_workdir)/cairo/src \
|
||||
@@ -4251,7 +4251,7 @@ gb_ExternalExecutable__register_xmllint :=
|
||||
else # ! SYSTEM_LIBXML_FOR_BUILD
|
||||
|
||||
define gb_ExternalExecutable__register_xmllint
|
||||
$(call gb_ExternalExecutable_set_internal,xmllint,$(WORKDIR_FOR_BUILD)/UnpackedTarball/libxml2/$(if $(filter MSC,$(COM)),$(if $(MSVC_USE_DEBUG_RUNTIME),Debug,Release))/xmllint$(gb_Executable_EXT_for_build),libxml2)
|
||||
$(call gb_ExternalExecutable_set_internal,xmllint,$(WORKDIR_FOR_BUILD)/UnpackedTarball/libxml2/xmllint$(gb_Executable_EXT_for_build),libxml2)
|
||||
$(call gb_ExternalExecutable_add_dependencies,xmllint,\
|
||||
$(if $(filter WNT,$(OS)),$(call gb_Package_get_target,icu_ure)) \
|
||||
$(call gb_Package_get_target,libxml2) \
|
||||
|
||||
@@ -74,6 +74,7 @@
|
||||
<!-- OTHER -->
|
||||
<data android:mimeType="text/csv"/>
|
||||
<data android:mimeType="text/comma-separated-values"/>
|
||||
<data android:mimeType="text/markdown"/>
|
||||
<data android:mimeType="application/vnd.ms-works" />
|
||||
<data android:mimeType="application/vnd.apple.keynote" />
|
||||
<data android:mimeType="application/x-abiword" />
|
||||
|
||||
@@ -86,7 +86,7 @@
|
||||
<string name="alert_ok">OK</string>
|
||||
<string name="alert_cancel">Annuleren</string>
|
||||
<string name="current_uno_command">Huidige UNO-opdracht</string>
|
||||
<string name="pdf_export_finished">PDF-export voltooit</string>
|
||||
<string name="pdf_export_finished">PDF-export voltooid</string>
|
||||
<string name="unable_to_export_pdf">Kan niet exporteren naar PDF</string>
|
||||
<string name="unable_to_save">Kan bestand niet opslaan</string>
|
||||
<string name="error">Fout</string>
|
||||
@@ -106,7 +106,7 @@
|
||||
<string name="pref_experimental_editing">Experimentele modus</string>
|
||||
<string name="pref_developer_mode_summary">Schakel de ontwikkelaarsmodus in, waarin u UNO-opdrachten binnen de app kunt verzenden. Gebruik op eigen risico.</string>
|
||||
<string name="action_save_as">Opslaan als…</string>
|
||||
<string name="message_saved">Opslaan voltooit</string>
|
||||
<string name="message_saved">Opslaan voltooid</string>
|
||||
<string name="save_alert_dialog_title">Het document opslaan voordat u het sluit?</string>
|
||||
<string name="calc_optimal_length_default_text">Extra lengte invoeren in 100ste/mm</string>
|
||||
<string name="compress_photo_max_quality">Maximale kwaliteit</string>
|
||||
|
||||
@@ -330,11 +330,16 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Shared
|
||||
|
||||
private boolean copyFileToTemp(Uri documentUri) {
|
||||
// CSV files need a .csv suffix to be opened in Calc.
|
||||
// Markdown files need an .md suffix to be imported as Markdown and not plain text
|
||||
String suffix = null;
|
||||
String intentType = getIntent().getType();
|
||||
if (intentType == null)
|
||||
intentType = getContentResolver().getType(documentUri);
|
||||
// K-9 mail uses the first, GMail uses the second variant.
|
||||
if ("text/comma-separated-values".equals(intentType) || "text/csv".equals(intentType))
|
||||
suffix = ".csv";
|
||||
else if ("text/markdown".equals(intentType))
|
||||
suffix = ".md";
|
||||
|
||||
try {
|
||||
mTempFile = File.createTempFile("LibreOffice", suffix, this.getCacheDir());
|
||||
|
||||
@@ -85,6 +85,7 @@ public class FileUtilities {
|
||||
|
||||
// Other
|
||||
mExtnMap.put(".csv", CALC);
|
||||
mExtnMap.put(".md", DOC);
|
||||
mExtnMap.put(".wps", DOC);
|
||||
mExtnMap.put(".key", IMPRESS);
|
||||
mExtnMap.put(".abw", DOC);
|
||||
|
||||
@@ -111,6 +111,7 @@ public class LibreOfficeUIActivity extends AppCompatActivity implements View.OnC
|
||||
"application/vnd.openxmlformats-officedocument.presentationml.template",
|
||||
"text/csv",
|
||||
"text/comma-separated-values",
|
||||
"text/markdown",
|
||||
"application/vnd.ms-works",
|
||||
"application/vnd.apple.keynote",
|
||||
"application/x-abiword",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[versions]
|
||||
constraintlayout_version = "2.2.1"
|
||||
gradle_version = "9.3.1"
|
||||
gradle_version = "9.4.1"
|
||||
material_version = "1.13.0"
|
||||
preference_version = "1.2.1"
|
||||
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionSha256Sum=a3c4ba4aca8f0075688b9c5b18939fd28e8cb4357c227da5c1d9f38343791439
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.0-all.zip
|
||||
distributionSha256Sum=87a2216cc1f9122192d4e0fe905ffdf1b4c72cff797e9f733b174e157cadd396
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.6.0-all.zip
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
#include "ddectrl.hxx"
|
||||
#include <basic/sberrors.hxx>
|
||||
|
||||
#define DDE_FIRSTERR 0x4000
|
||||
#define DDE_LASTERR 0x4011
|
||||
constexpr tools::Long DDE_FIRSTERR = 0x4000;
|
||||
constexpr tools::Long DDE_LASTERR = 0x4011;
|
||||
|
||||
const ErrCode nDdeErrMap[] =
|
||||
{
|
||||
|
||||
@@ -185,6 +185,8 @@
|
||||
#define STR_INVALID_TIME_UNIT NC_("STR_INVALID_TIME_UNIT", "The major and minor interval need to be greater or equal to the resolution. Check your input.")
|
||||
#define STR_UNSUPPORTED_CHART_TYPE NC_("STR_UNSUPPORTED_CHART_TYPE", "One or more chart types are unsupported in this version of %PRODUCTNAME")
|
||||
|
||||
#define STR_RANGE_FOR_VALUETYPE NC_("STR_RANGE_FOR_VALUETYPE", "Ran~ge for %VALUETYPE")
|
||||
|
||||
#endif
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||
|
||||
@@ -14,6 +14,9 @@
|
||||
#include <com/sun/star/chart2/RelativePosition.hpp>
|
||||
#include <com/sun/star/chart2/XChartDocument.hpp>
|
||||
#include <com/sun/star/chart/XChartDocument.hpp>
|
||||
#include <com/sun/star/chart/XDiagram.hpp>
|
||||
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
|
||||
#include <com/sun/star/chart2/PieChartSubType.hpp>
|
||||
#include <com/sun/star/chart2/XInternalDataProvider.hpp>
|
||||
#include <com/sun/star/chart2/data/XTextualDataSequence.hpp>
|
||||
#include <com/sun/star/chart/XAxisXSupplier.hpp>
|
||||
@@ -2038,6 +2041,66 @@ CPPUNIT_TEST_FIXTURE(Chart2ImportTest2, TestParetoDefaultColor)
|
||||
CPPUNIT_ASSERT_EQUAL(nCorrectColor, nFillColor);
|
||||
}
|
||||
|
||||
CPPUNIT_TEST_FIXTURE(Chart2ImportTest2, testTdf164516BarOfPieDiagram)
|
||||
{
|
||||
loadFromFile(u"ods/chart.ods");
|
||||
|
||||
uno::Reference<lang::XComponent> xChartComp = getChartCompFromSheet(0, 0);
|
||||
uno::Reference<chart::XChartDocument> xChartDoc(xChartComp, uno::UNO_QUERY_THROW);
|
||||
uno::Reference<lang::XMultiServiceFactory> xFactory(xChartDoc, uno::UNO_QUERY_THROW);
|
||||
|
||||
// tdf#164516 - switch the chart type to bar-of-pie using the chart API
|
||||
uno::Reference<chart::XDiagram> xDiagram(
|
||||
xFactory->createInstance(u"com.sun.star.chart.BarOfPieDiagram"_ustr), uno::UNO_QUERY);
|
||||
xChartDoc->setDiagram(xDiagram);
|
||||
|
||||
// Without the fix in place, this test would have failed with
|
||||
// - Expected: com.sun.star.chart.BarOfPieDiagram
|
||||
// - Actual : com.sun.star.chart.BarDiagram
|
||||
// i.e. the service name was unknown and the chart stays a bar chart
|
||||
CPPUNIT_ASSERT_EQUAL(u"com.sun.star.chart.BarOfPieDiagram"_ustr,
|
||||
xChartDoc->getDiagram()->getDiagramType());
|
||||
|
||||
uno::Reference<chart2::XChartDocument> xChart2Doc(xChartComp, uno::UNO_QUERY_THROW);
|
||||
uno::Reference<chart2::XChartType> xChartType = getChartTypeFromDoc(xChart2Doc, 0);
|
||||
CPPUNIT_ASSERT_EQUAL(u"com.sun.star.chart2.PieChartType"_ustr, xChartType->getChartType());
|
||||
|
||||
uno::Reference<beans::XPropertySet> xPropSet(xChartType, uno::UNO_QUERY_THROW);
|
||||
chart2::PieChartSubType eSubType;
|
||||
CPPUNIT_ASSERT(xPropSet->getPropertyValue(u"SubPieType"_ustr) >>= eSubType);
|
||||
CPPUNIT_ASSERT_EQUAL(chart2::PieChartSubType_BAR, eSubType);
|
||||
}
|
||||
|
||||
CPPUNIT_TEST_FIXTURE(Chart2ImportTest2, testTdf164516PieOfPieDiagram)
|
||||
{
|
||||
loadFromFile(u"ods/chart.ods");
|
||||
|
||||
uno::Reference<lang::XComponent> xChartComp = getChartCompFromSheet(0, 0);
|
||||
uno::Reference<chart::XChartDocument> xChartDoc(xChartComp, uno::UNO_QUERY_THROW);
|
||||
uno::Reference<lang::XMultiServiceFactory> xFactory(xChartDoc, uno::UNO_QUERY_THROW);
|
||||
|
||||
// tdf#164516 - switch the chart type to pie-of-pie using the chart API
|
||||
uno::Reference<chart::XDiagram> xDiagram(
|
||||
xFactory->createInstance(u"com.sun.star.chart.PieOfPieDiagram"_ustr), uno::UNO_QUERY);
|
||||
xChartDoc->setDiagram(xDiagram);
|
||||
|
||||
// Without the fix in place, this test would have failed with
|
||||
// - Expected: com.sun.star.chart.PieOfPieDiagram
|
||||
// - Actual : com.sun.star.chart.BarDiagram
|
||||
// i.e. the service name was unknown and the chart stays a bar chart
|
||||
CPPUNIT_ASSERT_EQUAL(u"com.sun.star.chart.PieOfPieDiagram"_ustr,
|
||||
xChartDoc->getDiagram()->getDiagramType());
|
||||
|
||||
uno::Reference<chart2::XChartDocument> xChart2Doc(xChartComp, uno::UNO_QUERY_THROW);
|
||||
uno::Reference<chart2::XChartType> xChartType = getChartTypeFromDoc(xChart2Doc, 0);
|
||||
CPPUNIT_ASSERT_EQUAL(u"com.sun.star.chart2.PieChartType"_ustr, xChartType->getChartType());
|
||||
|
||||
uno::Reference<beans::XPropertySet> xPropSet(xChartType, uno::UNO_QUERY_THROW);
|
||||
chart2::PieChartSubType eSubType;
|
||||
CPPUNIT_ASSERT(xPropSet->getPropertyValue(u"SubPieType"_ustr) >>= eSubType);
|
||||
CPPUNIT_ASSERT_EQUAL(chart2::PieChartSubType_PIE, eSubType);
|
||||
}
|
||||
|
||||
CPPUNIT_PLUGIN_IMPLEMENT();
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||
|
||||
@@ -84,6 +84,8 @@ enum eServiceType
|
||||
SERVICE_NAME_NET_DIAGRAM,
|
||||
SERVICE_NAME_FILLED_NET_DIAGRAM,
|
||||
SERVICE_NAME_PIE_DIAGRAM,
|
||||
SERVICE_NAME_BAR_OF_PIE_DIAGRAM,
|
||||
SERVICE_NAME_PIE_OF_PIE_DIAGRAM,
|
||||
SERVICE_NAME_STOCK_DIAGRAM,
|
||||
SERVICE_NAME_XY_DIAGRAM,
|
||||
SERVICE_NAME_BUBBLE_DIAGRAM,
|
||||
@@ -114,6 +116,8 @@ tServiceNameMap & lcl_getStaticServiceNameMap()
|
||||
{"com.sun.star.chart.NetDiagram", SERVICE_NAME_NET_DIAGRAM},
|
||||
{"com.sun.star.chart.FilledNetDiagram", SERVICE_NAME_FILLED_NET_DIAGRAM},
|
||||
{"com.sun.star.chart.PieDiagram", SERVICE_NAME_PIE_DIAGRAM},
|
||||
{"com.sun.star.chart.BarOfPieDiagram", SERVICE_NAME_BAR_OF_PIE_DIAGRAM},
|
||||
{"com.sun.star.chart.PieOfPieDiagram", SERVICE_NAME_PIE_OF_PIE_DIAGRAM},
|
||||
{"com.sun.star.chart.StockDiagram", SERVICE_NAME_STOCK_DIAGRAM},
|
||||
{"com.sun.star.chart.XYDiagram", SERVICE_NAME_XY_DIAGRAM},
|
||||
{"com.sun.star.chart.BubbleDiagram", SERVICE_NAME_BUBBLE_DIAGRAM},
|
||||
@@ -1207,6 +1211,22 @@ uno::Reference< uno::XInterface > SAL_CALL ChartDocumentWrapper::createInstance(
|
||||
bCreateDiagram = true;
|
||||
}
|
||||
break;
|
||||
case SERVICE_NAME_BAR_OF_PIE_DIAGRAM:
|
||||
if (xChartTypeManager.is())
|
||||
{
|
||||
xTemplate = xChartTypeManager->createTemplate(
|
||||
u"com.sun.star.chart2.template.BarOfPie"_ustr);
|
||||
bCreateDiagram = true;
|
||||
}
|
||||
break;
|
||||
case SERVICE_NAME_PIE_OF_PIE_DIAGRAM:
|
||||
if (xChartTypeManager.is())
|
||||
{
|
||||
xTemplate = xChartTypeManager->createTemplate(
|
||||
u"com.sun.star.chart2.template.PieOfPie"_ustr);
|
||||
bCreateDiagram = true;
|
||||
}
|
||||
break;
|
||||
case SERVICE_NAME_STOCK_DIAGRAM:
|
||||
if( xChartTypeManager.is())
|
||||
{
|
||||
|
||||
@@ -183,7 +183,6 @@ DataSourceTabPage::DataSourceTabPage(weld::Container* pPage, weld::DialogControl
|
||||
m_xLB_ROLE->get_height_rows(5));
|
||||
m_xFT_CAPTION->set_visible(!bHideDescription);
|
||||
|
||||
m_aFixedTextRange = m_xFT_RANGE->get_label();
|
||||
SetPageTitle(SchResId(STR_OBJECT_DATASERIES_PLURAL));
|
||||
|
||||
// set handlers
|
||||
@@ -473,15 +472,9 @@ IMPL_LINK_NOARG(DataSourceTabPage, RoleSelectionChangedHdl, weld::ItemView&, voi
|
||||
OUString aSelectedRoleUI = lcl_GetSelectedRole( *m_xLB_ROLE, true );
|
||||
OUString aSelectedRange = lcl_GetSelectedRolesRange( *m_xLB_ROLE );
|
||||
|
||||
// replace role in fixed text label
|
||||
static constexpr OUString aReplacementStr( u"%VALUETYPE"_ustr );
|
||||
sal_Int32 nIndex = m_aFixedTextRange.indexOf( aReplacementStr );
|
||||
if( nIndex != -1 )
|
||||
{
|
||||
// add the role in fixed text label
|
||||
m_xFT_RANGE->set_label(
|
||||
m_aFixedTextRange.replaceAt(
|
||||
nIndex, aReplacementStr.getLength(), aSelectedRoleUI ));
|
||||
}
|
||||
SchResId(STR_RANGE_FOR_VALUETYPE).replaceFirst(u"%VALUETYPE", aSelectedRoleUI));
|
||||
|
||||
m_xEDT_RANGE->set_text(aSelectedRange);
|
||||
isValid();
|
||||
|
||||
@@ -121,8 +121,6 @@ private:
|
||||
|
||||
std::vector<std::unique_ptr<SeriesEntry>> m_aEntries;
|
||||
|
||||
OUString m_aFixedTextRange;
|
||||
|
||||
ChartTypeTemplateProvider * m_pTemplateProvider;
|
||||
DialogModel & m_rDialogModel;
|
||||
weld::Entry* m_pCurrentRangeChoosingField;
|
||||
|
||||
@@ -13,12 +13,19 @@
|
||||
#include <DataSeries.hxx>
|
||||
#include <DataSeriesHelper.hxx>
|
||||
#include <PropertyHelper.hxx>
|
||||
#include <Axis.hxx>
|
||||
#include <AxisHelper.hxx>
|
||||
#include <AxisIndexDefines.hxx>
|
||||
#include <BaseCoordinateSystem.hxx>
|
||||
#include <com/sun/star/beans/PropertyAttribute.hpp>
|
||||
#include <com/sun/star/drawing/LineStyle.hpp>
|
||||
#include <com/sun/star/chart2/DataPointGeometry3D.hpp>
|
||||
#include <com/sun/star/uno/XComponentContext.hpp>
|
||||
#include <com/sun/star/chart2/AxisType.hpp>
|
||||
#include <comphelper/diagnose_ex.hxx>
|
||||
|
||||
#include <comphelper/property.hxx>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
using namespace ::com::sun::star;
|
||||
@@ -188,6 +195,42 @@ void FunnelChartTypeTemplate::resetStyles2(const rtl::Reference<::chart::Diagram
|
||||
xDiagram->setVertical(false);
|
||||
}
|
||||
|
||||
bool FunnelChartTypeTemplate::isSwapXAndY() const
|
||||
{
|
||||
// Ordinate axis is vertical
|
||||
return true;
|
||||
}
|
||||
|
||||
void FunnelChartTypeTemplate::createCoordinateSystems(
|
||||
const rtl::Reference<::chart::Diagram>& xDiagram)
|
||||
{
|
||||
ChartTypeTemplate::createCoordinateSystems(xDiagram);
|
||||
|
||||
xDiagram->setVertical(isSwapXAndY());
|
||||
}
|
||||
|
||||
void FunnelChartTypeTemplate::adaptAxes(
|
||||
const std::vector<rtl::Reference<BaseCoordinateSystem>>& rCoordSys)
|
||||
{
|
||||
// override to hide the horizontal (value) axis
|
||||
ChartTypeTemplate::adaptAxes(rCoordSys);
|
||||
|
||||
if (rCoordSys.empty())
|
||||
return;
|
||||
|
||||
for (rtl::Reference<BaseCoordinateSystem> const& xCooSys : rCoordSys)
|
||||
{
|
||||
if (!xCooSys.is())
|
||||
continue;
|
||||
|
||||
rtl::Reference<Axis> xAxis = AxisHelper::getAxis(1, 0, xCooSys);
|
||||
if (!xAxis.is())
|
||||
continue;
|
||||
|
||||
xAxis->setPropertyValue(u"Show"_ustr, uno::Any(false));
|
||||
}
|
||||
}
|
||||
|
||||
IMPLEMENT_FORWARD_XINTERFACE2(FunnelChartTypeTemplate, ChartTypeTemplate, OPropertySet)
|
||||
IMPLEMENT_FORWARD_XTYPEPROVIDER2(FunnelChartTypeTemplate, ChartTypeTemplate, OPropertySet)
|
||||
|
||||
|
||||
@@ -45,12 +45,16 @@ protected:
|
||||
::sal_Int32 nChartTypeGroupIndex, ::sal_Int32 nSeriesIndex,
|
||||
::sal_Int32 nSeriesCount) override;
|
||||
virtual void resetStyles2(const rtl::Reference<::chart::Diagram>& xDiagram) override;
|
||||
virtual void createCoordinateSystems(const rtl::Reference<::chart::Diagram>& xDiagram) override;
|
||||
|
||||
// ____ ChartTypeTemplate ____
|
||||
virtual sal_Int32 getDimension() const override;
|
||||
|
||||
virtual rtl::Reference<::chart::ChartType>
|
||||
getChartTypeForIndex(sal_Int32 nChartTypeIndex) override;
|
||||
virtual bool isSwapXAndY() const override;
|
||||
virtual void
|
||||
adaptAxes(const std::vector<rtl::Reference<BaseCoordinateSystem>>& rCoordSys) override;
|
||||
|
||||
private:
|
||||
sal_Int32 m_nDim;
|
||||
|
||||
@@ -38,6 +38,75 @@ typedef std::pair< double, double > tPointType;
|
||||
typedef std::vector< tPointType > tPointVecType;
|
||||
typedef tPointVecType::size_type lcl_tSizeType;
|
||||
|
||||
bool lcl_CalculateUpperTriangularForm(
|
||||
tPointVecType& rPointsIn
|
||||
, std::vector<std::vector<double>>& rMatN
|
||||
, std::vector<lcl_tSizeType>& rShift )
|
||||
{
|
||||
lcl_tSizeType r = 0; // true row index
|
||||
lcl_tSizeType c = 0; // true column index
|
||||
double fDivisor = 1.0; // used for diagonal element
|
||||
double fEliminate = 1.0; // used for the element, that will become zero
|
||||
bool bIsSuccessful = true;
|
||||
const lcl_tSizeType n = rPointsIn.size() - 1;
|
||||
for (c = 0 ; c <= n && bIsSuccessful; ++c)
|
||||
{
|
||||
// search for first non-zero downwards
|
||||
r = c;
|
||||
while ( r < n && rMatN[r][c-rShift[r]] == 0 )
|
||||
{
|
||||
++r;
|
||||
}
|
||||
if (rMatN[r][c-rShift[r]] == 0.0)
|
||||
{
|
||||
// Matrix N is singular, although this is mathematically impossible
|
||||
bIsSuccessful = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// exchange total row r with total row c if necessary
|
||||
if (r != c)
|
||||
{
|
||||
std::swap( rMatN[r], rMatN[c] );
|
||||
std::swap( rPointsIn[r], rPointsIn[c] );
|
||||
std::swap( rShift[r], rShift[c] );
|
||||
}
|
||||
|
||||
sal_uInt32 p = rMatN[c].size() - 1;
|
||||
|
||||
// divide row c, so that element(c,c) becomes 1
|
||||
fDivisor = rMatN[c][c-rShift[c]]; // not zero, see above
|
||||
for (sal_uInt32 i = 0; i <= p; ++i)
|
||||
{
|
||||
rMatN[c][i] /= fDivisor;
|
||||
}
|
||||
rPointsIn[c].first /= fDivisor;
|
||||
rPointsIn[c].second /= fDivisor;
|
||||
|
||||
// eliminate forward, examine row c+1 to n-1 (worst case)
|
||||
// stop if first non-zero element in row has an higher column as c
|
||||
// look at nShift for that, elements in nShift are equal or increasing
|
||||
for ( r = c+1; r < n && rShift[r]<=c ; ++r)
|
||||
{
|
||||
fEliminate = rMatN[r][0];
|
||||
if (fEliminate != 0.0) // else accidentally zero, nothing to do
|
||||
{
|
||||
for (sal_uInt32 i = 1; i <= p; ++i)
|
||||
{
|
||||
rMatN[r][i-1] = rMatN[r][i] - fEliminate * rMatN[c][i];
|
||||
}
|
||||
rMatN[r][p]=0;
|
||||
rPointsIn[r].first -= fEliminate * rPointsIn[c].first;
|
||||
rPointsIn[r].second -= fEliminate * rPointsIn[c].second;
|
||||
++rShift[r];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return bIsSuccessful;
|
||||
}
|
||||
|
||||
class lcl_SplineCalculation
|
||||
{
|
||||
public:
|
||||
@@ -719,63 +788,9 @@ void SplineCalculator::CalculateBSplines(
|
||||
// Get matrix C of control points from the matrix equation aMatN * C = aPointsIn
|
||||
// aPointsIn is overwritten with C.
|
||||
// Gaussian elimination is possible without pivoting, see reference
|
||||
lcl_tSizeType r = 0; // true row index
|
||||
lcl_tSizeType c = 0; // true column index
|
||||
double fDivisor = 1.0; // used for diagonal element
|
||||
double fEliminate = 1.0; // used for the element, that will become zero
|
||||
bool bIsSuccessful = true;
|
||||
for (c = 0 ; c <= n && bIsSuccessful; ++c)
|
||||
{
|
||||
// search for first non-zero downwards
|
||||
r = c;
|
||||
while ( r < n && aMatN[r][c-aShift[r]] == 0 )
|
||||
{
|
||||
++r;
|
||||
}
|
||||
if (aMatN[r][c-aShift[r]] == 0.0)
|
||||
{
|
||||
// Matrix N is singular, although this is mathematically impossible
|
||||
bIsSuccessful = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// exchange total row r with total row c if necessary
|
||||
if (r != c)
|
||||
{
|
||||
std::swap( aMatN[r], aMatN[c] );
|
||||
std::swap( aPointsIn[r], aPointsIn[c] );
|
||||
std::swap( aShift[r], aShift[c] );
|
||||
}
|
||||
|
||||
// divide row c, so that element(c,c) becomes 1
|
||||
fDivisor = aMatN[c][c-aShift[c]]; // not zero, see above
|
||||
for (sal_uInt32 i = 0; i <= p; ++i)
|
||||
{
|
||||
aMatN[c][i] /= fDivisor;
|
||||
}
|
||||
aPointsIn[c].first /= fDivisor;
|
||||
aPointsIn[c].second /= fDivisor;
|
||||
bool bIsSuccessful = lcl_CalculateUpperTriangularForm(aPointsIn, aMatN, aShift);
|
||||
|
||||
// eliminate forward, examine row c+1 to n-1 (worst case)
|
||||
// stop if first non-zero element in row has an higher column as c
|
||||
// look at nShift for that, elements in nShift are equal or increasing
|
||||
for ( r = c+1; r < n && aShift[r]<=c ; ++r)
|
||||
{
|
||||
fEliminate = aMatN[r][0];
|
||||
if (fEliminate != 0.0) // else accidentally zero, nothing to do
|
||||
{
|
||||
for (sal_uInt32 i = 1; i <= p; ++i)
|
||||
{
|
||||
aMatN[r][i-1] = aMatN[r][i] - fEliminate * aMatN[c][i];
|
||||
}
|
||||
aMatN[r][p]=0;
|
||||
aPointsIn[r].first -= fEliminate * aPointsIn[c].first;
|
||||
aPointsIn[r].second -= fEliminate * aPointsIn[c].second;
|
||||
++aShift[r];
|
||||
}
|
||||
}
|
||||
}
|
||||
}// upper triangle form is reached
|
||||
if( bIsSuccessful)
|
||||
{
|
||||
// eliminate backwards, begin with last column
|
||||
@@ -785,10 +800,11 @@ void SplineCalculator::CalculateBSplines(
|
||||
// diagonal are zero and do not influence other rows.
|
||||
// Full matrix N has semibandwidth < p, therefore element(r,c) is
|
||||
// zero, if abs(r-cc)>=p. abs(r-cc)=cc-r, because r<cc.
|
||||
r = cc - 1;
|
||||
|
||||
lcl_tSizeType r = cc - 1; // true row index
|
||||
while ( r !=0 && cc-r < p )
|
||||
{
|
||||
fEliminate = aMatN[r][ cc - aShift[r] ];
|
||||
double fEliminate = aMatN[r][ cc - aShift[r] ]; // used for the element, that will become zero
|
||||
if ( fEliminate != 0.0) // else element is accidentally zero, no action needed
|
||||
{
|
||||
// row r -= fEliminate * row cc only relevant for right side
|
||||
|
||||
@@ -309,7 +309,7 @@
|
||||
<object class="GtkLabel" id="FT_RANGE">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes" context="tp_DataSource|FT_RANGE">Ran_ge for %VALUETYPE</property>
|
||||
<property name="label" translatable="yes" context="tp_DataSource|FT_RANGE">Ran_ge</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="mnemonic-widget">EDT_RANGE</property>
|
||||
<property name="xalign">0</property>
|
||||
|
||||
@@ -117,6 +117,7 @@ $(eval $(call gb_Library_add_exception_objects,comphelper,\
|
||||
comphelper/source/misc/hash \
|
||||
comphelper/source/misc/instancelocker \
|
||||
comphelper/source/misc/interaction \
|
||||
comphelper/source/misc/invocationhelper \
|
||||
comphelper/source/misc/logging \
|
||||
comphelper/source/misc/lok \
|
||||
comphelper/source/misc/mimeconfighelper \
|
||||
|
||||
@@ -0,0 +1,243 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
|
||||
/*
|
||||
* This file is part of the LibreOffice project.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include <sal/config.h>
|
||||
|
||||
#include <comphelper/invocationhelper.hxx>
|
||||
|
||||
#include <com/sun/star/beans/MethodConcept.hpp>
|
||||
#include <com/sun/star/beans/PropertyConcept.hpp>
|
||||
#include <com/sun/star/beans/theIntrospection.hpp>
|
||||
#include <com/sun/star/beans/XIntrospectionAccess.hpp>
|
||||
#include <com/sun/star/beans/XPropertySet.hpp>
|
||||
#include <com/sun/star/container/NoSuchElementException.hpp>
|
||||
#include <com/sun/star/lang/NoSuchMethodException.hpp>
|
||||
#include <com/sun/star/script/CannotConvertException.hpp>
|
||||
#include <com/sun/star/script/Converter.hpp>
|
||||
#include <com/sun/star/script/XInvocation.hpp>
|
||||
|
||||
namespace comphelper
|
||||
{
|
||||
constexpr sal_Int32 ALLOWED_METHODS
|
||||
= css::beans::MethodConcept::ALL ^ css::beans::MethodConcept::DANGEROUS;
|
||||
constexpr sal_Int32 ALLOWED_PROPERTIES
|
||||
= css::beans::PropertyConcept::ALL ^ css::beans::PropertyConcept::DANGEROUS;
|
||||
|
||||
InvocationHelper::InvocationHelper(const css::uno::Reference<css::uno::XComponentContext>& xContext)
|
||||
: m_xContext(xContext)
|
||||
{
|
||||
}
|
||||
|
||||
css::uno::Reference<css::beans::XIntrospectionAccess>
|
||||
InvocationHelper::getIntrospection(css::script::XInvocation* pInvocation)
|
||||
{
|
||||
ensureIntrospection(pInvocation);
|
||||
|
||||
return m_xIntrospectionAccess;
|
||||
}
|
||||
|
||||
css::uno::Sequence<css::uno::Any> InvocationHelper::prepareInvokeParams(
|
||||
const css::uno::Sequence<css::uno::Any>& aParams,
|
||||
const css::uno::Sequence<css::reflection::ParamInfo>& aParamInfos)
|
||||
{
|
||||
css::uno::Sequence<css::uno::Any> aInvokeParams(aParamInfos.getLength());
|
||||
css::uno::Any* pInvokeParams = aInvokeParams.getArray();
|
||||
|
||||
for (sal_Int32 nParam = 0, nParams = aParamInfos.getLength(); nParam < nParams; ++nParam)
|
||||
{
|
||||
const css::reflection::ParamInfo& rParam = aParamInfos[nParam];
|
||||
|
||||
if (rParam.aMode == css::reflection::ParamMode_OUT)
|
||||
{
|
||||
// Initialize default value if the parameter is OUT
|
||||
rParam.aType->createObject(pInvokeParams[nParam]);
|
||||
}
|
||||
else
|
||||
{
|
||||
css::uno::Type aDestType(rParam.aType->getTypeClass(), rParam.aType->getName());
|
||||
|
||||
try
|
||||
{
|
||||
pInvokeParams[nParam] = m_xTypeConverter->convertTo(aParams[nParam], aDestType);
|
||||
}
|
||||
catch (css::script::CannotConvertException& e)
|
||||
{
|
||||
// Add optional parameter index
|
||||
e.ArgumentIndex = nParam;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return aInvokeParams;
|
||||
}
|
||||
|
||||
css::uno::Any InvocationHelper::invoke(css::script::XInvocation* pInvocation,
|
||||
const OUString& aFunctionName,
|
||||
const css::uno::Sequence<css::uno::Any>& aParams,
|
||||
css::uno::Sequence<sal_Int16>& aOutParamIndex,
|
||||
css::uno::Sequence<css::uno::Any>& aOutParam)
|
||||
{
|
||||
// This implementation is heavily inspired by Invocation_Impl::invoke
|
||||
|
||||
ensureIntrospection(pInvocation);
|
||||
|
||||
css::uno::Reference<css::reflection::XIdlMethod> xMethod;
|
||||
|
||||
try
|
||||
{
|
||||
xMethod = m_xIntrospectionAccess->getMethod(aFunctionName, ALLOWED_METHODS);
|
||||
}
|
||||
catch (css::lang::NoSuchMethodException&)
|
||||
{
|
||||
throw css::lang::IllegalArgumentException(u"no such method"_ustr, pInvocation, 0);
|
||||
}
|
||||
|
||||
css::uno::Sequence<css::reflection::ParamInfo> aParamInfos = xMethod->getParameterInfos();
|
||||
|
||||
if (aParams.getLength() != aParamInfos.getLength())
|
||||
{
|
||||
throw css::lang::IllegalArgumentException(
|
||||
"incorrect number of parameters passed invoking function " + aFunctionName
|
||||
+ ": expected " + OUString::number(aParamInfos.getLength()) + ", got "
|
||||
+ OUString::number(aParams.getLength()),
|
||||
pInvocation, 1);
|
||||
}
|
||||
|
||||
ensureTypeConverter();
|
||||
|
||||
css::uno::Sequence<css::uno::Any> aInvokeParams = prepareInvokeParams(aParams, aParamInfos);
|
||||
|
||||
css::uno::Reference<css::script::XInvocation> xInvocation(pInvocation);
|
||||
css::uno::Any aRet = xMethod->invoke(css::uno::Any(xInvocation), aInvokeParams);
|
||||
|
||||
size_t nOutParams = std::count_if(
|
||||
std::cbegin(aParamInfos), std::cend(aParamInfos),
|
||||
[](const auto& rParamInfo) { return rParamInfo.aMode != css::reflection::ParamMode_IN; });
|
||||
aOutParamIndex.realloc(nOutParams);
|
||||
aOutParam.realloc(nOutParams);
|
||||
|
||||
sal_Int16* pOutParamIndex = aOutParamIndex.getArray();
|
||||
css::uno::Any* pOutParam = aOutParam.getArray();
|
||||
|
||||
for (sal_Int32 nParam = 0, nOutParam = 0, nParams = aParamInfos.getLength(); nParam < nParams;
|
||||
++nParam)
|
||||
{
|
||||
if (aParamInfos[nParam].aMode == css::reflection::ParamMode_IN)
|
||||
continue;
|
||||
|
||||
pOutParamIndex[nOutParam] = nParam;
|
||||
pOutParam[nOutParam] = aInvokeParams[nParam];
|
||||
nOutParam++;
|
||||
}
|
||||
|
||||
return aRet;
|
||||
}
|
||||
|
||||
void InvocationHelper::setValue(css::script::XInvocation* pInvocation,
|
||||
const OUString& aPropertyName, const css::uno::Any& aValue)
|
||||
{
|
||||
ensureIntrospection(pInvocation);
|
||||
|
||||
css::uno::Reference<css::beans::XPropertySet> xPropertySet(m_xIntrospectionAccess,
|
||||
css::uno::UNO_QUERY);
|
||||
|
||||
if (!xPropertySet.is())
|
||||
throw css::beans::UnknownPropertyException(aPropertyName);
|
||||
|
||||
css::beans::Property aProp;
|
||||
|
||||
try
|
||||
{
|
||||
aProp = m_xIntrospectionAccess->getProperty(aPropertyName, ALLOWED_PROPERTIES);
|
||||
}
|
||||
catch (css::container::NoSuchElementException&)
|
||||
{
|
||||
throw css::beans::UnknownPropertyException(aPropertyName);
|
||||
}
|
||||
|
||||
ensureTypeConverter();
|
||||
|
||||
css::uno::Any aConvertedValue = m_xTypeConverter->convertTo(aValue, aProp.Type);
|
||||
|
||||
try
|
||||
{
|
||||
return xPropertySet->setPropertyValue(aPropertyName, aConvertedValue);
|
||||
}
|
||||
catch (css::lang::WrappedTargetException& e)
|
||||
{
|
||||
throw css::reflection::InvocationTargetException(e.Message, pInvocation, e.TargetException);
|
||||
}
|
||||
catch (css::beans::PropertyVetoException& e)
|
||||
{
|
||||
throw css::reflection::InvocationTargetException(e.Message, pInvocation, css::uno::Any(e));
|
||||
}
|
||||
}
|
||||
|
||||
css::uno::Any InvocationHelper::getValue(css::script::XInvocation* pInvocation,
|
||||
const OUString& aPropertyName)
|
||||
{
|
||||
// Make sure the introspection access implements XPropertySet and that the property is one of
|
||||
// the ones allowed by hasProperty.
|
||||
|
||||
if (!hasProperty(pInvocation, aPropertyName))
|
||||
throw css::beans::UnknownPropertyException(aPropertyName);
|
||||
|
||||
css::uno::Reference<css::beans::XPropertySet> xPropertySet(m_xIntrospectionAccess,
|
||||
css::uno::UNO_QUERY_THROW);
|
||||
|
||||
try
|
||||
{
|
||||
return xPropertySet->getPropertyValue(aPropertyName);
|
||||
}
|
||||
catch (css::lang::WrappedTargetException& e)
|
||||
{
|
||||
throw css::reflection::InvocationTargetException(e.Message, pInvocation, e.TargetException);
|
||||
}
|
||||
}
|
||||
|
||||
sal_Bool InvocationHelper::hasMethod(css::script::XInvocation* pInvocation, const OUString& aName)
|
||||
{
|
||||
ensureIntrospection(pInvocation);
|
||||
|
||||
return m_xIntrospectionAccess->hasMethod(aName, ALLOWED_METHODS);
|
||||
}
|
||||
|
||||
sal_Bool InvocationHelper::hasProperty(css::script::XInvocation* pInvocation, const OUString& aName)
|
||||
{
|
||||
ensureIntrospection(pInvocation);
|
||||
|
||||
css::uno::Reference<css::beans::XPropertySet> xPropertySet(m_xIntrospectionAccess,
|
||||
css::uno::UNO_QUERY);
|
||||
|
||||
return xPropertySet.is() && m_xIntrospectionAccess->hasProperty(aName, ALLOWED_PROPERTIES);
|
||||
}
|
||||
|
||||
void InvocationHelper::ensureTypeConverter()
|
||||
{
|
||||
if (m_xTypeConverter.is())
|
||||
return;
|
||||
|
||||
m_xTypeConverter = css::script::Converter::create(m_xContext);
|
||||
}
|
||||
|
||||
void InvocationHelper::ensureIntrospection(css::script::XInvocation* pInvocation)
|
||||
{
|
||||
if (m_xIntrospectionAccess.is())
|
||||
return;
|
||||
|
||||
css::uno::Reference<css::beans::XIntrospection> xIntrospection
|
||||
= css::beans::theIntrospection::get(m_xContext);
|
||||
|
||||
css::uno::Reference<css::script::XInvocation> xInvocation(pInvocation);
|
||||
m_xIntrospectionAccess = xIntrospection->inspect(css::uno::Any(xInvocation));
|
||||
}
|
||||
}
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
|
||||
@@ -115,6 +115,26 @@ public:
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool TraverseCXXFunctionalCastExpr(CXXFunctionalCastExpr* expr)
|
||||
{
|
||||
// The C++ definition of assert in glibc 2.44 checks that its argument is a single
|
||||
// expression with `1 ? 1 : bool (__VA_ARGS__)`, which re-evaluates the whole argument in a
|
||||
// branch that is never taken; do not descend into that dead branch to avoid duplicate
|
||||
// warnings:
|
||||
if (expr->getType()->isBooleanType())
|
||||
{
|
||||
auto const loc = expr->getBeginLoc();
|
||||
if (compiler.getSourceManager().isMacroBodyExpansion(loc)
|
||||
&& Lexer::getImmediateMacroName(loc, compiler.getSourceManager(),
|
||||
compiler.getLangOpts())
|
||||
== "assert")
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return FilteringPlugin::TraverseCXXFunctionalCastExpr(expr);
|
||||
}
|
||||
|
||||
bool VisitImplicitCastExpr(ImplicitCastExpr const* expr)
|
||||
{
|
||||
if (ignoreLocation(expr))
|
||||
|
||||
@@ -241,15 +241,7 @@ public:
|
||||
FilteringPlugin(data) {}
|
||||
|
||||
virtual void run() override
|
||||
{
|
||||
std::string fn(handler.getMainFileName());
|
||||
loplugin::normalizeDotDotInFilePath(fn);
|
||||
if (loplugin::hasPathnamePrefix(fn, SRCDIR "/soltools/cpp")
|
||||
|| loplugin::hasPathnamePrefix(fn, SRCDIR "/soltools/mkdepend"))
|
||||
return;
|
||||
|
||||
TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
|
||||
}
|
||||
{ TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); }
|
||||
|
||||
bool TraverseCallExpr(CallExpr * expr);
|
||||
|
||||
@@ -488,6 +480,18 @@ bool ImplicitBoolConversion::TraverseCXXStaticCastExpr(CXXStaticCastExpr * expr)
|
||||
bool ImplicitBoolConversion::TraverseCXXFunctionalCastExpr(
|
||||
CXXFunctionalCastExpr * expr)
|
||||
{
|
||||
// The C++ definition of assert in glibc 2.44 checks that its argument is a single expression
|
||||
// with `1 ? 1 : bool (__VA_ARGS__)`, which re-evaluates the whole argument in a branch that is
|
||||
// never taken; do not descend into that dead branch to avoid duplicate warnings:
|
||||
if (expr->getType()->isBooleanType()) {
|
||||
auto const loc = expr->getBeginLoc();
|
||||
if (compiler.getSourceManager().isMacroBodyExpansion(loc)
|
||||
&& Lexer::getImmediateMacroName(
|
||||
loc, compiler.getSourceManager(), compiler.getLangOpts()) == "assert")
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
nested.push(std::vector<ImplicitCastExpr const *>());
|
||||
bool bRet = RecursiveASTVisitor::TraverseCXXFunctionalCastExpr(expr);
|
||||
assert(!nested.empty());
|
||||
@@ -721,6 +725,15 @@ bool ImplicitBoolConversion::VisitImplicitCastExpr(
|
||||
}
|
||||
}
|
||||
}
|
||||
// Ignore the conversion from bool to int in the `1 ? 1 : bool (__VA_ARGS__)` argument check
|
||||
// of the C++ definition of assert in glibc 2.44:
|
||||
auto const loc = expr->getBeginLoc();
|
||||
if (compiler.getSourceManager().isMacroBodyExpansion(loc)
|
||||
&& Lexer::getImmediateMacroName(
|
||||
loc, compiler.getSourceManager(), compiler.getLangOpts()) == "assert")
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (nested.empty()) {
|
||||
reportWarning(expr);
|
||||
} else {
|
||||
@@ -757,6 +770,13 @@ bool ImplicitBoolConversion::VisitImplicitCastExpr(
|
||||
&& !calls.empty())
|
||||
{
|
||||
CallExpr const * call = calls.top();
|
||||
// Ignore the conversion from pointer in the `extern _Bool __assert_single_arg (_Bool)`
|
||||
// check in the C definition of assert in glibc 2.44:
|
||||
if (auto const fd = call->getDirectCallee()) {
|
||||
if (fd->getIdentifier() && fd->getName() == "__assert_single_arg") {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (std::any_of(
|
||||
call->arg_begin(), call->arg_end(),
|
||||
[expr](Expr const * e) { return expr == e->IgnoreParens(); }))
|
||||
|
||||
@@ -45,6 +45,9 @@ public:
|
||||
bool PreTraverseFunctionDecl(FunctionDecl* decl);
|
||||
bool PostTraverseFunctionDecl(FunctionDecl* decl, bool);
|
||||
bool TraverseFunctionDecl(FunctionDecl* decl);
|
||||
bool PreTraverseCXXFunctionalCastExpr(CXXFunctionalCastExpr* expr);
|
||||
bool PostTraverseCXXFunctionalCastExpr(CXXFunctionalCastExpr* expr, bool);
|
||||
bool TraverseCXXFunctionalCastExpr(CXXFunctionalCastExpr* expr);
|
||||
bool VisitCallExpr(CallExpr const*);
|
||||
|
||||
private:
|
||||
@@ -76,14 +79,36 @@ bool PointerBool::TraverseFunctionDecl(FunctionDecl* decl)
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool PointerBool::PreTraverseCXXFunctionalCastExpr(CXXFunctionalCastExpr* expr)
|
||||
{
|
||||
// The C++ definition of assert in glibc 2.44 checks that its argument is a single expression
|
||||
// with `1 ? 1 : bool (__VA_ARGS__)`, which re-evaluates the whole argument in a branch that is
|
||||
// never taken; do not descend into that dead branch to avoid duplicate warnings:
|
||||
if (!expr->getType()->isBooleanType())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
auto const loc = expr->getBeginLoc();
|
||||
return !compiler.getSourceManager().isMacroBodyExpansion(loc)
|
||||
|| Lexer::getImmediateMacroName(loc, compiler.getSourceManager(), compiler.getLangOpts())
|
||||
!= "assert";
|
||||
}
|
||||
|
||||
bool PointerBool::PostTraverseCXXFunctionalCastExpr(CXXFunctionalCastExpr*, bool) { return true; }
|
||||
|
||||
bool PointerBool::TraverseCXXFunctionalCastExpr(CXXFunctionalCastExpr* expr)
|
||||
{
|
||||
bool ret = true;
|
||||
if (PreTraverseCXXFunctionalCastExpr(expr))
|
||||
{
|
||||
ret = FilteringPlugin::TraverseCXXFunctionalCastExpr(expr);
|
||||
PostTraverseCXXFunctionalCastExpr(expr, ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool PointerBool::VisitCallExpr(CallExpr const* callExpr)
|
||||
{
|
||||
std::string fn(handler.getMainFileName());
|
||||
loplugin::normalizeDotDotInFilePath(fn);
|
||||
if (loplugin::hasPathnamePrefix(fn, SRCDIR "/soltools/cpp")
|
||||
|| loplugin::hasPathnamePrefix(fn, SRCDIR "/soltools/mkdepend"))
|
||||
return true;
|
||||
|
||||
if (ignoreLocation(callExpr))
|
||||
return true;
|
||||
// TODO this doesn't currently work, the args and the params don't seem to line up
|
||||
@@ -100,6 +125,11 @@ bool PointerBool::VisitCallExpr(CallExpr const* callExpr)
|
||||
}
|
||||
if (!functionDecl)
|
||||
return true;
|
||||
// glibc 2.44 checks that the argument to assert is a single expression by passing it to
|
||||
// "extern _Bool __assert_single_arg (_Bool)" inside a sizeof. A pointer argument to that
|
||||
// internal check is not a mistake in the calling code:
|
||||
if (functionDecl->getIdentifier() && functionDecl->getName() == "__assert_single_arg")
|
||||
return true;
|
||||
|
||||
unsigned len = std::min(callExpr->getNumArgs(), functionDecl->getNumParams());
|
||||
for (unsigned i = 0; i < len; ++i)
|
||||
|
||||
@@ -132,6 +132,23 @@ public:
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool TraverseCXXFunctionalCastExpr(CXXFunctionalCastExpr * expr) {
|
||||
// The C++ definition of assert in glibc 2.44 checks that its argument is a single
|
||||
// expression with `1 ? 1 : bool (__VA_ARGS__)`, which re-evaluates the whole argument in a
|
||||
// branch that is never taken; do not descend into that dead branch to avoid duplicate
|
||||
// warnings:
|
||||
if (expr->getType()->isBooleanType()) {
|
||||
auto const loc = expr->getBeginLoc();
|
||||
if (compiler.getSourceManager().isMacroBodyExpansion(loc)
|
||||
&& Lexer::getImmediateMacroName(
|
||||
loc, compiler.getSourceManager(), compiler.getLangOpts()) == "assert")
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return FilteringRewritePlugin::TraverseCXXFunctionalCastExpr(expr);
|
||||
}
|
||||
|
||||
bool VisitImplicitCastExpr(ImplicitCastExpr const * expr);
|
||||
|
||||
bool VisitCXXStaticCastExpr(CXXStaticCastExpr const * expr);
|
||||
|
||||
@@ -64,6 +64,8 @@ int main()
|
||||
}
|
||||
// expected-error@+1 {{implicit conversion of constant &"msg"[0] of type 'const char *' to 'bool'; use 'true' instead [loplugin:consttobool]}}
|
||||
assert("msg");
|
||||
// expected-error@+1 {{implicit conversion of constant 2 of type 'int' to 'bool'; use 'true' instead [loplugin:consttobool]}}
|
||||
assert(2);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#include <array>
|
||||
#include <atomic>
|
||||
#include <cassert>
|
||||
#include <initializer_list>
|
||||
|
||||
#include <com/sun/star/uno/Sequence.hxx>
|
||||
@@ -80,4 +81,13 @@ void f()
|
||||
s8[0] = false;
|
||||
}
|
||||
|
||||
void testAssert([[maybe_unused]] bool b, [[maybe_unused]] int n)
|
||||
{
|
||||
assert(b);
|
||||
#if !defined NDEBUG
|
||||
// expected-error@+1 {{implicit conversion (IntegralCast) from 'bool' to 'int' [loplugin:implicitboolconversion]}}
|
||||
assert(n = b);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
|
||||
|
||||
@@ -7,6 +7,10 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include <sal/config.h>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include <sal/types.h>
|
||||
#include <com/sun/star/uno/Sequence.hxx>
|
||||
|
||||
@@ -43,4 +47,16 @@ void test2(int p1)
|
||||
func_bool_via_forward_template(p1);
|
||||
}
|
||||
|
||||
// expected-note@+1 {{method here [loplugin:pointerbool]}}
|
||||
bool func_boolA(bool);
|
||||
|
||||
void testAssert([[maybe_unused]] int* p)
|
||||
{
|
||||
assert(p);
|
||||
#if !defined NDEBUG
|
||||
// expected-error@+1 {{possibly unwanted implicit conversion when calling bool param [loplugin:pointerbool]}}
|
||||
assert(func_boolA(p));
|
||||
#endif
|
||||
}
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include <sal/config.h>
|
||||
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
|
||||
#include <sal/types.h>
|
||||
@@ -485,6 +486,14 @@ void testFunctionalCast2() {
|
||||
S1 aTest2(S1_COL);
|
||||
}
|
||||
|
||||
void testAssert([[maybe_unused]] int n) {
|
||||
assert(n > 0);
|
||||
#if !defined NDEBUG
|
||||
// expected-error@+1 {{redundant functional cast from 'bool' to 'bool' [loplugin:redundantcast]}}
|
||||
assert(bool(n > 0));
|
||||
#endif
|
||||
}
|
||||
|
||||
int main() {
|
||||
testConstCast();
|
||||
testStaticCast();
|
||||
|
||||
@@ -38,8 +38,8 @@
|
||||
#define WITH_LOCALE_hu 0
|
||||
#define WITH_LOCALE_is 0
|
||||
#define WITH_LOCALE_ja 0
|
||||
#define WITH_LOCALE_kmr_Latn 0
|
||||
#define WITH_LOCALE_ko 0
|
||||
#define WITH_LOCALE_ku 0
|
||||
#define WITH_LOCALE_ln 0
|
||||
#define WITH_LOCALE_my 0
|
||||
#define WITH_LOCALE_ne 0
|
||||
|
||||
+8
-5
@@ -1108,8 +1108,6 @@ cygwin*|wsl*)
|
||||
|
||||
DLLPOST=".dll"
|
||||
LINKFLAGSNOUNDEFS=
|
||||
# bypass check for ninja, it is not in default path, but it can be used nevertheless by default
|
||||
NINJA="assumed to be available from Visual Studio"
|
||||
|
||||
if test "$host_cpu" = "aarch64"; then
|
||||
build_skia=yes
|
||||
@@ -1498,6 +1496,7 @@ if test "$_os" != "WINNT"; then
|
||||
# Clang 12.0.1 occasionally SEGVs on some of the test invocations during AC_PROG_CC with -O2):
|
||||
save_CFLAGS=$CFLAGS
|
||||
CFLAGS=-g
|
||||
ac_cv_prog_cc_c23=no
|
||||
AC_PROG_CC
|
||||
CFLAGS=$save_CFLAGS
|
||||
if test -z "$CC_BASE"; then
|
||||
@@ -4758,6 +4757,10 @@ if test "$_os" = "WINNT"; then
|
||||
PathFormat "$VC_PRODUCT_DIR/../Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/bin/cmake.exe"
|
||||
CMAKE="$formatted_path"
|
||||
|
||||
# Find the ninja that ships with Visual Studio, beside that cmake.
|
||||
PathFormat "$VC_PRODUCT_DIR/../Common7/IDE/CommonExtensions/Microsoft/CMake/Ninja/ninja.exe"
|
||||
NINJA="$formatted_path"
|
||||
|
||||
# Find the version of devenv.exe
|
||||
PathFormat "$VC_PRODUCT_DIR/../Common7/IDE/devenv.exe"
|
||||
DEVENV="$formatted_path"
|
||||
@@ -10641,9 +10644,9 @@ else
|
||||
fi
|
||||
if test "$COM" = "MSC"; then
|
||||
if test "$MSVC_USE_DEBUG_RUNTIME" = TRUE; then
|
||||
LIBXML_LIBS="${WORKDIR}/UnpackedTarball/libxml2/Debug/libxml2d.lib"
|
||||
LIBXML_LIBS="${WORKDIR}/UnpackedTarball/libxml2/libxml2d.lib"
|
||||
else
|
||||
LIBXML_LIBS="${WORKDIR}/UnpackedTarball/libxml2/Release/libxml2.lib"
|
||||
LIBXML_LIBS="${WORKDIR}/UnpackedTarball/libxml2/libxml2.lib"
|
||||
fi
|
||||
else
|
||||
LIBXML_LIBS="-L${WORKDIR}/UnpackedTarball/libxml2/.libs -lxml2"
|
||||
@@ -15020,7 +15023,7 @@ if test "$need_meson" = "yes"; then
|
||||
fi
|
||||
fi
|
||||
|
||||
if test -z "$NINJA" || test "$NINJA" = 'assumed to be available from Visual Studio'; then
|
||||
if test -z "$NINJA"; then
|
||||
x_NINJA=[\#]
|
||||
else
|
||||
x_NINJA=
|
||||
|
||||
@@ -52,6 +52,19 @@ public:
|
||||
void test_toDateTime_date_only();
|
||||
void test_toDateTime_with_nanoseconds();
|
||||
|
||||
// toTimeString / toDateTimeString tests
|
||||
void test_toTimeString_no_fraction_when_zero_nanoseconds();
|
||||
void test_toTimeString_keeps_full_precision();
|
||||
void test_toDateTimeString_no_fraction_when_zero_nanoseconds();
|
||||
|
||||
// fractional-seconds rounding for SQL literal generation
|
||||
void test_roundTimeFraction_rounds_to_4_digits();
|
||||
void test_roundTimeFraction_carries_into_seconds();
|
||||
void test_roundTimeFraction_wraps_at_midnight();
|
||||
void test_roundDateTimeFraction_carries_into_next_day();
|
||||
void test_roundDateTimeFraction_rolls_over_month_end();
|
||||
void test_roundTimeFraction_noop_when_no_cap_requested();
|
||||
|
||||
CPPUNIT_TEST_SUITE(DBTypeConversionTest);
|
||||
|
||||
CPPUNIT_TEST(test_toDate_basic);
|
||||
@@ -66,6 +79,17 @@ public:
|
||||
CPPUNIT_TEST(test_toDateTime_date_only);
|
||||
CPPUNIT_TEST(test_toDateTime_with_nanoseconds);
|
||||
|
||||
CPPUNIT_TEST(test_toTimeString_no_fraction_when_zero_nanoseconds);
|
||||
CPPUNIT_TEST(test_toTimeString_keeps_full_precision);
|
||||
CPPUNIT_TEST(test_toDateTimeString_no_fraction_when_zero_nanoseconds);
|
||||
|
||||
CPPUNIT_TEST(test_roundTimeFraction_rounds_to_4_digits);
|
||||
CPPUNIT_TEST(test_roundTimeFraction_carries_into_seconds);
|
||||
CPPUNIT_TEST(test_roundTimeFraction_wraps_at_midnight);
|
||||
CPPUNIT_TEST(test_roundDateTimeFraction_carries_into_next_day);
|
||||
CPPUNIT_TEST(test_roundDateTimeFraction_rolls_over_month_end);
|
||||
CPPUNIT_TEST(test_roundTimeFraction_noop_when_no_cap_requested);
|
||||
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
};
|
||||
|
||||
@@ -166,6 +190,118 @@ void DBTypeConversionTest::test_toDateTime_with_nanoseconds()
|
||||
CPPUNIT_ASSERT_EQUAL_MESSAGE("NanoSeconds", sal_uInt32(500000000), aDT.NanoSeconds);
|
||||
}
|
||||
|
||||
// ----- toTimeString / toDateTimeString ---------------------------------------
|
||||
|
||||
void DBTypeConversionTest::test_toTimeString_no_fraction_when_zero_nanoseconds()
|
||||
{
|
||||
// tdf#153057 (reopened): TIME values must not get trailing ".000000000"
|
||||
css::util::Time aTime;
|
||||
aTime.Hours = 0;
|
||||
aTime.Minutes = 3;
|
||||
aTime.Seconds = 0;
|
||||
aTime.NanoSeconds = 0;
|
||||
CPPUNIT_ASSERT_EQUAL(u"00:03:00"_ustr, DBTypeConversion::toTimeString(aTime));
|
||||
}
|
||||
|
||||
void DBTypeConversionTest::test_toTimeString_keeps_full_precision()
|
||||
{
|
||||
css::util::Time aTime;
|
||||
aTime.Hours = 0;
|
||||
aTime.Minutes = 3;
|
||||
aTime.Seconds = 0;
|
||||
aTime.NanoSeconds = 123456789;
|
||||
CPPUNIT_ASSERT_EQUAL(u"00:03:00.123456789"_ustr, DBTypeConversion::toTimeString(aTime));
|
||||
}
|
||||
|
||||
void DBTypeConversionTest::test_roundTimeFraction_rounds_to_4_digits()
|
||||
{
|
||||
// this is the rounding the Firebird is using
|
||||
css::util::Time aTime;
|
||||
aTime.Hours = 0;
|
||||
aTime.Minutes = 3;
|
||||
aTime.Seconds = 0;
|
||||
aTime.NanoSeconds = 123456789;
|
||||
CPPUNIT_ASSERT(!DBTypeConversion::roundTimeFraction(aTime, 4));
|
||||
// 123456789ns rounds to the nearest 1/10000s (123500000ns = .1235).
|
||||
CPPUNIT_ASSERT_EQUAL(sal_uInt32(123500000), aTime.NanoSeconds);
|
||||
// toTimeString() trims trailing zeros
|
||||
CPPUNIT_ASSERT_EQUAL(u"00:03:00.1235"_ustr, DBTypeConversion::toTimeString(aTime));
|
||||
}
|
||||
|
||||
void DBTypeConversionTest::test_roundTimeFraction_carries_into_seconds()
|
||||
{
|
||||
css::util::Time aTime;
|
||||
aTime.Hours = 0;
|
||||
aTime.Minutes = 3;
|
||||
aTime.Seconds = 59;
|
||||
aTime.NanoSeconds = 999960000; // rounds up to a full extra second
|
||||
CPPUNIT_ASSERT(!DBTypeConversion::roundTimeFraction(aTime, 4));
|
||||
CPPUNIT_ASSERT_EQUAL(u"00:04:00"_ustr, DBTypeConversion::toTimeString(aTime));
|
||||
}
|
||||
|
||||
void DBTypeConversionTest::test_roundTimeFraction_wraps_at_midnight()
|
||||
{
|
||||
css::util::Time aTime;
|
||||
aTime.Hours = 23;
|
||||
aTime.Minutes = 59;
|
||||
aTime.Seconds = 59;
|
||||
aTime.NanoSeconds = 999950000;
|
||||
CPPUNIT_ASSERT(DBTypeConversion::roundTimeFraction(aTime, 4));
|
||||
CPPUNIT_ASSERT_EQUAL(u"00:00:00"_ustr, DBTypeConversion::toTimeString(aTime));
|
||||
}
|
||||
|
||||
void DBTypeConversionTest::test_roundDateTimeFraction_carries_into_next_day()
|
||||
{
|
||||
css::util::DateTime aDT;
|
||||
aDT.Year = 2024;
|
||||
aDT.Month = 7;
|
||||
aDT.Day = 15;
|
||||
aDT.Hours = 23;
|
||||
aDT.Minutes = 59;
|
||||
aDT.Seconds = 59;
|
||||
aDT.NanoSeconds = 999950000;
|
||||
DBTypeConversion::roundDateTimeFraction(aDT, 4);
|
||||
CPPUNIT_ASSERT_EQUAL(u"2024-07-16 00:00:00"_ustr, DBTypeConversion::toDateTimeString(aDT));
|
||||
}
|
||||
|
||||
void DBTypeConversionTest::test_roundDateTimeFraction_rolls_over_month_end()
|
||||
{
|
||||
css::util::DateTime aDT;
|
||||
aDT.Year = 2024;
|
||||
aDT.Month = 12;
|
||||
aDT.Day = 31;
|
||||
aDT.Hours = 23;
|
||||
aDT.Minutes = 59;
|
||||
aDT.Seconds = 59;
|
||||
aDT.NanoSeconds = 999950000;
|
||||
DBTypeConversion::roundDateTimeFraction(aDT, 4);
|
||||
CPPUNIT_ASSERT_EQUAL(u"2025-01-01 00:00:00"_ustr, DBTypeConversion::toDateTimeString(aDT));
|
||||
}
|
||||
|
||||
void DBTypeConversionTest::test_roundTimeFraction_noop_when_no_cap_requested()
|
||||
{
|
||||
css::util::Time aTime;
|
||||
aTime.Hours = 0;
|
||||
aTime.Minutes = 3;
|
||||
aTime.Seconds = 0;
|
||||
aTime.NanoSeconds = 123456789;
|
||||
CPPUNIT_ASSERT(!DBTypeConversion::roundTimeFraction(aTime, 9));
|
||||
CPPUNIT_ASSERT_EQUAL(sal_uInt32(123456789), aTime.NanoSeconds);
|
||||
}
|
||||
|
||||
void DBTypeConversionTest::test_toDateTimeString_no_fraction_when_zero_nanoseconds()
|
||||
{
|
||||
css::util::DateTime aDT;
|
||||
aDT.Year = 2024;
|
||||
aDT.Month = 7;
|
||||
aDT.Day = 15;
|
||||
aDT.Hours = 14;
|
||||
aDT.Minutes = 30;
|
||||
aDT.Seconds = 0;
|
||||
aDT.NanoSeconds = 0;
|
||||
CPPUNIT_ASSERT_EQUAL(u"2024-07-15 14:30:00"_ustr, DBTypeConversion::toDateTimeString(aDT));
|
||||
}
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(DBTypeConversionTest);
|
||||
|
||||
} // namespace connectivity::commontools
|
||||
|
||||
@@ -75,6 +75,13 @@
|
||||
<node oor:name="Features">
|
||||
</node><!--Features-->
|
||||
<node oor:name="MetaData">
|
||||
<!-- Firebird's native TIME/TIMESTAMP precision is 1/10000s; it rejects a SQL
|
||||
literal with more fractional-seconds digits than that (tdf#153057). -->
|
||||
<node oor:name="MaxDateTimeLiteralFractionDigits" oor:op="replace">
|
||||
<prop oor:name="Value" oor:type="xs:int">
|
||||
<value>4</value>
|
||||
</prop>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<!-- Firebird EXTERNAL Driver -->
|
||||
@@ -129,6 +136,13 @@
|
||||
<value>UserPassword</value>
|
||||
</prop>
|
||||
</node>
|
||||
<!-- Firebird's native TIME/TIMESTAMP precision is 1/10000s; it rejects a SQL
|
||||
literal with more fractional-seconds digits than that (tdf#153057). -->
|
||||
<node oor:name="MaxDateTimeLiteralFractionDigits" oor:op="replace">
|
||||
<prop oor:name="Value" oor:type="xs:int">
|
||||
<value>4</value>
|
||||
</prop>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
|
||||
#include <connectivity/dbconversion.hxx>
|
||||
#include <connectivity/dbmetadata.hxx>
|
||||
#include <connectivity/dbtools.hxx>
|
||||
#include <com/sun/star/script/XTypeConverter.hpp>
|
||||
#include <com/sun/star/sdbc/DataType.hpp>
|
||||
@@ -32,6 +33,7 @@
|
||||
#include <comphelper/numbers.hxx>
|
||||
#include <comphelper/types.hxx>
|
||||
#include <rtl/ustrbuf.hxx>
|
||||
#include <tuple>
|
||||
#include <sal/log.hxx>
|
||||
#include <comphelper/diagnose_ex.hxx>
|
||||
|
||||
@@ -48,7 +50,8 @@ using namespace ::com::sun::star::util;
|
||||
using namespace ::com::sun::star::uno;
|
||||
|
||||
OUString DBTypeConversion::toSQLString(sal_Int32 eType, const Any& _rVal,
|
||||
const Reference< XTypeConverter >& _rxTypeConverter)
|
||||
const Reference< XTypeConverter >& _rxTypeConverter,
|
||||
const Reference< XConnection >& _rxConnection)
|
||||
{
|
||||
OUStringBuffer aRet;
|
||||
if (_rVal.hasValue())
|
||||
@@ -125,6 +128,10 @@ OUString DBTypeConversion::toSQLString(sal_Int32 eType, const Any& _rVal,
|
||||
// check if this is really a timestamp or only a date
|
||||
if ( bOk )
|
||||
{
|
||||
// This is a SQL literal, so cap the fraction to what
|
||||
// _rxConnection's backend can parse (tdf#153057).
|
||||
DBTypeConversion::roundDateTimeFraction(aDateTime,
|
||||
::dbtools::DatabaseMetaData(_rxConnection).getMaxDateTimeLiteralFractionDigits());
|
||||
aRet.append("{ts '"
|
||||
+ DBTypeConversion::toDateTimeString(aDateTime)
|
||||
+ "'}");
|
||||
@@ -178,6 +185,10 @@ OUString DBTypeConversion::toSQLString(sal_Int32 eType, const Any& _rVal,
|
||||
else
|
||||
bOk = _rVal >>= aTime;
|
||||
OSL_ENSURE( bOk,"DBTypeConversion::toSQLString: _rVal is not time!");
|
||||
// See the TIMESTAMP case above.
|
||||
// Discarding the day-carry return: this is just a Time.
|
||||
std::ignore = DBTypeConversion::roundTimeFraction(aTime,
|
||||
::dbtools::DatabaseMetaData(_rxConnection).getMaxDateTimeLiteralFractionDigits());
|
||||
aRet.append("{t '"
|
||||
+ DBTypeConversion::toTimeString(aTime)
|
||||
+ "'}");
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <sal/log.hxx>
|
||||
#include <unotools/datetime.hxx>
|
||||
#include <comphelper/date.hxx>
|
||||
#include <o3tl/safeint.hxx>
|
||||
#include <o3tl/string_view.hxx>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
@@ -100,8 +101,18 @@ namespace dbtools
|
||||
ostr.fill('0');
|
||||
ostr << setw(2) << rTime.Hours << ":"
|
||||
<< setw(2) << rTime.Minutes << ":"
|
||||
<< setw(2) << rTime.Seconds << "."
|
||||
<< setw(9) << rTime.NanoSeconds;
|
||||
<< setw(2) << rTime.Seconds;
|
||||
if (rTime.NanoSeconds)
|
||||
{
|
||||
std::ostringstream ostrFraction;
|
||||
ostrFraction.fill('0');
|
||||
ostrFraction << setw(9) << rTime.NanoSeconds;
|
||||
// Trim trailing zeros if exist, since some backends (e.g. Firebird)
|
||||
// reject a literal with more fractional digits than they support.
|
||||
std::string sFraction = ostrFraction.str();
|
||||
sFraction.erase(sFraction.find_last_not_of('0') + 1);
|
||||
ostr << "." << sFraction;
|
||||
}
|
||||
return OUString::createFromAscii(ostr.str());
|
||||
}
|
||||
|
||||
@@ -113,6 +124,43 @@ namespace dbtools
|
||||
return toDateString(aDate) + " " + toTimeString(aTime);
|
||||
}
|
||||
|
||||
bool DBTypeConversion::roundTimeFraction(css::util::Time& rTime, sal_Int32 nMaxFractionDigits)
|
||||
{
|
||||
// Round the fraction to at most nMaxFractionDigits digits,
|
||||
// carrying into seconds/minutes/hours as needed.
|
||||
if (nMaxFractionDigits >= 9 || nMaxFractionDigits < 0)
|
||||
return false;
|
||||
|
||||
sal_uInt32 nRoundingUnit = 1;
|
||||
for (sal_Int32 i = 0; i < 9 - nMaxFractionDigits; ++i)
|
||||
nRoundingUnit *= 10;
|
||||
|
||||
sal_uInt32 nNanoSeconds
|
||||
= ((rTime.NanoSeconds + nRoundingUnit / 2) / nRoundingUnit) * nRoundingUnit;
|
||||
bool bCarriedPastMidnight = false;
|
||||
if (nNanoSeconds >= o3tl::make_unsigned(nanoSecInSec))
|
||||
{
|
||||
nNanoSeconds -= static_cast<sal_uInt32>(nanoSecInSec);
|
||||
if (++rTime.Seconds >= secInMin)
|
||||
{
|
||||
rTime.Seconds -= secInMin;
|
||||
if (++rTime.Minutes >= minInHour)
|
||||
{
|
||||
rTime.Minutes -= minInHour;
|
||||
// Time has no day of its own to carry into so wrap
|
||||
// at 24h and report it to the caller.
|
||||
if (++rTime.Hours >= 24)
|
||||
{
|
||||
rTime.Hours -= 24;
|
||||
bCarriedPastMidnight = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
rTime.NanoSeconds = nNanoSeconds;
|
||||
return bCarriedPastMidnight;
|
||||
}
|
||||
|
||||
css::util::Date DBTypeConversion::toDate(const sal_Int32 _nVal)
|
||||
{
|
||||
css::util::Date aReturn;
|
||||
@@ -221,6 +269,27 @@ namespace dbtools
|
||||
comphelper::date::convertDaysToDate( nTempDays, _rDate.Day, _rDate.Month, _rDate.Year );
|
||||
}
|
||||
|
||||
void DBTypeConversion::roundDateTimeFraction(css::util::DateTime& rDateTime, sal_Int32 nMaxFractionDigits)
|
||||
{
|
||||
css::util::Time aTime(rDateTime.NanoSeconds, rDateTime.Seconds, rDateTime.Minutes,
|
||||
rDateTime.Hours, rDateTime.IsUTC);
|
||||
if (roundTimeFraction(aTime, nMaxFractionDigits))
|
||||
{
|
||||
// Unlike a bare Time, a DateTime does have a date to carry into,
|
||||
// so 23:59:59.99995 becomes the next day at 00:00:00 rather than
|
||||
// an out-of-range 24:00:00 on the original date.
|
||||
css::util::Date aDate(rDateTime.Day, rDateTime.Month, rDateTime.Year);
|
||||
addDays(1, aDate);
|
||||
rDateTime.Day = aDate.Day;
|
||||
rDateTime.Month = aDate.Month;
|
||||
rDateTime.Year = aDate.Year;
|
||||
}
|
||||
rDateTime.Hours = aTime.Hours;
|
||||
rDateTime.Minutes = aTime.Minutes;
|
||||
rDateTime.Seconds = aTime.Seconds;
|
||||
rDateTime.NanoSeconds = aTime.NanoSeconds;
|
||||
}
|
||||
|
||||
static void subDays(const sal_Int32 nDays, css::util::Date& _rDate )
|
||||
{
|
||||
sal_Int64 nTempDays = implRelativeToAbsoluteNull(_rDate);
|
||||
|
||||
@@ -300,6 +300,24 @@ namespace dbtools
|
||||
return doGenerate;
|
||||
}
|
||||
|
||||
sal_Int32 DatabaseMetaData::getMaxDateTimeLiteralFractionDigits() const
|
||||
{
|
||||
if ( !isConnected() )
|
||||
return 4; // fallback for a caller with no connection info
|
||||
|
||||
sal_Int32 nDigits( 9 );
|
||||
Any setting;
|
||||
if ( lcl_getDriverSetting( u"MaxDateTimeLiteralFractionDigits"_ustr, *m_pImpl, setting ) )
|
||||
{
|
||||
if( ! (setting >>= nDigits) )
|
||||
{
|
||||
SAL_WARN("connectivity.commontools", "getMaxDateTimeLiteralFractionDigits: unable to assign MaxDateTimeLiteralFractionDigits");
|
||||
nDigits = 4;
|
||||
}
|
||||
}
|
||||
return nDigits;
|
||||
}
|
||||
|
||||
bool DatabaseMetaData::shouldSubstituteParameterNames() const
|
||||
{
|
||||
bool doSubstitute( true );
|
||||
|
||||
@@ -128,7 +128,7 @@ namespace dbtools
|
||||
|
||||
std::unique_ptr<OSQLParseNode> OPredicateInputController::implPredicateTree(OUString& _rErrorMessage, const OUString& _rStatement, const Reference< XPropertySet > & _rxField) const
|
||||
{
|
||||
std::unique_ptr<OSQLParseNode> pReturn = const_cast< OSQLParser& >( m_aParser ).predicateTree( _rErrorMessage, _rStatement, m_xFormatter, _rxField );
|
||||
std::unique_ptr<OSQLParseNode> pReturn = const_cast< OSQLParser& >( m_aParser ).predicateTree( _rErrorMessage, _rStatement, m_xFormatter, _rxField, /*bUseRealName*/true, m_xConnection );
|
||||
if ( !pReturn )
|
||||
{ // is it a text field ?
|
||||
sal_Int32 nType = DataType::OTHER;
|
||||
@@ -149,7 +149,7 @@ namespace dbtools
|
||||
{
|
||||
sQuoted = u"'" + sQuoted.replaceAll(u"'", u"''") + u"'";
|
||||
}
|
||||
pReturn = const_cast< OSQLParser& >( m_aParser ).predicateTree( _rErrorMessage, sQuoted, m_xFormatter, _rxField );
|
||||
pReturn = const_cast< OSQLParser& >( m_aParser ).predicateTree( _rErrorMessage, sQuoted, m_xFormatter, _rxField, /*bUseRealName*/true, m_xConnection );
|
||||
}
|
||||
|
||||
// one more fallback: for numeric fields, and value strings containing a decimal/thousands separator
|
||||
@@ -215,7 +215,7 @@ namespace dbtools
|
||||
sTranslated = sTranslated.replace( nCtxThdSep, nFmtThdSep );
|
||||
sTranslated = sTranslated.replace( nIntermediate, nFmtDecSep );
|
||||
|
||||
pReturn = const_cast< OSQLParser& >( m_aParser ).predicateTree( _rErrorMessage, sTranslated, m_xFormatter, _rxField );
|
||||
pReturn = const_cast< OSQLParser& >( m_aParser ).predicateTree( _rErrorMessage, sTranslated, m_xFormatter, _rxField, /*bUseRealName*/true, m_xConnection );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -966,9 +966,9 @@ void SAL_CALL OPreparedStatement::setBytes(sal_Int32 nParameterIndex,
|
||||
setParameterNull(nParameterIndex, false);
|
||||
const sal_Int32 nMaxSize = 0xFFFF;
|
||||
const sal_uInt16 nSize = std::min(xBytes.getLength(), nMaxSize);
|
||||
// 8000 corresponds to value from lcl_addDefaultParameters
|
||||
// in dbaccess/source/filter/hsqldb/createparser.cxx
|
||||
if (nSize > 8000)
|
||||
// sqldata was allocated from sqllen in mallocSQLVAR, so grow it whenever the value is
|
||||
// longer than the column it is bound to.
|
||||
if (nSize > pVar->sqllen)
|
||||
{
|
||||
free(pVar->sqldata);
|
||||
pVar->sqldata = static_cast<char *>(malloc(sizeof(char) * nSize + 2));
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string_view>
|
||||
#include <tuple>
|
||||
|
||||
#include <rtl/ustrbuf.hxx>
|
||||
#include <sal/log.hxx>
|
||||
@@ -214,6 +215,14 @@ OUString OSQLParseNode::convertDateString(const SQLParseNodeParameter& rParam, s
|
||||
OUString OSQLParseNode::convertDateTimeString(const SQLParseNodeParameter& rParam, const OUString& rString)
|
||||
{
|
||||
DateTime aDate = DBTypeConversion::toDateTime(rString);
|
||||
|
||||
// round here in case of re-normalization on a rounded value
|
||||
if (aDate.NanoSeconds)
|
||||
{
|
||||
DBTypeConversion::roundDateTimeFraction(aDate, rParam.aMetaData.getMaxDateTimeLiteralFractionDigits());
|
||||
return DBTypeConversion::toDateTimeString(aDate);
|
||||
}
|
||||
|
||||
Reference< XNumberFormatsSupplier > xSupplier(rParam.xFormatter->getNumberFormatsSupplier());
|
||||
Reference< XNumberFormatTypes > xTypes(xSupplier->getNumberFormats(), UNO_QUERY);
|
||||
|
||||
@@ -226,6 +235,15 @@ OUString OSQLParseNode::convertDateTimeString(const SQLParseNodeParameter& rPara
|
||||
OUString OSQLParseNode::convertTimeString(const SQLParseNodeParameter& rParam, std::u16string_view rString)
|
||||
{
|
||||
css::util::Time aTime = DBTypeConversion::toTime(rString);
|
||||
|
||||
// Same fallback as convertDateTimeString() above
|
||||
if (aTime.NanoSeconds)
|
||||
{
|
||||
// Discarding the day-carry return: only time is relevant here
|
||||
std::ignore = DBTypeConversion::roundTimeFraction(aTime, rParam.aMetaData.getMaxDateTimeLiteralFractionDigits());
|
||||
return DBTypeConversion::toTimeString(aTime);
|
||||
}
|
||||
|
||||
Reference< XNumberFormatsSupplier > xSupplier(rParam.xFormatter->getNumberFormatsSupplier());
|
||||
|
||||
Reference< XNumberFormatTypes > xTypes(xSupplier->getNumberFormats(), UNO_QUERY);
|
||||
@@ -1081,6 +1099,7 @@ OSQLParseNode* OSQLParser::buildNode_Date(const double& fValue, sal_Int32 nType)
|
||||
case DataType::TIME:
|
||||
{
|
||||
css::util::Time aTime = DBTypeConversion::toTime(fValue);
|
||||
std::ignore = DBTypeConversion::roundTimeFraction(aTime, m_aMetaData.getMaxDateTimeLiteralFractionDigits());
|
||||
OUString aString = DBTypeConversion::toTimeString(aTime);
|
||||
pDateNode->append(new OSQLInternalNode("", SQLNodeType::Keyword, SQL_TOKEN_T));
|
||||
pDateNode->append(new OSQLInternalNode(aString, SQLNodeType::String));
|
||||
@@ -1089,6 +1108,7 @@ OSQLParseNode* OSQLParser::buildNode_Date(const double& fValue, sal_Int32 nType)
|
||||
case DataType::TIMESTAMP:
|
||||
{
|
||||
DateTime aDateTime = DBTypeConversion::toDateTime(fValue,DBTypeConversion::getNULLDate(m_xFormatter->getNumberFormatsSupplier()));
|
||||
DBTypeConversion::roundDateTimeFraction(aDateTime, m_aMetaData.getMaxDateTimeLiteralFractionDigits());
|
||||
if (aDateTime.Seconds || aDateTime.Minutes || aDateTime.Hours)
|
||||
{
|
||||
OUString aString = DBTypeConversion::toDateTimeString(aDateTime);
|
||||
@@ -1176,7 +1196,8 @@ std::mutex& OSQLParser::getMutex()
|
||||
std::unique_ptr<OSQLParseNode> OSQLParser::predicateTree(OUString& rErrorMessage, const OUString& rStatement,
|
||||
const Reference< css::util::XNumberFormatter > & xFormatter,
|
||||
const Reference< XPropertySet > & xField,
|
||||
bool bUseRealName)
|
||||
bool bUseRealName,
|
||||
const Reference< css::sdbc::XConnection >& xConnection)
|
||||
{
|
||||
// Guard the parsing
|
||||
std::unique_lock aGuard(getMutex());
|
||||
@@ -1187,6 +1208,7 @@ std::unique_ptr<OSQLParseNode> OSQLParser::predicateTree(OUString& rErrorMessage
|
||||
// reset the parser
|
||||
m_xField = xField;
|
||||
m_xFormatter = xFormatter;
|
||||
m_aMetaData = ::dbtools::DatabaseMetaData(xConnection);
|
||||
|
||||
if (m_xField.is())
|
||||
{
|
||||
|
||||
@@ -728,8 +728,8 @@ private:
|
||||
DECL_LINK(OnMoreColorsClick, weld::Button&, void);
|
||||
|
||||
DECL_LINK(SelectPaletteLBHdl, weld::ComboBox&, void);
|
||||
DECL_LINK(ActivatePaletteColorHdl, const Color&, void);
|
||||
DECL_LINK(ActivateRecentColorHdl, const Color&, void);
|
||||
DECL_LINK(ActivatePaletteColorHdl, int, void);
|
||||
DECL_LINK(ActivateRecentColorHdl, int, void);
|
||||
DECL_LINK( SelectColorModeHdl_Impl, weld::Toggleable&, void );
|
||||
void UpdateToSelectedColor(const NamedColor& rNamedColor);
|
||||
void ChangeColor(const NamedColor &rNewColor, bool bUpdatePreset = true);
|
||||
|
||||
+17
-16
@@ -210,23 +210,23 @@ class SvxNumOptionsTabPage : public SfxTabPage
|
||||
OUString m_sNumCharFmtName;
|
||||
OUString m_sBulletCharFormatName;
|
||||
|
||||
Timer aInvalidateTimer;
|
||||
Timer m_aInvalidateTimer;
|
||||
|
||||
std::unique_ptr<SvxNumRule> pActNum;
|
||||
std::unique_ptr<SvxNumRule> pSaveNum;
|
||||
std::unique_ptr<SvxNumRule> m_pActNum;
|
||||
std::unique_ptr<SvxNumRule> m_pSaveNum;
|
||||
|
||||
Size aInitSize[SVX_MAX_NUM];
|
||||
Size m_aInitSize[SVX_MAX_NUM];
|
||||
|
||||
ImplSVEvent* m_pLevelHdlEvent;
|
||||
|
||||
bool bLastWidthModified : 1;
|
||||
bool bModified : 1;
|
||||
bool bPreset : 1;
|
||||
bool bAutomaticCharStyles: 1;
|
||||
bool bHTMLMode : 1;
|
||||
bool m_bLastWidthModified : 1;
|
||||
bool m_bModified : 1;
|
||||
bool m_bPreset : 1;
|
||||
bool m_bAutomaticCharStyles : 1;
|
||||
bool m_bHTMLMode : 1;
|
||||
|
||||
std::vector<OUString> aGrfNames;
|
||||
vcl::Font aActBulletFont;
|
||||
std::vector<OUString> m_aGrfNames;
|
||||
vcl::Font m_aActBulletFont;
|
||||
|
||||
enum class NumberType {
|
||||
SHOW_NUMBERING = 0,
|
||||
@@ -234,11 +234,11 @@ class SvxNumOptionsTabPage : public SfxTabPage
|
||||
SHOW_BITMAP = 2,
|
||||
NONE = 0xff
|
||||
};
|
||||
NumberType nBullet;
|
||||
NumberType m_nBullet;
|
||||
|
||||
sal_uInt16 nActNumLvl;
|
||||
TypedWhichId<SvxNumBulletItem> nNumItemId;
|
||||
MapUnit eCoreUnit;
|
||||
sal_uInt16 m_nActNumLvl;
|
||||
TypedWhichId<SvxNumBulletItem> m_nNumItemId;
|
||||
MapUnit m_eCoreUnit;
|
||||
|
||||
SvxRatioConnector m_aRatioTop;
|
||||
SvxRatioConnector m_aRatioBottom;
|
||||
@@ -289,7 +289,6 @@ class SvxNumOptionsTabPage : public SfxTabPage
|
||||
DECL_LINK(NumberTypeSelectHdl_Impl, weld::ComboBox&, void);
|
||||
DECL_LINK(LevelHdl_Impl, weld::ItemView&, void);
|
||||
DECL_LINK(LevelHdl, void *, void);
|
||||
DECL_LINK(PopupActivateHdl_Impl, weld::Toggleable&, void);
|
||||
DECL_LINK(GraphicHdl_Impl, const OUString&, void);
|
||||
DECL_LINK(BulletHdl_Impl, weld::Button&, void);
|
||||
DECL_LINK(SizeHdl_Impl, weld::MetricSpinButton&, void);
|
||||
@@ -306,6 +305,8 @@ class SvxNumOptionsTabPage : public SfxTabPage
|
||||
DECL_LINK(PreviewInvalidateHdl_Impl, Timer*, void);
|
||||
void EditModifyHdl_Impl(const weld::TextWidget*);
|
||||
|
||||
void CreateGalleryMenu();
|
||||
|
||||
public:
|
||||
SvxNumOptionsTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
|
||||
virtual ~SvxNumOptionsTabPage() override;
|
||||
|
||||
@@ -177,6 +177,9 @@ class SvxParaAlignTabPage : public SfxTabPage
|
||||
std::unique_ptr<weld::MetricSpinButton> m_xLetterSpacingMinimum;
|
||||
std::unique_ptr<weld::MetricSpinButton> m_xLetterSpacingMaximum;
|
||||
|
||||
/// compound-based hyphenation
|
||||
std::unique_ptr<weld::CheckButton> m_xCompoundBased;
|
||||
|
||||
/// glyph scaling
|
||||
std::unique_ptr<weld::Label> m_xLabelGlyphScaling;
|
||||
std::unique_ptr<weld::MetricSpinButton> m_xGlyphScalingMinimum;
|
||||
|
||||
@@ -344,12 +344,13 @@ IMPL_LINK_NOARG( SvxDefaultColorOptPage, SelectPaletteLbHdl, weld::ComboBox&, vo
|
||||
aPaletteManager.ReloadColorSet(m_aColorIconView);
|
||||
}
|
||||
|
||||
IMPL_LINK(SvxDefaultColorOptPage, ColorActivatedHdl, const Color&, rColor, void)
|
||||
IMPL_LINK(SvxDefaultColorOptPage, ColorActivatedHdl, int, nIndex, void)
|
||||
{
|
||||
sal_Int32 nIdx = m_xLbChartColors->get_selected_index();
|
||||
if (nIdx != -1)
|
||||
{
|
||||
const XColorEntry aEntry(rColor, m_xLbChartColors->get_selected_text());
|
||||
const XColorEntry aEntry(m_aColorIconView.getColor(nIndex),
|
||||
m_xLbChartColors->get_selected_text());
|
||||
|
||||
ModifyColorEntry(aEntry, nIdx);
|
||||
m_SvxChartColorTableUniquePtr->replace(nIdx, aEntry);
|
||||
|
||||
@@ -53,7 +53,7 @@ private:
|
||||
DECL_LINK(ResetToDefaults, weld::Button&, void);
|
||||
DECL_LINK(AddChartColor, weld::Button&, void);
|
||||
DECL_LINK(RemoveChartColor, weld::Button&, void);
|
||||
DECL_LINK(ColorActivatedHdl, const Color&, void);
|
||||
DECL_LINK(ColorActivatedHdl, int, void);
|
||||
DECL_LINK(SelectPaletteLbHdl, weld::ComboBox&, void);
|
||||
DECL_LINK(LbChartColorsSelectionChangedHdl, weld::ItemView&, void);
|
||||
|
||||
|
||||
+183
-175
@@ -1126,16 +1126,16 @@ IMPL_LINK_NOARG(SvxBitmapPickTabPage, ClickAddBrowseHdl_Impl, weld::Button&, voi
|
||||
SvxNumOptionsTabPage::SvxNumOptionsTabPage(weld::Container* pPage, weld::DialogController* pController,
|
||||
const SfxItemSet& rSet)
|
||||
: SfxTabPage(pPage, pController, u"cui/ui/numberingoptionspage.ui"_ustr, u"NumberingOptionsPage"_ustr, &rSet)
|
||||
, aInvalidateTimer("cui SvxNumOptionsTabPage aInvalidateTimer")
|
||||
, m_aInvalidateTimer("cui SvxNumOptionsTabPage aInvalidateTimer")
|
||||
, m_pLevelHdlEvent(nullptr)
|
||||
, bLastWidthModified(false)
|
||||
, bModified(false)
|
||||
, bPreset(false)
|
||||
, bAutomaticCharStyles(true)
|
||||
, bHTMLMode(false)
|
||||
, nBullet(NumberType::NONE)
|
||||
, nActNumLvl(1)
|
||||
, nNumItemId(SID_ATTR_NUMBERING_RULE)
|
||||
, m_bLastWidthModified(false)
|
||||
, m_bModified(false)
|
||||
, m_bPreset(false)
|
||||
, m_bAutomaticCharStyles(true)
|
||||
, m_bHTMLMode(false)
|
||||
, m_nBullet(NumberType::NONE)
|
||||
, m_nActNumLvl(1)
|
||||
, m_nNumItemId(SID_ATTR_NUMBERING_RULE)
|
||||
, m_aRatioTop(ConnectorType::Top)
|
||||
, m_aRatioBottom(ConnectorType::Bottom)
|
||||
, m_xGrid(m_xBuilder->weld_widget(u"grid2"_ustr))
|
||||
@@ -1180,7 +1180,7 @@ SvxNumOptionsTabPage::SvxNumOptionsTabPage(weld::Container* pPage, weld::DialogC
|
||||
m_xBulRelSizeMF->set_min(SVX_NUM_REL_SIZE_MIN, FieldUnit::PERCENT);
|
||||
m_xBulRelSizeMF->set_increments(5, 50, FieldUnit::PERCENT);
|
||||
SetExchangeSupport();
|
||||
aActBulletFont = lcl_GetDefaultBulletFont();
|
||||
m_aActBulletFont = lcl_GetDefaultBulletFont();
|
||||
// vertical alignment = fill makes the drawingarea expand the associated spinedits so we have to size it here
|
||||
const sal_Int16 aHeight
|
||||
= static_cast<sal_Int16>(std::max(int(m_xRatioCB->get_preferred_size().getHeight() / 2
|
||||
@@ -1197,7 +1197,6 @@ SvxNumOptionsTabPage::SvxNumOptionsTabPage(weld::Container* pPage, weld::DialogC
|
||||
m_xBulletPB->connect_clicked(LINK(this, SvxNumOptionsTabPage, BulletHdl_Impl));
|
||||
m_xFmtLB->connect_changed(LINK(this, SvxNumOptionsTabPage, NumberTypeSelectHdl_Impl));
|
||||
m_xBitmapMB->connect_selected(LINK(this, SvxNumOptionsTabPage, GraphicHdl_Impl));
|
||||
m_xBitmapMB->connect_toggled(LINK(this, SvxNumOptionsTabPage, PopupActivateHdl_Impl));
|
||||
m_xLevelLB->set_selection_mode(SelectionMode::Multiple);
|
||||
m_xLevelLB->connect_selection_changed(LINK(this, SvxNumOptionsTabPage, LevelHdl_Impl));
|
||||
m_xCharFmtLB->connect_changed(LINK(this, SvxNumOptionsTabPage, CharFmtHdl_Impl));
|
||||
@@ -1213,10 +1212,12 @@ SvxNumOptionsTabPage::SvxNumOptionsTabPage(weld::Container* pPage, weld::DialogC
|
||||
m_xSameLevelCB->connect_toggled(LINK(this, SvxNumOptionsTabPage, SameLevelHdl_Impl));
|
||||
m_xBulRelSizeMF->connect_value_changed(LINK(this,SvxNumOptionsTabPage, BulRelSizeHdl_Impl));
|
||||
m_xBulColLB->SetSelectHdl(LINK(this, SvxNumOptionsTabPage, BulColorHdl_Impl));
|
||||
aInvalidateTimer.SetInvokeHandler(LINK(this, SvxNumOptionsTabPage, PreviewInvalidateHdl_Impl));
|
||||
aInvalidateTimer.SetTimeout(50);
|
||||
m_aInvalidateTimer.SetInvokeHandler(
|
||||
LINK(this, SvxNumOptionsTabPage, PreviewInvalidateHdl_Impl));
|
||||
m_aInvalidateTimer.SetTimeout(50);
|
||||
|
||||
eCoreUnit = rSet.GetPool()->GetMetric(rSet.GetPool()->GetWhichIDFromSlotID(SID_ATTR_NUMBERING_RULE));
|
||||
m_eCoreUnit
|
||||
= rSet.GetPool()->GetMetric(rSet.GetPool()->GetWhichIDFromSlotID(SID_ATTR_NUMBERING_RULE));
|
||||
|
||||
// Fill ListBox with predefined / translated numbering types.
|
||||
sal_uInt32 nCount = SvxNumberingTypeTable::Count();
|
||||
@@ -1244,8 +1245,8 @@ SvxNumOptionsTabPage::~SvxNumOptionsTabPage()
|
||||
{
|
||||
m_xPreviewWIN.reset();
|
||||
m_xBulColLB.reset();
|
||||
pActNum.reset();
|
||||
pSaveNum.reset();
|
||||
m_pActNum.reset();
|
||||
m_pSaveNum.reset();
|
||||
if (m_pLevelHdlEvent)
|
||||
{
|
||||
Application::RemoveUserEvent(m_pLevelHdlEvent);
|
||||
@@ -1277,34 +1278,34 @@ void SvxNumOptionsTabPage::ActivatePage(const SfxItemSet& rSet)
|
||||
if(pExampleSet)
|
||||
{
|
||||
if(const SfxBoolItem* pPresetItem = pExampleSet->GetItemIfSet(SID_PARAM_NUM_PRESET, false))
|
||||
bPreset = pPresetItem->GetValue();
|
||||
m_bPreset = pPresetItem->GetValue();
|
||||
if(const SfxUInt16Item* pLevelItem = pExampleSet->GetItemIfSet(SID_PARAM_CUR_NUM_LEVEL, false))
|
||||
nTmpNumLvl = pLevelItem->GetValue();
|
||||
}
|
||||
if(const SvxNumBulletItem* pBulletItem = rSet.GetItemIfSet(nNumItemId, false))
|
||||
if (const SvxNumBulletItem* pBulletItem = rSet.GetItemIfSet(m_nNumItemId, false))
|
||||
{
|
||||
pSaveNum.reset( new SvxNumRule(pBulletItem->GetNumRule()) );
|
||||
m_pSaveNum.reset(new SvxNumRule(pBulletItem->GetNumRule()));
|
||||
}
|
||||
|
||||
bModified = (!pActNum->Get( 0 ) || bPreset);
|
||||
if(*pActNum == *pSaveNum && nActNumLvl == nTmpNumLvl)
|
||||
m_bModified = (!m_pActNum->Get(0) || m_bPreset);
|
||||
if (*m_pActNum == *m_pSaveNum && m_nActNumLvl == nTmpNumLvl)
|
||||
return;
|
||||
|
||||
nActNumLvl = nTmpNumLvl;
|
||||
m_nActNumLvl = nTmpNumLvl;
|
||||
sal_uInt16 nMask = 1;
|
||||
m_xLevelLB->unselect_all();
|
||||
if (nActNumLvl == SAL_MAX_UINT16)
|
||||
m_xLevelLB->select(pActNum->GetLevelCount());
|
||||
if(nActNumLvl != SAL_MAX_UINT16)
|
||||
if (m_nActNumLvl == SAL_MAX_UINT16)
|
||||
m_xLevelLB->select(m_pActNum->GetLevelCount());
|
||||
if (m_nActNumLvl != SAL_MAX_UINT16)
|
||||
{
|
||||
for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
|
||||
for (sal_uInt16 i = 0; i < m_pActNum->GetLevelCount(); i++)
|
||||
{
|
||||
if(nActNumLvl & nMask)
|
||||
if (m_nActNumLvl & nMask)
|
||||
m_xLevelLB->select(i);
|
||||
nMask <<= 1 ;
|
||||
}
|
||||
}
|
||||
*pActNum = *pSaveNum;
|
||||
*m_pActNum = *m_pSaveNum;
|
||||
|
||||
InitControls();
|
||||
}
|
||||
@@ -1318,14 +1319,14 @@ DeactivateRC SvxNumOptionsTabPage::DeactivatePage(SfxItemSet * _pSet)
|
||||
|
||||
bool SvxNumOptionsTabPage::FillItemSet( SfxItemSet* rSet )
|
||||
{
|
||||
rSet->Put(SfxUInt16Item(SID_PARAM_CUR_NUM_LEVEL, nActNumLvl));
|
||||
if(bModified && pActNum)
|
||||
rSet->Put(SfxUInt16Item(SID_PARAM_CUR_NUM_LEVEL, m_nActNumLvl));
|
||||
if (m_bModified && m_pActNum)
|
||||
{
|
||||
*pSaveNum = *pActNum;
|
||||
rSet->Put(SvxNumBulletItem( *pSaveNum, nNumItemId ));
|
||||
*m_pSaveNum = *m_pActNum;
|
||||
rSet->Put(SvxNumBulletItem(*m_pSaveNum, m_nNumItemId));
|
||||
rSet->Put(SfxBoolItem(SID_PARAM_NUM_PRESET, false));
|
||||
}
|
||||
return bModified;
|
||||
return m_bModified;
|
||||
};
|
||||
|
||||
void SvxNumOptionsTabPage::Reset( const SfxItemSet* rSet )
|
||||
@@ -1335,25 +1336,25 @@ void SvxNumOptionsTabPage::Reset( const SfxItemSet* rSet )
|
||||
rSet->GetItemIfSet(SID_ATTR_NUMBERING_RULE, false);
|
||||
if(!pBulletItem)
|
||||
{
|
||||
nNumItemId = rSet->GetPool()->GetWhichIDFromSlotID(SID_ATTR_NUMBERING_RULE);
|
||||
pBulletItem = rSet->GetItemIfSet(nNumItemId, false);
|
||||
m_nNumItemId = rSet->GetPool()->GetWhichIDFromSlotID(SID_ATTR_NUMBERING_RULE);
|
||||
pBulletItem = rSet->GetItemIfSet(m_nNumItemId, false);
|
||||
|
||||
if( !pBulletItem )
|
||||
{
|
||||
pBulletItem = & rSet->Get( nNumItemId );
|
||||
pBulletItem = &rSet->Get(m_nNumItemId);
|
||||
}
|
||||
}
|
||||
DBG_ASSERT(pBulletItem, "no item found!");
|
||||
pSaveNum.reset( new SvxNumRule(pBulletItem->GetNumRule()) );
|
||||
m_pSaveNum.reset(new SvxNumRule(pBulletItem->GetNumRule()));
|
||||
|
||||
// insert levels
|
||||
if (!m_xLevelLB->n_children())
|
||||
{
|
||||
for(sal_uInt16 i = 1; i <= pSaveNum->GetLevelCount(); i++)
|
||||
for (sal_uInt16 i = 1; i <= m_pSaveNum->GetLevelCount(); i++)
|
||||
m_xLevelLB->append_text(OUString::number(i));
|
||||
if(pSaveNum->GetLevelCount() > 1)
|
||||
if (m_pSaveNum->GetLevelCount() > 1)
|
||||
{
|
||||
OUString sEntry = "1 - " + OUString::number( pSaveNum->GetLevelCount() );
|
||||
OUString sEntry = "1 - " + OUString::number(m_pSaveNum->GetLevelCount());
|
||||
m_xLevelLB->append_text(sEntry);
|
||||
m_xLevelLB->select_text(sEntry);
|
||||
}
|
||||
@@ -1365,26 +1366,26 @@ void SvxNumOptionsTabPage::Reset( const SfxItemSet* rSet )
|
||||
|
||||
sal_uInt16 nMask = 1;
|
||||
m_xLevelLB->unselect_all();
|
||||
if (nActNumLvl == SAL_MAX_UINT16)
|
||||
if (m_nActNumLvl == SAL_MAX_UINT16)
|
||||
{
|
||||
m_xLevelLB->select( pSaveNum->GetLevelCount() );
|
||||
m_xLevelLB->select(m_pSaveNum->GetLevelCount());
|
||||
}
|
||||
else
|
||||
{
|
||||
for(sal_uInt16 i = 0; i < pSaveNum->GetLevelCount(); i++)
|
||||
for (sal_uInt16 i = 0; i < m_pSaveNum->GetLevelCount(); i++)
|
||||
{
|
||||
if(nActNumLvl & nMask)
|
||||
if (m_nActNumLvl & nMask)
|
||||
m_xLevelLB->select( i );
|
||||
nMask <<= 1 ;
|
||||
}
|
||||
}
|
||||
|
||||
if(!pActNum)
|
||||
pActNum.reset( new SvxNumRule(*pSaveNum) );
|
||||
else if(*pSaveNum != *pActNum)
|
||||
*pActNum = *pSaveNum;
|
||||
m_aPreviewWIN.SetNumRule(pActNum.get());
|
||||
m_xSameLevelCB->set_active(pActNum->IsContinuousNumbering());
|
||||
if (!m_pActNum)
|
||||
m_pActNum.reset(new SvxNumRule(*m_pSaveNum));
|
||||
else if (*m_pSaveNum != *m_pActNum)
|
||||
*m_pActNum = *m_pSaveNum;
|
||||
m_aPreviewWIN.SetNumRule(m_pActNum.get());
|
||||
m_xSameLevelCB->set_active(m_pActNum->IsContinuousNumbering());
|
||||
|
||||
const SfxUInt16Item* pHtmlModeItem =
|
||||
rSet->GetItemIfSet( SID_HTML_MODE, false );
|
||||
@@ -1396,16 +1397,16 @@ void SvxNumOptionsTabPage::Reset( const SfxItemSet* rSet )
|
||||
if ( pHtmlModeItem )
|
||||
{
|
||||
sal_uInt16 nHtmlMode = pHtmlModeItem->GetValue();
|
||||
bHTMLMode = 0 != (nHtmlMode&HTMLMODE_ON);
|
||||
m_bHTMLMode = 0 != (nHtmlMode & HTMLMODE_ON);
|
||||
}
|
||||
|
||||
bool bCharFmt = pActNum->IsFeatureSupported(SvxNumRuleFlags::CHAR_STYLE);
|
||||
bool bCharFmt = m_pActNum->IsFeatureSupported(SvxNumRuleFlags::CHAR_STYLE);
|
||||
m_xCharFmtFT->set_visible(bCharFmt);
|
||||
m_xCharFmtLB->set_visible(bCharFmt);
|
||||
|
||||
bool bContinuous = pActNum->IsFeatureSupported(SvxNumRuleFlags::CONTINUOUS);
|
||||
bool bContinuous = m_pActNum->IsFeatureSupported(SvxNumRuleFlags::CONTINUOUS);
|
||||
|
||||
bool bAllLevel = bContinuous && !bHTMLMode;
|
||||
bool bAllLevel = bContinuous && !m_bHTMLMode;
|
||||
m_xAllLevelFT->set_visible(bAllLevel);
|
||||
m_xAllLevelNF->set_visible(bAllLevel);
|
||||
m_xIsLegalCB->set_visible(bAllLevel);
|
||||
@@ -1427,13 +1428,13 @@ void SvxNumOptionsTabPage::Reset( const SfxItemSet* rSet )
|
||||
}
|
||||
}
|
||||
//one must be enabled
|
||||
if(!pActNum->IsFeatureSupported(SvxNumRuleFlags::ENABLE_LINKED_BMP))
|
||||
if (!m_pActNum->IsFeatureSupported(SvxNumRuleFlags::ENABLE_LINKED_BMP))
|
||||
{
|
||||
auto nPos = m_xFmtLB->find_id(OUString::number(SVX_NUM_BITMAP|LINK_TOKEN));
|
||||
if (nPos != -1)
|
||||
m_xFmtLB->remove(nPos);
|
||||
}
|
||||
else if(!pActNum->IsFeatureSupported(SvxNumRuleFlags::ENABLE_EMBEDDED_BMP))
|
||||
else if (!m_pActNum->IsFeatureSupported(SvxNumRuleFlags::ENABLE_EMBEDDED_BMP))
|
||||
{
|
||||
auto nPos = m_xFmtLB->find_id(OUString::number(SVX_NUM_BITMAP));
|
||||
if (nPos != -1)
|
||||
@@ -1442,7 +1443,7 @@ void SvxNumOptionsTabPage::Reset( const SfxItemSet* rSet )
|
||||
|
||||
// MegaHack: because of a not-fixable 'design mistake/error' in Impress
|
||||
// delete all kinds of numeric enumerations
|
||||
if(pActNum->IsFeatureSupported(SvxNumRuleFlags::NO_NUMBERS))
|
||||
if (m_pActNum->IsFeatureSupported(SvxNumRuleFlags::NO_NUMBERS))
|
||||
{
|
||||
sal_Int32 nFmtCount = m_xFmtLB->get_count();
|
||||
for(sal_Int32 i = nFmtCount; i; i--)
|
||||
@@ -1454,7 +1455,7 @@ void SvxNumOptionsTabPage::Reset( const SfxItemSet* rSet )
|
||||
}
|
||||
|
||||
InitControls();
|
||||
bModified = false;
|
||||
m_bModified = false;
|
||||
const SvxLanguageItem* pLangItem = rSet->GetItemIfSet(SID_ATTR_CHAR_LANGUAGE, true);
|
||||
if (!pLangItem)
|
||||
pLangItem = rSet->GetItemIfSet(EE_CHAR_LANGUAGE, true);
|
||||
@@ -1487,13 +1488,13 @@ void SvxNumOptionsTabPage::InitControls()
|
||||
sal_uInt16 nLvl = SAL_MAX_UINT16;
|
||||
sal_uInt16 nHighestLevel = 0;
|
||||
|
||||
bool bBullColor = pActNum->IsFeatureSupported(SvxNumRuleFlags::BULLET_COLOR);
|
||||
bool bBullRelSize = pActNum->IsFeatureSupported(SvxNumRuleFlags::BULLET_REL_SIZE);
|
||||
for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
|
||||
bool bBullColor = m_pActNum->IsFeatureSupported(SvxNumRuleFlags::BULLET_COLOR);
|
||||
bool bBullRelSize = m_pActNum->IsFeatureSupported(SvxNumRuleFlags::BULLET_REL_SIZE);
|
||||
for (sal_uInt16 i = 0; i < m_pActNum->GetLevelCount(); i++)
|
||||
{
|
||||
if(nActNumLvl & nMask)
|
||||
if (m_nActNumLvl & nMask)
|
||||
{
|
||||
aNumFmtArr[i] = &pActNum->GetLevel(i);
|
||||
aNumFmtArr[i] = &m_pActNum->GetLevel(i);
|
||||
bShowBullet &= aNumFmtArr[i]->GetNumberingType() == SVX_NUM_CHAR_SPECIAL;
|
||||
bShowBitmap &= (aNumFmtArr[i]->GetNumberingType()&(~LINK_TOKEN)) == SVX_NUM_BITMAP;
|
||||
if(SAL_MAX_UINT16 == nLvl)
|
||||
@@ -1558,8 +1559,8 @@ void SvxNumOptionsTabPage::InitControls()
|
||||
|
||||
if(bSameSize)
|
||||
{
|
||||
SetMetricValue(*m_xHeightMF, aFirstSize.Height(), eCoreUnit);
|
||||
SetMetricValue(*m_xWidthMF, aFirstSize.Width(), eCoreUnit);
|
||||
SetMetricValue(*m_xHeightMF, aFirstSize.Height(), m_eCoreUnit);
|
||||
SetMetricValue(*m_xWidthMF, aFirstSize.Width(), m_eCoreUnit);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1605,7 +1606,7 @@ void SvxNumOptionsTabPage::InitControls()
|
||||
m_xBulColLB->SetNoSelection();
|
||||
}
|
||||
m_xStartED->set_value(1); // If this isn't set then changing the bullet type to a numbered type doesn't reset the start level
|
||||
switch(nBullet)
|
||||
switch (m_nBullet)
|
||||
{
|
||||
case NumberType::SHOW_NUMBERING:
|
||||
if(bSameStart)
|
||||
@@ -1642,16 +1643,16 @@ void SvxNumOptionsTabPage::InitControls()
|
||||
else
|
||||
m_xCharFmtLB->set_active(-1);
|
||||
|
||||
m_aPreviewWIN.SetLevel(nActNumLvl);
|
||||
m_aPreviewWIN.SetLevel(m_nActNumLvl);
|
||||
m_aPreviewWIN.Invalidate();
|
||||
}
|
||||
|
||||
// 0 - Number; 1 - Bullet; 2 - Bitmap
|
||||
void SvxNumOptionsTabPage::SwitchNumberType( NumberType nType )
|
||||
{
|
||||
if(nBullet == nType)
|
||||
if (m_nBullet == nType)
|
||||
return;
|
||||
nBullet = nType;
|
||||
m_nBullet = nType;
|
||||
bool bBullet = (nType == NumberType::SHOW_BULLET);
|
||||
bool bBitmap = (nType == NumberType::SHOW_BITMAP);
|
||||
bool bEnableBitmap = (nType == NumberType::SHOW_BITMAP);
|
||||
@@ -1662,14 +1663,14 @@ void SvxNumOptionsTabPage::SwitchNumberType( NumberType nType )
|
||||
m_xSuffixFT->set_visible(bNumeric);
|
||||
m_xSuffixED->set_visible(bNumeric);
|
||||
|
||||
bool bCharFmt = pActNum->IsFeatureSupported(SvxNumRuleFlags::CHAR_STYLE);
|
||||
bool bCharFmt = m_pActNum->IsFeatureSupported(SvxNumRuleFlags::CHAR_STYLE);
|
||||
m_xCharFmtFT->set_visible(!bBitmap && bCharFmt);
|
||||
m_xCharFmtLB->set_visible(!bBitmap && bCharFmt);
|
||||
|
||||
// this is rather misusage, as there is no own flag
|
||||
// for complete numeration
|
||||
bool bAllLevelFeature = pActNum->IsFeatureSupported(SvxNumRuleFlags::CONTINUOUS);
|
||||
bool bAllLevel = bNumeric && bAllLevelFeature && !bHTMLMode;
|
||||
bool bAllLevelFeature = m_pActNum->IsFeatureSupported(SvxNumRuleFlags::CONTINUOUS);
|
||||
bool bAllLevel = bNumeric && bAllLevelFeature && !m_bHTMLMode;
|
||||
m_xAllLevelFT->set_visible(bAllLevel);
|
||||
m_xAllLevelNF->set_visible(bAllLevel);
|
||||
m_xIsLegalCB->set_visible(bAllLevel);
|
||||
@@ -1679,15 +1680,17 @@ void SvxNumOptionsTabPage::SwitchNumberType( NumberType nType )
|
||||
|
||||
m_xBulletFT->set_visible(bBullet);
|
||||
m_xBulletPB->set_visible(bBullet);
|
||||
bool bBullColor = pActNum->IsFeatureSupported(SvxNumRuleFlags::BULLET_COLOR);
|
||||
bool bBullColor = m_pActNum->IsFeatureSupported(SvxNumRuleFlags::BULLET_COLOR);
|
||||
m_xBulColorFT->set_visible(!bBitmap && bBullColor);
|
||||
m_xBulColLB->set_visible(!bBitmap && bBullColor);
|
||||
bool bBullResSize = pActNum->IsFeatureSupported(SvxNumRuleFlags::BULLET_REL_SIZE);
|
||||
bool bBullResSize = m_pActNum->IsFeatureSupported(SvxNumRuleFlags::BULLET_REL_SIZE);
|
||||
m_xBulRelSizeFT->set_visible(!bBitmap && bBullResSize);
|
||||
m_xBulRelSizeMF->set_visible(!bBitmap && bBullResSize);
|
||||
|
||||
m_xBitmapFT->set_visible(bBitmap);
|
||||
m_xBitmapMB->set_visible(bBitmap);
|
||||
if (bBitmap)
|
||||
CreateGalleryMenu();
|
||||
|
||||
m_xWidthFT->set_visible(bBitmap);
|
||||
m_xWidthMF->set_visible(bBitmap);
|
||||
@@ -1724,34 +1727,35 @@ IMPL_LINK_NOARG(SvxNumOptionsTabPage, LevelHdl, void*, void)
|
||||
{
|
||||
m_pLevelHdlEvent = nullptr;
|
||||
|
||||
sal_uInt16 nSaveNumLvl = nActNumLvl;
|
||||
nActNumLvl = 0;
|
||||
sal_uInt16 nSaveNumLvl = m_nActNumLvl;
|
||||
m_nActNumLvl = 0;
|
||||
std::vector<int> aSelectedRows = m_xLevelLB->get_selected_rows();
|
||||
if (std::find(aSelectedRows.begin(), aSelectedRows.end(), pActNum->GetLevelCount()) != aSelectedRows.end() &&
|
||||
(aSelectedRows.size() == 1 || nSaveNumLvl != 0xffff))
|
||||
if (std::find(aSelectedRows.begin(), aSelectedRows.end(), m_pActNum->GetLevelCount())
|
||||
!= aSelectedRows.end()
|
||||
&& (aSelectedRows.size() == 1 || nSaveNumLvl != 0xffff))
|
||||
{
|
||||
nActNumLvl = 0xFFFF;
|
||||
for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++ )
|
||||
m_nActNumLvl = 0xFFFF;
|
||||
for (sal_uInt16 i = 0; i < m_pActNum->GetLevelCount(); i++)
|
||||
m_xLevelLB->unselect(i);
|
||||
}
|
||||
else if (!aSelectedRows.empty())
|
||||
{
|
||||
sal_uInt16 nMask = 1;
|
||||
for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++ )
|
||||
for (sal_uInt16 i = 0; i < m_pActNum->GetLevelCount(); i++)
|
||||
{
|
||||
if (std::find(aSelectedRows.begin(), aSelectedRows.end(), i) != aSelectedRows.end())
|
||||
nActNumLvl |= nMask;
|
||||
m_nActNumLvl |= nMask;
|
||||
nMask <<= 1;
|
||||
}
|
||||
m_xLevelLB->unselect(pActNum->GetLevelCount());
|
||||
m_xLevelLB->unselect(m_pActNum->GetLevelCount());
|
||||
}
|
||||
else
|
||||
{
|
||||
nActNumLvl = nSaveNumLvl;
|
||||
m_nActNumLvl = nSaveNumLvl;
|
||||
sal_uInt16 nMask = 1;
|
||||
for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++ )
|
||||
for (sal_uInt16 i = 0; i < m_pActNum->GetLevelCount(); i++)
|
||||
{
|
||||
if(nActNumLvl & nMask)
|
||||
if (m_nActNumLvl & nMask)
|
||||
{
|
||||
m_xLevelLB->select(i);
|
||||
break;
|
||||
@@ -1770,15 +1774,15 @@ IMPL_LINK_NOARG(SvxNumOptionsTabPage, PreviewInvalidateHdl_Impl, Timer *, void)
|
||||
IMPL_LINK(SvxNumOptionsTabPage, AllLevelHdl_Impl, weld::SpinButton&, rBox, void)
|
||||
{
|
||||
sal_uInt16 nMask = 1;
|
||||
for(sal_uInt16 e = 0; e < pActNum->GetLevelCount(); e++)
|
||||
for (sal_uInt16 e = 0; e < m_pActNum->GetLevelCount(); e++)
|
||||
{
|
||||
if(nActNumLvl & nMask)
|
||||
if (m_nActNumLvl & nMask)
|
||||
{
|
||||
SvxNumberFormat aNumFmt(pActNum->GetLevel(e));
|
||||
SvxNumberFormat aNumFmt(m_pActNum->GetLevel(e));
|
||||
aNumFmt.SetIncludeUpperLevels(static_cast<sal_uInt8>(std::min(rBox.get_value(), sal_Int64(e + 1))) );
|
||||
// Set the same prefix/suffix to generate list format with changed IncludedUpperLevels
|
||||
aNumFmt.SetListFormat(aNumFmt.GetPrefix(), aNumFmt.GetSuffix(), e);
|
||||
pActNum->SetLevel(e, aNumFmt);
|
||||
m_pActNum->SetLevel(e, aNumFmt);
|
||||
}
|
||||
nMask <<= 1;
|
||||
}
|
||||
@@ -1788,13 +1792,13 @@ IMPL_LINK(SvxNumOptionsTabPage, AllLevelHdl_Impl, weld::SpinButton&, rBox, void)
|
||||
IMPL_LINK(SvxNumOptionsTabPage, IsLegalHdl_Impl, weld::Toggleable&, rBox, void)
|
||||
{
|
||||
bool bSet = rBox.get_active();
|
||||
for (sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
|
||||
for (sal_uInt16 i = 0; i < m_pActNum->GetLevelCount(); i++)
|
||||
{
|
||||
if (nActNumLvl & (sal_uInt16(1) << i))
|
||||
if (m_nActNumLvl & (sal_uInt16(1) << i))
|
||||
{
|
||||
SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
|
||||
SvxNumberFormat aNumFmt(m_pActNum->GetLevel(i));
|
||||
aNumFmt.SetIsLegal(bSet);
|
||||
pActNum->SetLevel(i, aNumFmt);
|
||||
m_pActNum->SetLevel(i, aNumFmt);
|
||||
}
|
||||
}
|
||||
SetModified();
|
||||
@@ -1806,11 +1810,11 @@ IMPL_LINK(SvxNumOptionsTabPage, NumberTypeSelectHdl_Impl, weld::ComboBox&, rBox,
|
||||
bool bShowOrient = false;
|
||||
bool bBmp = false;
|
||||
sal_uInt16 nMask = 1;
|
||||
for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
|
||||
for (sal_uInt16 i = 0; i < m_pActNum->GetLevelCount(); i++)
|
||||
{
|
||||
if(nActNumLvl & nMask)
|
||||
if (m_nActNumLvl & nMask)
|
||||
{
|
||||
SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
|
||||
SvxNumberFormat aNumFmt(m_pActNum->GetLevel(i));
|
||||
// PAGEDESC does not exist
|
||||
SvxNumType nNumType = static_cast<SvxNumType>(rBox.get_active_id().toUInt32());
|
||||
aNumFmt.SetNumberingType(nNumType);
|
||||
@@ -1822,7 +1826,7 @@ IMPL_LINK(SvxNumOptionsTabPage, NumberTypeSelectHdl_Impl, weld::ComboBox&, rBox,
|
||||
aNumFmt.SetListFormat(u""_ustr, u""_ustr, i);
|
||||
if(!bBmp)
|
||||
aNumFmt.SetGraphic(u""_ustr);
|
||||
pActNum->SetLevel(i, aNumFmt);
|
||||
m_pActNum->SetLevel(i, aNumFmt);
|
||||
SwitchNumberType(NumberType::SHOW_BITMAP);
|
||||
bShowOrient = true;
|
||||
}
|
||||
@@ -1831,13 +1835,13 @@ IMPL_LINK(SvxNumOptionsTabPage, NumberTypeSelectHdl_Impl, weld::ComboBox&, rBox,
|
||||
aNumFmt.SetIncludeUpperLevels( 1 );
|
||||
aNumFmt.SetListFormat(u""_ustr, u""_ustr, i);
|
||||
if( !aNumFmt.GetBulletFont() )
|
||||
aNumFmt.SetBulletFont(&aActBulletFont);
|
||||
aNumFmt.SetBulletFont(&m_aActBulletFont);
|
||||
if( !aNumFmt.GetBulletChar() )
|
||||
aNumFmt.SetBulletChar( SVX_DEF_BULLET );
|
||||
pActNum->SetLevel(i, aNumFmt);
|
||||
m_pActNum->SetLevel(i, aNumFmt);
|
||||
SwitchNumberType(NumberType::SHOW_BULLET);
|
||||
// allocation of the drawing pattern is automatic
|
||||
if(bAutomaticCharStyles)
|
||||
if (m_bAutomaticCharStyles)
|
||||
{
|
||||
sSelectStyle = m_sBulletCharFormatName;
|
||||
}
|
||||
@@ -1847,11 +1851,11 @@ IMPL_LINK(SvxNumOptionsTabPage, NumberTypeSelectHdl_Impl, weld::ComboBox&, rBox,
|
||||
aNumFmt.SetListFormat(m_xPrefixED->get_text(), m_xSuffixED->get_text(), i);
|
||||
|
||||
SwitchNumberType(NumberType::SHOW_NUMBERING);
|
||||
pActNum->SetLevel(i, aNumFmt);
|
||||
m_pActNum->SetLevel(i, aNumFmt);
|
||||
CheckForStartValue_Impl(nNumberingType);
|
||||
|
||||
// allocation of the drawing pattern is automatic
|
||||
if(bAutomaticCharStyles)
|
||||
if (m_bAutomaticCharStyles)
|
||||
{
|
||||
sSelectStyle = m_sNumCharFmtName;
|
||||
}
|
||||
@@ -1859,7 +1863,7 @@ IMPL_LINK(SvxNumOptionsTabPage, NumberTypeSelectHdl_Impl, weld::ComboBox&, rBox,
|
||||
}
|
||||
nMask <<= 1;
|
||||
}
|
||||
bool bAllLevelFeature = pActNum->IsFeatureSupported(SvxNumRuleFlags::CONTINUOUS);
|
||||
bool bAllLevelFeature = m_pActNum->IsFeatureSupported(SvxNumRuleFlags::CONTINUOUS);
|
||||
if(bShowOrient && bAllLevelFeature)
|
||||
{
|
||||
m_xOrientFT->show();
|
||||
@@ -1875,7 +1879,7 @@ IMPL_LINK(SvxNumOptionsTabPage, NumberTypeSelectHdl_Impl, weld::ComboBox&, rBox,
|
||||
{
|
||||
m_xCharFmtLB->set_active_text(sSelectStyle);
|
||||
CharFmtHdl_Impl(*m_xCharFmtLB);
|
||||
bAutomaticCharStyles = true;
|
||||
m_bAutomaticCharStyles = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1896,18 +1900,18 @@ IMPL_LINK(SvxNumOptionsTabPage, OrientHdl_Impl, weld::ComboBox&, rBox, void)
|
||||
nPos ++; // no VERT_NONE
|
||||
|
||||
sal_uInt16 nMask = 1;
|
||||
for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
|
||||
for (sal_uInt16 i = 0; i < m_pActNum->GetLevelCount(); i++)
|
||||
{
|
||||
if(nActNumLvl & nMask)
|
||||
if (m_nActNumLvl & nMask)
|
||||
{
|
||||
SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
|
||||
SvxNumberFormat aNumFmt(m_pActNum->GetLevel(i));
|
||||
if(SVX_NUM_BITMAP == (aNumFmt.GetNumberingType()&(~LINK_TOKEN)))
|
||||
{
|
||||
const SvxBrushItem* pBrushItem = aNumFmt.GetBrush();
|
||||
const Size& rSize = aNumFmt.GetGraphicSize();
|
||||
sal_Int16 eOrient = static_cast<sal_Int16>(nPos);
|
||||
aNumFmt.SetGraphicBrush( pBrushItem, &rSize, &eOrient );
|
||||
pActNum->SetLevel(i, aNumFmt);
|
||||
m_pActNum->SetLevel(i, aNumFmt);
|
||||
}
|
||||
}
|
||||
nMask <<= 1;
|
||||
@@ -1918,11 +1922,11 @@ IMPL_LINK(SvxNumOptionsTabPage, OrientHdl_Impl, weld::ComboBox&, rBox, void)
|
||||
IMPL_LINK(SvxNumOptionsTabPage, SameLevelHdl_Impl, weld::Toggleable&, rBox, void)
|
||||
{
|
||||
bool bSet = rBox.get_active();
|
||||
pActNum->SetContinuousNumbering(bSet);
|
||||
m_pActNum->SetContinuousNumbering(bSet);
|
||||
bool bRepaint = false;
|
||||
for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
|
||||
for (sal_uInt16 i = 0; i < m_pActNum->GetLevelCount(); i++)
|
||||
{
|
||||
SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
|
||||
SvxNumberFormat aNumFmt(m_pActNum->GetLevel(i));
|
||||
if(aNumFmt.GetNumberingType() != SVX_NUM_NUMBER_NONE)
|
||||
{
|
||||
bRepaint = true;
|
||||
@@ -1938,13 +1942,13 @@ IMPL_LINK(SvxNumOptionsTabPage, BulColorHdl_Impl, ColorListBox&, rColorBox, void
|
||||
Color nSetColor = rColorBox.GetSelectEntryColor();
|
||||
|
||||
sal_uInt16 nMask = 1;
|
||||
for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
|
||||
for (sal_uInt16 i = 0; i < m_pActNum->GetLevelCount(); i++)
|
||||
{
|
||||
if(nActNumLvl & nMask)
|
||||
if (m_nActNumLvl & nMask)
|
||||
{
|
||||
SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
|
||||
SvxNumberFormat aNumFmt(m_pActNum->GetLevel(i));
|
||||
aNumFmt.SetBulletColor(nSetColor);
|
||||
pActNum->SetLevel(i, aNumFmt);
|
||||
m_pActNum->SetLevel(i, aNumFmt);
|
||||
}
|
||||
nMask <<= 1;
|
||||
}
|
||||
@@ -1956,13 +1960,13 @@ IMPL_LINK(SvxNumOptionsTabPage, BulRelSizeHdl_Impl, weld::MetricSpinButton&, rFi
|
||||
sal_uInt16 nRelSize = o3tl::sanitizing_cast<sal_uInt16>(rField.get_value(FieldUnit::PERCENT));
|
||||
|
||||
sal_uInt16 nMask = 1;
|
||||
for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
|
||||
for (sal_uInt16 i = 0; i < m_pActNum->GetLevelCount(); i++)
|
||||
{
|
||||
if(nActNumLvl & nMask)
|
||||
if (m_nActNumLvl & nMask)
|
||||
{
|
||||
SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
|
||||
SvxNumberFormat aNumFmt(m_pActNum->GetLevel(i));
|
||||
aNumFmt.SetBulletRelSize(nRelSize);
|
||||
pActNum->SetLevel(i, aNumFmt);
|
||||
m_pActNum->SetLevel(i, aNumFmt);
|
||||
}
|
||||
nMask <<= 1;
|
||||
}
|
||||
@@ -1980,9 +1984,9 @@ IMPL_LINK(SvxNumOptionsTabPage, GraphicHdl_Impl, const OUString&, rIdent, void)
|
||||
if (rIdent.startsWith("gallery", &sNumber))
|
||||
{
|
||||
auto idx = o3tl::toUInt32(sNumber);
|
||||
if (idx < aGrfNames.size())
|
||||
if (idx < m_aGrfNames.size())
|
||||
{
|
||||
aGrfName = aGrfNames[idx];
|
||||
aGrfName = m_aGrfNames[idx];
|
||||
Graphic aGraphic;
|
||||
if(GalleryExplorer::GetGraphicObj( GALLERY_THEME_BULLETS, idx, &aGraphic))
|
||||
{
|
||||
@@ -2011,14 +2015,14 @@ IMPL_LINK(SvxNumOptionsTabPage, GraphicHdl_Impl, const OUString&, rIdent, void)
|
||||
if(!bSucc)
|
||||
return;
|
||||
|
||||
aSize = OutputDevice::LogicToLogic(aSize, MapMode(MapUnit::Map100thMM), MapMode(eCoreUnit));
|
||||
aSize = OutputDevice::LogicToLogic(aSize, MapMode(MapUnit::Map100thMM), MapMode(m_eCoreUnit));
|
||||
|
||||
sal_uInt16 nMask = 1;
|
||||
for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
|
||||
for (sal_uInt16 i = 0; i < m_pActNum->GetLevelCount(); i++)
|
||||
{
|
||||
if(nActNumLvl & nMask)
|
||||
if (m_nActNumLvl & nMask)
|
||||
{
|
||||
SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
|
||||
SvxNumberFormat aNumFmt(m_pActNum->GetLevel(i));
|
||||
aNumFmt.SetCharFormatName(m_sNumCharFmtName);
|
||||
aNumFmt.SetGraphic(aGrfName);
|
||||
|
||||
@@ -2027,9 +2031,9 @@ IMPL_LINK(SvxNumOptionsTabPage, GraphicHdl_Impl, const OUString&, rIdent, void)
|
||||
// initiate asynchronous loading
|
||||
sal_Int16 eOrient = aNumFmt.GetVertOrient();
|
||||
aNumFmt.SetGraphicBrush( pBrushItem, &aSize, &eOrient );
|
||||
aInitSize[i] = aNumFmt.GetGraphicSize();
|
||||
m_aInitSize[i] = aNumFmt.GetGraphicSize();
|
||||
|
||||
pActNum->SetLevel(i, aNumFmt);
|
||||
m_pActNum->SetLevel(i, aNumFmt);
|
||||
}
|
||||
nMask <<= 1;
|
||||
}
|
||||
@@ -2038,16 +2042,16 @@ IMPL_LINK(SvxNumOptionsTabPage, GraphicHdl_Impl, const OUString&, rIdent, void)
|
||||
m_xHeightFT->set_sensitive(true);
|
||||
m_xWidthMF->set_sensitive(true);
|
||||
m_xHeightMF->set_sensitive(true);
|
||||
SetMetricValue(*m_xWidthMF, aSize.Width(), eCoreUnit);
|
||||
SetMetricValue(*m_xHeightMF, aSize.Height(), eCoreUnit);
|
||||
SetMetricValue(*m_xWidthMF, aSize.Width(), m_eCoreUnit);
|
||||
SetMetricValue(*m_xHeightMF, aSize.Height(), m_eCoreUnit);
|
||||
m_xOrientFT->set_sensitive(true);
|
||||
m_xOrientLB->set_sensitive(true);
|
||||
SetModified();
|
||||
//needed due to asynchronous loading of graphics in the SvxBrushItem
|
||||
aInvalidateTimer.Start();
|
||||
m_aInvalidateTimer.Start();
|
||||
}
|
||||
|
||||
IMPL_LINK_NOARG(SvxNumOptionsTabPage, PopupActivateHdl_Impl, weld::Toggleable&, void)
|
||||
void SvxNumOptionsTabPage::CreateGalleryMenu()
|
||||
{
|
||||
if (m_xGalleryMenu)
|
||||
return;
|
||||
@@ -2055,7 +2059,7 @@ IMPL_LINK_NOARG(SvxNumOptionsTabPage, PopupActivateHdl_Impl, weld::Toggleable&,
|
||||
m_xGalleryMenu = m_xBuilder->weld_menu(u"gallerysubmenu"_ustr);
|
||||
weld::WaitObject aWait(GetFrameWeld());
|
||||
|
||||
if (!GalleryExplorer::FillObjList(GALLERY_THEME_BULLETS, aGrfNames))
|
||||
if (!GalleryExplorer::FillObjList(GALLERY_THEME_BULLETS, m_aGrfNames))
|
||||
return;
|
||||
|
||||
GalleryExplorer::BeginLocking(GALLERY_THEME_BULLETS);
|
||||
@@ -2064,7 +2068,7 @@ IMPL_LINK_NOARG(SvxNumOptionsTabPage, PopupActivateHdl_Impl, weld::Toggleable&,
|
||||
OUString sGrfName;
|
||||
ScopedVclPtrInstance< VirtualDevice > pVD;
|
||||
size_t i = 0;
|
||||
for (const auto & grfName : aGrfNames)
|
||||
for (const auto& grfName : m_aGrfNames)
|
||||
{
|
||||
sGrfName = grfName;
|
||||
OUString sItemId = "gallery" + OUString::number(i);
|
||||
@@ -2110,11 +2114,11 @@ IMPL_LINK_NOARG(SvxNumOptionsTabPage, BulletHdl_Impl, weld::Button&, void)
|
||||
bool bSameBullet = true;
|
||||
sal_UCS4 cBullet = 0;
|
||||
bool bFirst = true;
|
||||
for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
|
||||
for (sal_uInt16 i = 0; i < m_pActNum->GetLevelCount(); i++)
|
||||
{
|
||||
if(nActNumLvl & nMask)
|
||||
if (m_nActNumLvl & nMask)
|
||||
{
|
||||
const SvxNumberFormat& rCurFmt = pActNum->GetLevel(i);
|
||||
const SvxNumberFormat& rCurFmt = m_pActNum->GetLevel(i);
|
||||
if(bFirst)
|
||||
{
|
||||
cBullet = rCurFmt.GetBulletChar();
|
||||
@@ -2135,24 +2139,24 @@ IMPL_LINK_NOARG(SvxNumOptionsTabPage, BulletHdl_Impl, weld::Button&, void)
|
||||
if (pFmtFont)
|
||||
aMap.SetCharFont(*pFmtFont);
|
||||
else
|
||||
aMap.SetCharFont(aActBulletFont);
|
||||
aMap.SetCharFont(m_aActBulletFont);
|
||||
if (bSameBullet)
|
||||
aMap.SetChar(cBullet);
|
||||
if (aMap.run() != RET_OK)
|
||||
return;
|
||||
|
||||
// change Font Numrules
|
||||
aActBulletFont = aMap.GetCharFont();
|
||||
m_aActBulletFont = aMap.GetCharFont();
|
||||
|
||||
sal_uInt16 _nMask = 1;
|
||||
for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
|
||||
for (sal_uInt16 i = 0; i < m_pActNum->GetLevelCount(); i++)
|
||||
{
|
||||
if(nActNumLvl & _nMask)
|
||||
if (m_nActNumLvl & _nMask)
|
||||
{
|
||||
SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
|
||||
aNumFmt.SetBulletFont(&aActBulletFont);
|
||||
SvxNumberFormat aNumFmt(m_pActNum->GetLevel(i));
|
||||
aNumFmt.SetBulletFont(&m_aActBulletFont);
|
||||
aNumFmt.SetBulletChar(aMap.GetChar());
|
||||
pActNum->SetLevel(i, aNumFmt);
|
||||
m_pActNum->SetLevel(i, aNumFmt);
|
||||
}
|
||||
_nMask <<= 1;
|
||||
}
|
||||
@@ -2163,54 +2167,58 @@ IMPL_LINK_NOARG(SvxNumOptionsTabPage, BulletHdl_Impl, weld::Button&, void)
|
||||
IMPL_LINK( SvxNumOptionsTabPage, SizeHdl_Impl, weld::MetricSpinButton&, rField, void)
|
||||
{
|
||||
bool bWidth = &rField == m_xWidthMF.get();
|
||||
bLastWidthModified = bWidth;
|
||||
m_bLastWidthModified = bWidth;
|
||||
bool bRatio = m_xRatioCB->get_active();
|
||||
tools::Long nWidthVal = static_cast<tools::Long>(m_xWidthMF->denormalize(m_xWidthMF->get_value(FieldUnit::MM_100TH)));
|
||||
tools::Long nHeightVal = static_cast<tools::Long>(m_xHeightMF->denormalize(m_xHeightMF->get_value(FieldUnit::MM_100TH)));
|
||||
nWidthVal = OutputDevice::LogicToLogic( nWidthVal ,
|
||||
MapUnit::Map100thMM, eCoreUnit );
|
||||
nHeightVal = OutputDevice::LogicToLogic( nHeightVal,
|
||||
MapUnit::Map100thMM, eCoreUnit);
|
||||
nWidthVal = OutputDevice::LogicToLogic(nWidthVal, MapUnit::Map100thMM, m_eCoreUnit);
|
||||
nHeightVal = OutputDevice::LogicToLogic(nHeightVal, MapUnit::Map100thMM, m_eCoreUnit);
|
||||
double fSizeRatio;
|
||||
|
||||
bool bRepaint = false;
|
||||
sal_uInt16 nMask = 1;
|
||||
for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
|
||||
for (sal_uInt16 i = 0; i < m_pActNum->GetLevelCount(); i++)
|
||||
{
|
||||
if(nActNumLvl & nMask)
|
||||
if (m_nActNumLvl & nMask)
|
||||
{
|
||||
SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
|
||||
SvxNumberFormat aNumFmt(m_pActNum->GetLevel(i));
|
||||
if(SVX_NUM_BITMAP == (aNumFmt.GetNumberingType()&(~LINK_TOKEN)))
|
||||
{
|
||||
Size aSize(aNumFmt.GetGraphicSize() );
|
||||
Size aSaveSize(aSize);
|
||||
|
||||
if (aInitSize[i].Height())
|
||||
fSizeRatio = static_cast<double>(aInitSize[i].Width()) / static_cast<double>(aInitSize[i].Height());
|
||||
if (m_aInitSize[i].Height())
|
||||
fSizeRatio = static_cast<double>(m_aInitSize[i].Width())
|
||||
/ static_cast<double>(m_aInitSize[i].Height());
|
||||
else
|
||||
fSizeRatio = double(1);
|
||||
|
||||
if(bWidth)
|
||||
{
|
||||
tools::Long nDelta = nWidthVal - aInitSize[i].Width();
|
||||
tools::Long nDelta = nWidthVal - m_aInitSize[i].Width();
|
||||
aSize.setWidth( nWidthVal );
|
||||
if (bRatio)
|
||||
{
|
||||
aSize.setHeight( aInitSize[i].Height() + static_cast<tools::Long>(static_cast<double>(nDelta) / fSizeRatio) );
|
||||
m_xHeightMF->set_value(m_xHeightMF->normalize(
|
||||
OutputDevice::LogicToLogic( aSize.Height(), eCoreUnit, MapUnit::Map100thMM )),
|
||||
aSize.setHeight(
|
||||
m_aInitSize[i].Height()
|
||||
+ static_cast<tools::Long>(static_cast<double>(nDelta) / fSizeRatio));
|
||||
m_xHeightMF->set_value(
|
||||
m_xHeightMF->normalize(OutputDevice::LogicToLogic(
|
||||
aSize.Height(), m_eCoreUnit, MapUnit::Map100thMM)),
|
||||
FieldUnit::MM_100TH);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tools::Long nDelta = nHeightVal - aInitSize[i].Height();
|
||||
tools::Long nDelta = nHeightVal - m_aInitSize[i].Height();
|
||||
aSize.setHeight( nHeightVal );
|
||||
if (bRatio)
|
||||
{
|
||||
aSize.setWidth( aInitSize[i].Width() + static_cast<tools::Long>(static_cast<double>(nDelta) * fSizeRatio) );
|
||||
m_xWidthMF->set_value(m_xWidthMF->normalize(
|
||||
OutputDevice::LogicToLogic( aSize.Width(), eCoreUnit, MapUnit::Map100thMM )),
|
||||
aSize.setWidth(
|
||||
m_aInitSize[i].Width()
|
||||
+ static_cast<tools::Long>(static_cast<double>(nDelta) * fSizeRatio));
|
||||
m_xWidthMF->set_value(m_xWidthMF->normalize(OutputDevice::LogicToLogic(
|
||||
aSize.Width(), m_eCoreUnit, MapUnit::Map100thMM)),
|
||||
FieldUnit::MM_100TH);
|
||||
}
|
||||
}
|
||||
@@ -2219,7 +2227,7 @@ IMPL_LINK( SvxNumOptionsTabPage, SizeHdl_Impl, weld::MetricSpinButton&, rField,
|
||||
if(aSize != aSaveSize)
|
||||
bRepaint = true;
|
||||
aNumFmt.SetGraphicBrush( pBrushItem, &aSize, &eOrient );
|
||||
pActNum->SetLevel(i, aNumFmt);
|
||||
m_pActNum->SetLevel(i, aNumFmt);
|
||||
}
|
||||
}
|
||||
nMask <<= 1;
|
||||
@@ -2232,7 +2240,7 @@ IMPL_LINK(SvxNumOptionsTabPage, RatioHdl_Impl, weld::Toggleable&, rBox, void)
|
||||
m_xCbxScaleImg->set_from_icon_name(m_xRatioCB->get_active() ? RID_SVXBMP_LOCKED : RID_SVXBMP_UNLOCKED);
|
||||
if (rBox.get_active())
|
||||
{
|
||||
if (bLastWidthModified)
|
||||
if (m_bLastWidthModified)
|
||||
SizeHdl_Impl(*m_xWidthMF);
|
||||
else
|
||||
SizeHdl_Impl(*m_xHeightMF);
|
||||
@@ -2241,15 +2249,15 @@ IMPL_LINK(SvxNumOptionsTabPage, RatioHdl_Impl, weld::Toggleable&, rBox, void)
|
||||
|
||||
IMPL_LINK_NOARG(SvxNumOptionsTabPage, CharFmtHdl_Impl, weld::ComboBox&, void)
|
||||
{
|
||||
bAutomaticCharStyles = false;
|
||||
m_bAutomaticCharStyles = false;
|
||||
sal_Int32 nEntryPos = m_xCharFmtLB->get_active();
|
||||
OUString sEntry = m_xCharFmtLB->get_active_text();
|
||||
sal_uInt16 nMask = 1;
|
||||
for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
|
||||
for (sal_uInt16 i = 0; i < m_pActNum->GetLevelCount(); i++)
|
||||
{
|
||||
if(nActNumLvl & nMask)
|
||||
if (m_nActNumLvl & nMask)
|
||||
{
|
||||
SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
|
||||
SvxNumberFormat aNumFmt(m_pActNum->GetLevel(i));
|
||||
if( 0 == nEntryPos )
|
||||
aNumFmt.SetCharFormatName(u""_ustr);
|
||||
else
|
||||
@@ -2257,7 +2265,7 @@ IMPL_LINK_NOARG(SvxNumOptionsTabPage, CharFmtHdl_Impl, weld::ComboBox&, void)
|
||||
if(SVX_NUM_BITMAP != (aNumFmt.GetNumberingType()&(~LINK_TOKEN)))
|
||||
aNumFmt.SetCharFormatName(sEntry);
|
||||
}
|
||||
pActNum->SetLevel(i, aNumFmt);
|
||||
m_pActNum->SetLevel(i, aNumFmt);
|
||||
}
|
||||
nMask <<= 1;
|
||||
}
|
||||
@@ -2279,16 +2287,16 @@ void SvxNumOptionsTabPage::EditModifyHdl_Impl(const weld::TextWidget* pEdit)
|
||||
bool bPrefixSuffix = (pEdit == m_xPrefixED.get())|| (pEdit == m_xSuffixED.get());
|
||||
bool bStart = pEdit == m_xStartED.get();
|
||||
sal_uInt16 nMask = 1;
|
||||
for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
|
||||
for (sal_uInt16 i = 0; i < m_pActNum->GetLevelCount(); i++)
|
||||
{
|
||||
if(nActNumLvl & nMask)
|
||||
if (m_nActNumLvl & nMask)
|
||||
{
|
||||
SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
|
||||
SvxNumberFormat aNumFmt(m_pActNum->GetLevel(i));
|
||||
if (bPrefixSuffix)
|
||||
aNumFmt.SetListFormat(m_xPrefixED->get_text(), m_xSuffixED->get_text(), i);
|
||||
else if(bStart)
|
||||
aNumFmt.SetStart(m_xStartED->get_value());
|
||||
pActNum->SetLevel(i, aNumFmt);
|
||||
m_pActNum->SetLevel(i, aNumFmt);
|
||||
}
|
||||
nMask <<= 1;
|
||||
}
|
||||
@@ -3150,10 +3158,10 @@ void SvxNumPositionTabPage::SetModified()
|
||||
|
||||
void SvxNumOptionsTabPage::SetModified(bool bRepaint)
|
||||
{
|
||||
bModified = true;
|
||||
m_bModified = true;
|
||||
if (bRepaint)
|
||||
{
|
||||
m_aPreviewWIN.SetLevel(nActNumLvl);
|
||||
m_aPreviewWIN.SetLevel(m_nActNumLvl);
|
||||
m_aPreviewWIN.Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1299,6 +1299,7 @@ SvxParaAlignTabPage::SvxParaAlignTabPage(weld::Container* pPage, weld::DialogCon
|
||||
, m_xLabelLetterSpacing(m_xBuilder->weld_label(u"labelLetterSpacing"_ustr))
|
||||
, m_xLetterSpacingMinimum(m_xBuilder->weld_metric_spin_button(u"spin_LETTER_SPACING_MIN"_ustr, FieldUnit::PERCENT))
|
||||
, m_xLetterSpacingMaximum(m_xBuilder->weld_metric_spin_button(u"spin_LETTER_SPACING_MAX"_ustr, FieldUnit::PERCENT))
|
||||
, m_xCompoundBased(m_xBuilder->weld_check_button(u"checkCompoundBased"_ustr))
|
||||
, m_xLabelGlyphScaling(m_xBuilder->weld_label(u"labelGlyphScaling"_ustr))
|
||||
, m_xGlyphScalingMinimum(m_xBuilder->weld_metric_spin_button(u"spin_GLYPH_SCALING_MIN"_ustr, FieldUnit::PERCENT))
|
||||
, m_xGlyphScalingMaximum(m_xBuilder->weld_metric_spin_button(u"spin_GLYPH_SCALING_MAX"_ustr, FieldUnit::PERCENT))
|
||||
@@ -1409,6 +1410,7 @@ bool SvxParaAlignTabPage::FillItemSet( SfxItemSet* rOutSet )
|
||||
m_xParagraphComposer->get_state_changed_from_saved() ||
|
||||
m_xLetterSpacingMinimum->get_value_changed_from_saved() ||
|
||||
m_xLetterSpacingMaximum->get_value_changed_from_saved() ||
|
||||
m_xCompoundBased->get_state_changed_from_saved() ||
|
||||
m_xGlyphScalingMinimum->get_value_changed_from_saved() ||
|
||||
m_xGlyphScalingMaximum->get_value_changed_from_saved();
|
||||
}
|
||||
@@ -1436,6 +1438,7 @@ bool SvxParaAlignTabPage::FillItemSet( SfxItemSet* rOutSet )
|
||||
aAdj.SetParagraphComposer( m_xParagraphComposer->get_active() );
|
||||
aAdj.SetPropLetterSpacingMinimum( m_xLetterSpacingMinimum->get_value(FieldUnit::PERCENT) );
|
||||
aAdj.SetPropLetterSpacingMaximum( m_xLetterSpacingMaximum->get_value(FieldUnit::PERCENT) );
|
||||
aAdj.SetCompoundBased( m_xCompoundBased->get_active() );
|
||||
aAdj.SetPropScaleWidthMinimum( m_xGlyphScalingMinimum->get_value(FieldUnit::PERCENT) );
|
||||
aAdj.SetPropScaleWidthMaximum( m_xGlyphScalingMaximum->get_value(FieldUnit::PERCENT) );
|
||||
rOutSet->Put( aAdj );
|
||||
@@ -1543,6 +1546,8 @@ void SvxParaAlignTabPage::Reset( const SfxItemSet* rSet )
|
||||
m_xLetterSpacingMinimum->set_sensitive(true);
|
||||
m_xLetterSpacingMinimum->set_value(rAdj.GetPropLetterSpacingMinimum(), FieldUnit::PERCENT);
|
||||
m_xLetterSpacingMaximum->set_value(rAdj.GetPropLetterSpacingMaximum(), FieldUnit::PERCENT);
|
||||
m_xCompoundBased->set_sensitive(true);
|
||||
m_xCompoundBased->set_active(rAdj.GetCompoundBased());
|
||||
// TODO add GlyphScaling (CharScaleWidth)
|
||||
m_xGlyphScalingMaximum->set_sensitive(true);
|
||||
m_xGlyphScalingMinimum->set_sensitive(true);
|
||||
@@ -1559,10 +1564,10 @@ void SvxParaAlignTabPage::Reset( const SfxItemSet* rSet )
|
||||
m_xWordSpacingMinimum->set_sensitive(false);
|
||||
m_xWordSpacingMaximum->set_sensitive(false);
|
||||
m_xParagraphComposer->set_sensitive(false);
|
||||
m_xParagraphComposer->set_sensitive(false);
|
||||
m_xLabelLetterSpacing->set_sensitive(false);
|
||||
m_xLetterSpacingMinimum->set_sensitive(false);
|
||||
m_xLetterSpacingMaximum->set_sensitive(false);
|
||||
m_xCompoundBased->set_sensitive(false);
|
||||
m_xLabelGlyphScaling->set_sensitive(false);
|
||||
m_xGlyphScalingMinimum->set_sensitive(false);
|
||||
m_xGlyphScalingMaximum->set_sensitive(false);
|
||||
@@ -1664,6 +1669,7 @@ void SvxParaAlignTabPage::Reset( const SfxItemSet* rSet )
|
||||
m_xParagraphComposer->save_state();
|
||||
m_xLetterSpacingMinimum->save_value();
|
||||
m_xLetterSpacingMaximum->save_value();
|
||||
m_xCompoundBased->save_state();
|
||||
m_xGlyphScalingMinimum->save_value();
|
||||
m_xGlyphScalingMaximum->save_value();
|
||||
|
||||
@@ -1690,6 +1696,7 @@ void SvxParaAlignTabPage::ChangesApplied()
|
||||
m_xParagraphComposer->save_state();
|
||||
m_xLetterSpacingMinimum->save_value();
|
||||
m_xLetterSpacingMaximum->save_value();
|
||||
m_xCompoundBased->save_state();
|
||||
m_xGlyphScalingMinimum->save_value();
|
||||
m_xGlyphScalingMaximum->save_value();
|
||||
}
|
||||
@@ -1711,6 +1718,7 @@ IMPL_LINK_NOARG(SvxParaAlignTabPage, AlignHdl_Impl, weld::Toggleable&, void)
|
||||
// TODO visualize CharKerning with percentage
|
||||
m_xLetterSpacingMinimum->set_sensitive(bJustify);
|
||||
m_xLetterSpacingMaximum->set_sensitive(bJustify);
|
||||
m_xCompoundBased->set_sensitive(bJustify);
|
||||
m_xLabelGlyphScaling->set_sensitive(bJustify);
|
||||
// TODO visualize CharScaleWidth with percentage
|
||||
m_xGlyphScalingMinimum->set_sensitive(bJustify);
|
||||
|
||||
@@ -185,7 +185,7 @@ void SvxColorTabPage::ActivatePage( const SfxItemSet& )
|
||||
if (nSelectedIndex < 0)
|
||||
return;
|
||||
|
||||
ActivatePaletteColorHdl(m_aColorIconView.getColor(nSelectedIndex));
|
||||
ActivatePaletteColorHdl(nSelectedIndex);
|
||||
}
|
||||
|
||||
DeactivateRC SvxColorTabPage::DeactivatePage( SfxItemSet* _pSet )
|
||||
@@ -388,7 +388,7 @@ IMPL_LINK_NOARG(SvxColorTabPage, ClickDeleteHdl_Impl, weld::Button&, void)
|
||||
if (m_aColorIconView.getItemCount() > 0)
|
||||
{
|
||||
m_aColorIconView.select(0);
|
||||
ActivatePaletteColorHdl(m_aColorIconView.getColor(0));
|
||||
ActivatePaletteColorHdl(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -481,20 +481,16 @@ void SvxColorTabPage::UpdateToSelectedColor(const NamedColor& rNamedColor)
|
||||
ChangeColor(rNamedColor, false);
|
||||
}
|
||||
|
||||
IMPL_LINK(SvxColorTabPage, ActivatePaletteColorHdl, const Color&, rColor, void)
|
||||
IMPL_LINK(SvxColorTabPage, ActivatePaletteColorHdl, int, nIndex, void)
|
||||
{
|
||||
const int nPos = m_aColorIconView.get_selected_index();
|
||||
if (nPos < 0 || m_aColorIconView.getColor(nPos) != rColor)
|
||||
return;
|
||||
|
||||
NamedColor aNamedColor;
|
||||
aNamedColor.m_aColor = rColor;
|
||||
aNamedColor.m_aColor = m_aColorIconView.getColor(nIndex);
|
||||
|
||||
if (maPaletteManager.IsThemePaletteSelected())
|
||||
{
|
||||
sal_uInt16 nThemeIndex;
|
||||
sal_uInt16 nEffectIndex;
|
||||
if (PaletteManager::GetThemeAndEffectIndex(nPos, nThemeIndex, nEffectIndex))
|
||||
if (PaletteManager::GetThemeAndEffectIndex(nIndex, nThemeIndex, nEffectIndex))
|
||||
{
|
||||
aNamedColor.m_nThemeIndex = nThemeIndex;
|
||||
maPaletteManager.GetLumModOff(nThemeIndex, nEffectIndex, aNamedColor.m_nLumMod, aNamedColor.m_nLumOff);
|
||||
@@ -516,10 +512,10 @@ IMPL_LINK(SvxColorTabPage, ActivatePaletteColorHdl, const Color&, rColor, void)
|
||||
}
|
||||
}
|
||||
|
||||
IMPL_LINK(SvxColorTabPage, ActivateRecentColorHdl, const Color&, rColor, void)
|
||||
IMPL_LINK(SvxColorTabPage, ActivateRecentColorHdl, int, nIndex, void)
|
||||
{
|
||||
NamedColor aNamedColor;
|
||||
aNamedColor.m_aColor = rColor;
|
||||
aNamedColor.m_aColor = m_aRecentIconView.getColor(nIndex);
|
||||
|
||||
UpdateToSelectedColor(aNamedColor);
|
||||
|
||||
|
||||
@@ -167,7 +167,10 @@
|
||||
<property name="model">coloriconviewmodel</property>
|
||||
<property name="columns">12</property>
|
||||
<property name="pixbuf-column">0</property>
|
||||
<property name="row-spacing">0</property>
|
||||
<property name="column-spacing">0</property>
|
||||
<property name="tooltip-column">2</property>
|
||||
<property name="item-padding">2</property>
|
||||
<property name="activate-on-single-click">True</property>
|
||||
</object>
|
||||
</child>
|
||||
@@ -214,7 +217,10 @@
|
||||
<property name="model">recentcoloriconviewmodel</property>
|
||||
<property name="columns">12</property>
|
||||
<property name="pixbuf-column">0</property>
|
||||
<property name="row-spacing">0</property>
|
||||
<property name="column-spacing">0</property>
|
||||
<property name="tooltip-column">2</property>
|
||||
<property name="item-padding">2</property>
|
||||
<property name="activate-on-single-click">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
|
||||
@@ -164,7 +164,7 @@
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="label" translatable="yes" context="numberingoptionspage|label4">Number:</property>
|
||||
<property name="label" translatable="yes" context="numberingoptionspage|label4">Type:</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="mnemonic-widget">numfmtlb</property>
|
||||
<property name="xalign">0</property>
|
||||
@@ -180,7 +180,7 @@
|
||||
<property name="can-focus">False</property>
|
||||
<child internal-child="accessible">
|
||||
<object class="AtkObject" id="numfmtlb-atkobject">
|
||||
<property name="AtkObject::accessible-description" translatable="yes" context="numberingoptionspage|extended_tip|numfmtlb">Select a numbering scheme for the selected levels.</property>
|
||||
<property name="AtkObject::accessible-description" translatable="yes" context="numberingoptionspage|extended_tip|numfmtlb">Select a numbering scheme or a bullet for the selected levels.</property>
|
||||
</object>
|
||||
</child>
|
||||
<style>
|
||||
@@ -754,7 +754,7 @@
|
||||
<object class="GtkLabel" id="label2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes" context="numberingoptionspage|label2">Numbering</property>
|
||||
<property name="label" translatable="yes" context="numberingoptionspage|label2">List Format</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
|
||||
@@ -210,7 +210,10 @@
|
||||
<property name="model">tableiconview_model</property>
|
||||
<property name="columns">12</property>
|
||||
<property name="pixbuf-column">0</property>
|
||||
<property name="row-spacing">0</property>
|
||||
<property name="column-spacing">0</property>
|
||||
<property name="tooltip-column">2</property>
|
||||
<property name="item-padding">2</property>
|
||||
<property name="activate-on-single-click">True</property>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
@@ -740,6 +740,26 @@
|
||||
<property name="top-attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="checkCompoundBased">
|
||||
<property name="label" translatable="yes" context="paralignpage|checkCompoundBased">Split compound words</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">False</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="inconsistent">True</property>
|
||||
<property name="draw-indicator">True</property>
|
||||
<child internal-child="accessible">
|
||||
<object class="AtkObject" id="checkCompoundBased-atkobject">
|
||||
<property name="AtkObject::accessible-description" translatable="yes" context="textflowpage|extended_tip|checkCompoundBased">Select this check box, if you want to prefer compound word splitting during justification.</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">4</property>
|
||||
<property name="top-attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="labelGlyphScaling">
|
||||
<property name="visible">True</property>
|
||||
|
||||
@@ -23,6 +23,7 @@ $(eval $(call gb_CppunitTest_use_libraries,dbaccess_firebird_test, \
|
||||
cppu \
|
||||
cppuhelper \
|
||||
dbaxml \
|
||||
dbtools \
|
||||
firebird_sdbc \
|
||||
sal \
|
||||
subsequenttest \
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*-
|
||||
#
|
||||
# This file is part of the LibreOffice project.
|
||||
#
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
#
|
||||
from uitest.framework import UITestCase
|
||||
from uitest.uihelper.common import get_url_for_data_file, select_pos
|
||||
|
||||
from libreoffice.uno.propertyvalue import mkPropertyValues
|
||||
|
||||
# Bug 173673 - Tablefilter: Resetting impossible when "Apply Filter" is unchecked
|
||||
class tdf173673(UITestCase):
|
||||
def test_tdf173673(self):
|
||||
with self.ui_test.load_file(get_url_for_data_file("tdf75509.odb")) as document:
|
||||
xConnection = document.DataSource.getConnection("", "")
|
||||
xStatement = xConnection.createStatement()
|
||||
xStatement.executeUpdate('INSERT INTO "Table1" ("FrenchField", "EnglishField") VALUES (1, 1)')
|
||||
xStatement.executeUpdate('INSERT INTO "Table1" ("FrenchField", "EnglishField") VALUES (2, 2)')
|
||||
xConnection.close()
|
||||
|
||||
self.xUITest.executeCommand(".uno:DBViewTables")
|
||||
xToolkit = self.xContext.ServiceManager.createInstance('com.sun.star.awt.Toolkit')
|
||||
xToolkit.waitUntilAllIdlesDispatched()
|
||||
self.xUITest.executeCommand(".uno:SelectAll")
|
||||
|
||||
with self.ui_test.open_subcomponent_through_command(".uno:DBTableOpen") as xTableFrame:
|
||||
xTableWindow = self.xUITest.getWindow(xTableFrame.getContainerWindow())
|
||||
xGrid = xTableWindow.getChild("DBGrid")
|
||||
xForm = xTableFrame.getController().CurrentControl.getModel().getParent()
|
||||
|
||||
self.assertEqual(2, xForm.RowCount)
|
||||
|
||||
# AutoFilter on the first row's FrenchField cell (value 1)
|
||||
xGrid.executeAction("FOCUS", tuple())
|
||||
xGrid.executeAction("TYPE", mkPropertyValues({"KEYCODE": "TAB"}))
|
||||
self.xUITest.executeCommandForProvider(".uno:AutoFilter", xTableFrame)
|
||||
xToolkit.waitUntilAllIdlesDispatched()
|
||||
self.assertNotEqual("", xForm.Filter)
|
||||
self.assertTrue(xForm.ApplyFilter)
|
||||
self.assertEqual(1, xForm.RowCount)
|
||||
|
||||
# Uncheck "Apply Filter": the filter is kept, but no longer applied
|
||||
self.xUITest.executeCommandForProvider(".uno:FormFiltered", xTableFrame)
|
||||
xToolkit.waitUntilAllIdlesDispatched()
|
||||
self.assertNotEqual("", xForm.Filter)
|
||||
self.assertFalse(xForm.ApplyFilter)
|
||||
self.assertEqual(2, xForm.RowCount)
|
||||
|
||||
# Clear the condition in the Standard Filter dialog
|
||||
with self.ui_test.execute_blocking_action(
|
||||
self.xUITest.executeCommandForProvider,
|
||||
args=(".uno:FilterCrit", xTableFrame)) as xDialog:
|
||||
xDialog.getChild("field1").executeAction("SELECT", mkPropertyValues({"TEXT": "- none -"}))
|
||||
xToolkit.waitUntilAllIdlesDispatched()
|
||||
|
||||
# Check that the old filter is removed
|
||||
self.assertEqual("", xForm.Filter)
|
||||
self.assertEqual(2, xForm.RowCount)
|
||||
|
||||
# vim: set shiftwidth=4 softtabstop=4 expandtab:
|
||||
@@ -9,7 +9,13 @@
|
||||
|
||||
#include "dbtest_base.cxx"
|
||||
|
||||
#include <com/sun/star/beans/PropertyValue.hpp>
|
||||
#include <com/sun/star/beans/XPropertySet.hpp>
|
||||
#include <com/sun/star/container/XNameAccess.hpp>
|
||||
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
|
||||
#include <com/sun/star/sdb/SQLFilterOperator.hpp>
|
||||
#include <com/sun/star/sdb/XOfficeDatabaseDocument.hpp>
|
||||
#include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp>
|
||||
#include <com/sun/star/sdbc/XColumnLocate.hpp>
|
||||
#include <com/sun/star/sdbc/XConnection.hpp>
|
||||
#include <com/sun/star/sdbc/XParameters.hpp>
|
||||
@@ -17,6 +23,10 @@
|
||||
#include <com/sun/star/sdbc/XResultSet.hpp>
|
||||
#include <com/sun/star/sdbc/XRow.hpp>
|
||||
#include <com/sun/star/sdbc/XStatement.hpp>
|
||||
#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
|
||||
#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
|
||||
#include <com/sun/star/util/XRefreshable.hpp>
|
||||
#include <connectivity/predicateinput.hxx>
|
||||
|
||||
using namespace ::com::sun::star;
|
||||
using namespace ::com::sun::star::sdb;
|
||||
@@ -31,12 +41,18 @@ public:
|
||||
void testIntegerDatabase();
|
||||
void testTdf132924();
|
||||
void testTdf153057();
|
||||
void testTdf153057_RangeFilter();
|
||||
void testTdf153057_FractionalFilter();
|
||||
void testTdf173589_TableStandardFilter();
|
||||
|
||||
CPPUNIT_TEST_SUITE(FirebirdTest);
|
||||
CPPUNIT_TEST(testEmptyDBConnection);
|
||||
CPPUNIT_TEST(testIntegerDatabase);
|
||||
CPPUNIT_TEST(testTdf132924);
|
||||
CPPUNIT_TEST(testTdf153057);
|
||||
CPPUNIT_TEST(testTdf153057_RangeFilter);
|
||||
CPPUNIT_TEST(testTdf153057_FractionalFilter);
|
||||
CPPUNIT_TEST(testTdf173589_TableStandardFilter);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
};
|
||||
|
||||
@@ -194,6 +210,177 @@ void FirebirdTest::testTdf153057()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for tdf#153057: a range filter on a TIME column built via
|
||||
* XSingleSelectQueryComposer::setStructuredFilter(). This exercises
|
||||
* OPredicateInputController -> OSQLParser::buildDate() ->
|
||||
* DBTypeConversion::toTimeString(), a different code path from
|
||||
* testTdf153057()'s setString() test above. Before the fix,
|
||||
* a whole-second TIME value got ".000000000" into
|
||||
* the generated SQL, which Firebird rejects.
|
||||
*/
|
||||
void FirebirdTest::testTdf153057_RangeFilter()
|
||||
{
|
||||
createTempCopy(u"firebird_empty.odb");
|
||||
uno::Reference<XOfficeDatabaseDocument> xDocument = getDocumentForUrl(maTempFile.GetURL());
|
||||
uno::Reference<XConnection> xConnection = getConnectionForDocument(xDocument);
|
||||
CPPUNIT_ASSERT(xConnection.is());
|
||||
|
||||
uno::Reference<XStatement> xStmt = xConnection->createStatement();
|
||||
xStmt->execute(u"CREATE TABLE \"DURATIONS\" ("
|
||||
" \"ID\" INTEGER NOT NULL PRIMARY KEY,"
|
||||
" \"T\" TIME)"_ustr);
|
||||
xStmt->execute(u"INSERT INTO \"DURATIONS\" VALUES(1, '00:01:00')"_ustr);
|
||||
xStmt->execute(u"INSERT INTO \"DURATIONS\" VALUES(2, '00:03:00')"_ustr);
|
||||
xStmt->execute(u"INSERT INTO \"DURATIONS\" VALUES(3, '00:05:00')"_ustr);
|
||||
xConnection->commit();
|
||||
|
||||
// A table created directly via SQL isn't visible to the connection's
|
||||
// cached table container until it's explicitly refreshed (matches the
|
||||
// "Refresh Tables" UI command). Without this, the composer below can't
|
||||
// resolve "T" as a typed select column and silently falls back to an
|
||||
// untyped/unquoted filter-value path.
|
||||
uno::Reference<sdbcx::XTablesSupplier> xTablesSupplier(xConnection, UNO_QUERY_THROW);
|
||||
uno::Reference<util::XRefreshable> xTablesRefresh(xTablesSupplier->getTables(), UNO_QUERY_THROW);
|
||||
xTablesRefresh->refresh();
|
||||
|
||||
uno::Reference<lang::XMultiServiceFactory> xFactory(xConnection, UNO_QUERY_THROW);
|
||||
uno::Reference<XSingleSelectQueryComposer> xComposer(
|
||||
xFactory->createInstance(u"com.sun.star.sdb.SingleSelectQueryComposer"_ustr),
|
||||
UNO_QUERY_THROW);
|
||||
xComposer->setQuery(u"SELECT \"ID\", \"T\" FROM \"DURATIONS\""_ustr);
|
||||
|
||||
beans::PropertyValue aLower, aUpper;
|
||||
aLower.Name = u"\"T\""_ustr;
|
||||
aLower.Handle = SQLFilterOperator::GREATER_EQUAL;
|
||||
aLower.Value <<= u"00:02:00"_ustr;
|
||||
aUpper.Name = u"\"T\""_ustr;
|
||||
aUpper.Handle = SQLFilterOperator::LESS_EQUAL;
|
||||
aUpper.Value <<= u"00:04:00"_ustr;
|
||||
|
||||
Sequence<Sequence<beans::PropertyValue>> aFilter{ { aLower, aUpper } };
|
||||
|
||||
// Before the fix: SQLException "conversion error from string ..." here,
|
||||
// because the generated literal was "... AND \"T\" <= '00:04:00.000000000'".
|
||||
xComposer->setStructuredFilter(aFilter);
|
||||
|
||||
uno::Reference<XStatement> xQueryStmt = xConnection->createStatement();
|
||||
uno::Reference<XResultSet> xRS = xQueryStmt->executeQuery(xComposer->getQuery());
|
||||
uno::Reference<XRow> xRow(xRS, UNO_QUERY_THROW);
|
||||
|
||||
CPPUNIT_ASSERT_MESSAGE("range filter: expected a row", xRS->next());
|
||||
CPPUNIT_ASSERT_EQUAL_MESSAGE("range filter: wrong row returned", sal_Int32(2), xRow->getInt(1));
|
||||
CPPUNIT_ASSERT_MESSAGE("range filter: expected exactly one row", !xRS->next());
|
||||
}
|
||||
|
||||
/**
|
||||
* Regression test for a fractional-seconds TIME filter, distinct from
|
||||
* testTdf153057_RangeFilter() above.
|
||||
*/
|
||||
void FirebirdTest::testTdf153057_FractionalFilter()
|
||||
{
|
||||
createTempCopy(u"firebird_empty.odb");
|
||||
uno::Reference<XOfficeDatabaseDocument> xDocument = getDocumentForUrl(maTempFile.GetURL());
|
||||
uno::Reference<XConnection> xConnection = getConnectionForDocument(xDocument);
|
||||
CPPUNIT_ASSERT(xConnection.is());
|
||||
|
||||
uno::Reference<XStatement> xStmt = xConnection->createStatement();
|
||||
xStmt->execute(u"CREATE TABLE \"DURATIONS2\" ("
|
||||
" \"ID\" INTEGER NOT NULL PRIMARY KEY,"
|
||||
" \"T\" TIME)"_ustr);
|
||||
xStmt->execute(u"INSERT INTO \"DURATIONS2\" VALUES(1, '00:01:00')"_ustr);
|
||||
xStmt->execute(u"INSERT INTO \"DURATIONS2\" VALUES(2, '00:03:00.1235')"_ustr);
|
||||
xStmt->execute(u"INSERT INTO \"DURATIONS2\" VALUES(3, '00:05:00')"_ustr);
|
||||
xConnection->commit();
|
||||
|
||||
uno::Reference<sdbcx::XTablesSupplier> xTablesSupplier(xConnection, UNO_QUERY_THROW);
|
||||
uno::Reference<util::XRefreshable> xTablesRefresh(xTablesSupplier->getTables(), UNO_QUERY_THROW);
|
||||
xTablesRefresh->refresh();
|
||||
|
||||
uno::Reference<lang::XMultiServiceFactory> xFactory(xConnection, UNO_QUERY_THROW);
|
||||
uno::Reference<XSingleSelectQueryComposer> xComposer(
|
||||
xFactory->createInstance(u"com.sun.star.sdb.SingleSelectQueryComposer"_ustr),
|
||||
UNO_QUERY_THROW);
|
||||
xComposer->setQuery(u"SELECT \"ID\", \"T\" FROM \"DURATIONS2\""_ustr);
|
||||
|
||||
// A value with genuine sub-decisecond precision (6 significant fractional
|
||||
// digits) should be rounded to 4 digits for Firebird
|
||||
beans::PropertyValue aEquals;
|
||||
aEquals.Name = u"\"T\""_ustr;
|
||||
aEquals.Handle = SQLFilterOperator::EQUAL;
|
||||
aEquals.Value <<= u"00:03:00.123456"_ustr;
|
||||
|
||||
Sequence<Sequence<beans::PropertyValue>> aFilter{ { aEquals } };
|
||||
|
||||
xComposer->setStructuredFilter(aFilter);
|
||||
|
||||
uno::Reference<XStatement> xQueryStmt = xConnection->createStatement();
|
||||
uno::Reference<XResultSet> xRS = xQueryStmt->executeQuery(xComposer->getQuery());
|
||||
uno::Reference<XRow> xRow(xRS, UNO_QUERY_THROW);
|
||||
|
||||
CPPUNIT_ASSERT_MESSAGE("fractional filter: expected a row", xRS->next());
|
||||
CPPUNIT_ASSERT_EQUAL_MESSAGE("fractional filter: wrong row returned", sal_Int32(2), xRow->getInt(1));
|
||||
CPPUNIT_ASSERT_MESSAGE("fractional filter: expected exactly one row", !xRS->next());
|
||||
}
|
||||
|
||||
/**
|
||||
* Regression test for tdf#173589: filtering a TIME column via the Standard
|
||||
* Filter dialog on a raw table (Table Data View) returned an
|
||||
* empty result.
|
||||
*/
|
||||
void FirebirdTest::testTdf173589_TableStandardFilter()
|
||||
{
|
||||
createTempCopy(u"firebird_empty.odb");
|
||||
uno::Reference<XOfficeDatabaseDocument> xDocument = getDocumentForUrl(maTempFile.GetURL());
|
||||
uno::Reference<XConnection> xConnection = getConnectionForDocument(xDocument);
|
||||
CPPUNIT_ASSERT(xConnection.is());
|
||||
|
||||
uno::Reference<XStatement> xStmt = xConnection->createStatement();
|
||||
xStmt->execute(u"CREATE TABLE \"TITLES\" ("
|
||||
" \"ID\" INTEGER NOT NULL PRIMARY KEY,"
|
||||
" \"Duration\" TIME)"_ustr);
|
||||
xStmt->execute(u"INSERT INTO \"TITLES\" VALUES(1, '00:01:00')"_ustr);
|
||||
xStmt->execute(u"INSERT INTO \"TITLES\" VALUES(2, '00:05:00')"_ustr);
|
||||
xStmt->execute(u"INSERT INTO \"TITLES\" VALUES(3, '00:09:00')"_ustr);
|
||||
xConnection->commit();
|
||||
|
||||
uno::Reference<sdbcx::XTablesSupplier> xTablesSupplier(xConnection, UNO_QUERY_THROW);
|
||||
uno::Reference<util::XRefreshable> xTablesRefresh(xTablesSupplier->getTables(), UNO_QUERY_THROW);
|
||||
xTablesRefresh->refresh();
|
||||
|
||||
uno::Reference<lang::XMultiServiceFactory> xFactory(xConnection, UNO_QUERY_THROW);
|
||||
uno::Reference<XSingleSelectQueryComposer> xComposer(
|
||||
xFactory->createInstance(u"com.sun.star.sdb.SingleSelectQueryComposer"_ustr),
|
||||
UNO_QUERY_THROW);
|
||||
xComposer->setQuery(u"SELECT \"ID\", \"Duration\" FROM \"TITLES\""_ustr);
|
||||
|
||||
uno::Reference<container::XNameAccess> xColumns(
|
||||
uno::Reference<sdbcx::XColumnsSupplier>(xComposer, UNO_QUERY_THROW)->getColumns());
|
||||
uno::Reference<beans::XPropertySet> xColumn(xColumns->getByName(u"Duration"_ustr), UNO_QUERY_THROW);
|
||||
|
||||
::dbtools::OPredicateInputController aPredicateInput(getComponentContext(), xConnection);
|
||||
OUString sPredicateValue;
|
||||
aPredicateInput.getPredicateValue(u"00:05:00"_ustr, xColumn) >>= sPredicateValue;
|
||||
CPPUNIT_ASSERT_MESSAGE("tdf173589: predicate value must not be empty", !sPredicateValue.isEmpty());
|
||||
|
||||
beans::PropertyValue aFilter;
|
||||
aFilter.Name = u"\"Duration\""_ustr;
|
||||
aFilter.Handle = SQLFilterOperator::LESS;
|
||||
aFilter.Value <<= sPredicateValue;
|
||||
|
||||
Sequence<Sequence<beans::PropertyValue>> aFilterSeq{ { aFilter } };
|
||||
|
||||
xComposer->setStructuredFilter(aFilterSeq);
|
||||
|
||||
uno::Reference<XStatement> xQueryStmt = xConnection->createStatement();
|
||||
uno::Reference<XResultSet> xRS = xQueryStmt->executeQuery(xComposer->getQuery());
|
||||
uno::Reference<XRow> xRow(xRS, UNO_QUERY_THROW);
|
||||
|
||||
CPPUNIT_ASSERT_MESSAGE("tdf173589: expected a row", xRS->next());
|
||||
CPPUNIT_ASSERT_EQUAL_MESSAGE("tdf173589: wrong row returned", sal_Int32(1), xRow->getInt(1));
|
||||
CPPUNIT_ASSERT_MESSAGE("tdf173589: expected exactly one row", !xRS->next());
|
||||
}
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(FirebirdTest);
|
||||
|
||||
CPPUNIT_PLUGIN_IMPLEMENT();
|
||||
|
||||
@@ -1689,7 +1689,7 @@ void OSingleSelectQueryComposer::setConditionByColumn( const Reference< XPropert
|
||||
case DataType::VARCHAR:
|
||||
case DataType::CHAR:
|
||||
case DataType::LONGVARCHAR:
|
||||
aSQL.append( DBTypeConversion::toSQLString( nType, aValue, m_xTypeConverter ) );
|
||||
aSQL.append( DBTypeConversion::toSQLString( nType, aValue, m_xTypeConverter, m_xConnection ) );
|
||||
break;
|
||||
case DataType::CLOB:
|
||||
{
|
||||
@@ -1704,7 +1704,7 @@ void OSingleSelectQueryComposer::setConditionByColumn( const Reference< XPropert
|
||||
}
|
||||
else
|
||||
{
|
||||
aSQL.append( DBTypeConversion::toSQLString( nType, aValue, m_xTypeConverter ) );
|
||||
aSQL.append( DBTypeConversion::toSQLString( nType, aValue, m_xTypeConverter, m_xConnection ) );
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1737,7 +1737,7 @@ void OSingleSelectQueryComposer::setConditionByColumn( const Reference< XPropert
|
||||
}
|
||||
break;
|
||||
default:
|
||||
aSQL.append( DBTypeConversion::toSQLString( nType, aValue, m_xTypeConverter ) );
|
||||
aSQL.append( DBTypeConversion::toSQLString( nType, aValue, m_xTypeConverter, m_xConnection ) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1361,8 +1361,14 @@ FeatureState SbaXDataBrowserController::GetState(sal_uInt16 nId) const
|
||||
aReturn.bEnabled = false;
|
||||
return aReturn;
|
||||
}
|
||||
{
|
||||
Reference< XPropertySet > xFormSet(getRowSet(), UNO_QUERY);
|
||||
OUString sFilter, sHaving;
|
||||
xFormSet->getPropertyValue(PROPERTY_FILTER) >>= sFilter;
|
||||
xFormSet->getPropertyValue(PROPERTY_HAVING_CLAUSE) >>= sHaving;
|
||||
// any filter or sort order set ?
|
||||
aReturn.bEnabled = m_xParser->getFilter().getLength() || m_xParser->getHavingClause().getLength() || m_xParser->getOrder().getLength();
|
||||
aReturn.bEnabled = !sFilter.isEmpty() || !sHaving.isEmpty() || m_xParser->getOrder().getLength();
|
||||
}
|
||||
return aReturn;
|
||||
}
|
||||
// no chance without valid models
|
||||
@@ -1705,8 +1711,16 @@ void SbaXDataBrowserController::ExecuteFilterSortCrit(bool bFilter)
|
||||
|
||||
Reference< XPropertySet > xFormSet(getRowSet(), UNO_QUERY);
|
||||
|
||||
const OUString sOldVal = bFilter ? m_xParser->getFilter() : m_xParser->getOrder();
|
||||
const OUString sOldHaving = m_xParser->getHavingClause();
|
||||
OUString sOldVal, sOldHaving;
|
||||
if (bFilter)
|
||||
{
|
||||
xFormSet->getPropertyValue(PROPERTY_FILTER) >>= sOldVal;
|
||||
xFormSet->getPropertyValue(PROPERTY_HAVING_CLAUSE) >>= sOldHaving;
|
||||
}
|
||||
else
|
||||
{
|
||||
sOldVal = m_xParser->getOrder();
|
||||
}
|
||||
Reference< XSingleSelectQueryComposer > xParser = createParser_nothrow();
|
||||
try
|
||||
{
|
||||
|
||||
@@ -2968,7 +2968,8 @@ std::unique_ptr<OSQLParseNode> OQueryDesignView::getPredicateTreeFromEntry(const
|
||||
_sCriteria,
|
||||
static_cast<OQueryController&>(getController()).getNumberFormatter(),
|
||||
_rxColumn,
|
||||
false);
|
||||
false,
|
||||
static_cast<OQueryController&>(getController()).getConnection());
|
||||
return pParseNode;
|
||||
}
|
||||
|
||||
|
||||
@@ -1145,7 +1145,9 @@ bool OSelectionBrowseBox::SaveModified()
|
||||
pParseNode = rParser.predicateTree(aErrorMsg,
|
||||
aText,
|
||||
static_cast<OQueryController&>(getDesignView()->getController()).getNumberFormatter(),
|
||||
xColumn);
|
||||
xColumn,
|
||||
/*bUseRealName*/true,
|
||||
static_cast<OQueryController&>(getDesignView()->getController()).getConnection());
|
||||
if (pParseNode)
|
||||
{
|
||||
pParseNode->parseNodeToPredicateStr(aCrit,
|
||||
|
||||
+17
-22
@@ -44,8 +44,8 @@ BZIP2_TARBALL := bzip2-1.0.8.tar.gz
|
||||
# three static lines
|
||||
# so that git cherry-pick
|
||||
# will not run into conflicts
|
||||
CAIRO_SHA256SUM := 445ed8208a6e4823de1226a74ca319d3600e83f6369f99b14265006599c32ccb
|
||||
CAIRO_VERSION_MICRO := 4
|
||||
CAIRO_SHA256SUM := 1c767308174337a74694da0f3ec069c271452163a1ef4540964c50c301f157d4
|
||||
CAIRO_VERSION_MICRO := 6
|
||||
CAIRO_TARBALL := cairo-1.18.$(CAIRO_VERSION_MICRO).tar.xz
|
||||
# three static lines
|
||||
# so that git cherry-pick
|
||||
@@ -116,13 +116,13 @@ ETONYEK_TARBALL := libetonyek-0.1.$(ETONYEK_VERSION_MICRO).tar.xz
|
||||
# three static lines
|
||||
# so that git cherry-pick
|
||||
# will not run into conflicts
|
||||
EXPAT_SHA256SUM := 656ae1cc8da3b4ea513bb4e254f33e6243938084c0ec6239da873376b09985a7
|
||||
EXPAT_TARBALL := expat-2.8.4.tar.xz
|
||||
EXPAT_SHA256SUM := 1e727b8933ec51a77a9a9d9afcf8e688bce45d907c13e36ab7393fe36e703182
|
||||
EXPAT_TARBALL := expat-2.8.5.tar.xz
|
||||
# three static lines
|
||||
# so that git cherry-pick
|
||||
# will not run into conflicts
|
||||
FIREBIRD_SHA256SUM := bd263c4f685fb8fc3f1dcb8be8a411033cc31c5404d1dfce5d3849aa3f63a64d
|
||||
FIREBIRD_TARBALL := Firebird-3.0.13.33818-0.tar.bz2
|
||||
FIREBIRD_SHA256SUM := dce3f26c0f015b3c40f36085f8cc21de58dd568e0f347fdd0fcc7942deda8cff
|
||||
FIREBIRD_TARBALL := Firebird-3.0.14.33856-0.tar.bz2
|
||||
# three static lines
|
||||
# so that git cherry-pick
|
||||
# will not run into conflicts
|
||||
@@ -257,11 +257,6 @@ FONT_REEM_TARBALL := ReemKufi-2.0.zip
|
||||
# three static lines
|
||||
# so that git cherry-pick
|
||||
# will not run into conflicts
|
||||
FONT_SCHEHERAZADE_SHA256SUM := 251c8817ceb87d9b661ce1d5b49e732a0116add10abc046be4b8ba5196e149b5
|
||||
FONT_SCHEHERAZADE_TARBALL := Scheherazade-2.100.zip
|
||||
# three static lines
|
||||
# so that git cherry-pick
|
||||
# will not run into conflicts
|
||||
FREEHAND_SHA256SUM := 350b10d24a76d7e8c8ae98b74c2d432a2c8ddec08935d09856d20b695a35e600
|
||||
FREEHAND_TARBALL := libfreehand-0.1.4.tar.xz
|
||||
# three static lines
|
||||
@@ -292,8 +287,8 @@ GRAPHITE_TARBALL := graphite2-minimal-1.3.15.tgz
|
||||
# three static lines
|
||||
# so that git cherry-pick
|
||||
# will not run into conflicts
|
||||
HARFBUZZ_SHA256SUM := 2357ed966c6ced7bfa720b0640c0231065af01158fbea215093ffa15aed44371
|
||||
HARFBUZZ_TARBALL := harfbuzz-14.4.0.tar.xz
|
||||
HARFBUZZ_SHA256SUM := b7132e148358a45185c9feafd049dbaf243649d3c44414b3534d9c95d18592b9
|
||||
HARFBUZZ_TARBALL := harfbuzz-14.5.0.tar.xz
|
||||
# three static lines
|
||||
# so that git cherry-pick
|
||||
# will not run into conflicts
|
||||
@@ -307,8 +302,8 @@ HSQLDB_TARBALL := 17410483b5b5f267aa18b7e00b65e6e0-hsqldb_1_8_0.zip
|
||||
# three static lines
|
||||
# so that git cherry-pick
|
||||
# will not run into conflicts
|
||||
HUNSPELL_SHA256SUM := 433274dac0619cb00c2e18b43a3dd3a9d50da5b5613fa9b5c21781e35dd76bc1
|
||||
HUNSPELL_TARBALL := hunspell-1.7.3.tar.gz
|
||||
HUNSPELL_SHA256SUM := 66ec82a577395fe9d471504267e6dd04615c76517c61af7c6b9c19e5e34e73c8
|
||||
HUNSPELL_TARBALL := hunspell-1.7.4.tar.gz
|
||||
# three static lines
|
||||
# so that git cherry-pick
|
||||
# will not run into conflicts
|
||||
@@ -365,8 +360,8 @@ LIBJPEG_TURBO_TARBALL := libjpeg-turbo-3.1.4.1.tar.gz
|
||||
# three static lines
|
||||
# so that git cherry-pick
|
||||
# will not run into conflicts
|
||||
LANGTAGREG_SHA256SUM := 48293d95a13372f3e5bae04890d7d54ef4168b2469060e8e49cf60461cfc616f
|
||||
LANGTAGREG_TARBALL := language-subtag-registry-2026-08-08.tar.bz2
|
||||
LANGTAGREG_SHA256SUM := 10223cc8c219427c86a4c66ce98282a00c7f4d9b0609355146282344783007f2
|
||||
LANGTAGREG_TARBALL := language-subtag-registry-2026-9-17.tar.bz2
|
||||
# three static lines
|
||||
# so that git cherry-pick
|
||||
# will not run into conflicts
|
||||
@@ -493,8 +488,8 @@ MYTHES_TARBALL := mythes-1.2.6.tar.xz
|
||||
# three static lines
|
||||
# so that git cherry-pick
|
||||
# will not run into conflicts
|
||||
NSS_SHA256SUM := d389064d5e5ef09d597f8ae8dadc066f71e97b982bd7418b835686425fc3a189
|
||||
NSS_TARBALL := nss-3.129-with-nspr-4.39.tar.gz
|
||||
NSS_SHA256SUM := d122bd039416254567f2dfe7f4c9b6ed4d202d8c6a3ed91332da0d514d0974c0
|
||||
NSS_TARBALL := nss-3.130-with-nspr-4.39.tar.gz
|
||||
# three static lines
|
||||
# so that git cherry-pick
|
||||
# will not run into conflicts
|
||||
@@ -592,7 +587,7 @@ PYTHON_TARBALL := Python-3.13.15.tar.xz
|
||||
# so that git cherry-pick
|
||||
# will not run into conflicts
|
||||
QUICKJS_SHA256SUM := 866bad1e2f148b6f8144a4a3d4c3f8a0754495a6920fe56a7dd698cf0ad27f65
|
||||
QUICKJS_TARBALL := quickjs-0.16.2-amalgam.zip
|
||||
QUICKJS_TARBALL := quickjs-0.17.0-amalgam.zip
|
||||
# three static lines
|
||||
# so that git cherry-pick
|
||||
# will not run into conflicts
|
||||
@@ -627,8 +622,8 @@ REVENGE_TARBALL := librevenge-0.0.$(REVENGE_VERSION_MICRO).tar.bz2
|
||||
# three static lines
|
||||
# so that git cherry-pick
|
||||
# will not run into conflicts
|
||||
MD4C_SHA256SUM := 353c346f376b87c954a13f3415ede2d51264cc61dc5abcd38ff1d2aa0d059b9e
|
||||
MD4C_TARBALL := md4c-release-0.5.3.tar.gz
|
||||
MD4C_SHA256SUM := 4d151298125a81da3b2efa2e0eed8bdb7a9318569804e4fa4d7a2375ab83ef70
|
||||
MD4C_TARBALL := md4c-0.6.0.tar.gz
|
||||
# three static lines
|
||||
# so that git cherry-pick
|
||||
# will not run into conflicts
|
||||
|
||||
@@ -37,6 +37,7 @@ $(eval $(call gb_CppunitTest_use_externals,drawinglayer_processors,\
|
||||
))
|
||||
|
||||
$(eval $(call gb_CppunitTest_add_exception_objects,drawinglayer_processors, \
|
||||
drawinglayer/qa/unit/strokeattribute \
|
||||
drawinglayer/qa/unit/vclmetafileprocessor2d \
|
||||
drawinglayer/qa/unit/vclpixelprocessor2d \
|
||||
))
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This file is part of the LibreOffice project.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include <cppunit/TestAssert.h>
|
||||
#include <test/bootstrapfixture.hxx>
|
||||
|
||||
#include <drawinglayer/attribute/strokeattribute.hxx>
|
||||
|
||||
using namespace drawinglayer::attribute;
|
||||
|
||||
namespace
|
||||
{
|
||||
class StrokeAttributeTest : public test::BootstrapFixture
|
||||
{
|
||||
};
|
||||
|
||||
CPPUNIT_TEST_FIXTURE(StrokeAttributeTest, tdf152997_odd_length_dash_array)
|
||||
{
|
||||
std::vector<double> aDashArray{ 6.0 };
|
||||
StrokeAttribute aStroke(std::move(aDashArray));
|
||||
|
||||
// Without the fix in place, this test would have failed with
|
||||
// - Expected: 2
|
||||
// - Actual : 1
|
||||
// i.e. the odd-length array was not duplicated
|
||||
const std::vector<double> aExpected{ 6.0, 6.0 };
|
||||
CPPUNIT_ASSERT_EQUAL(aExpected.size(), aStroke.getDotDashArray().size());
|
||||
CPPUNIT_ASSERT_EQUAL(12.0, aStroke.getFullDotDashLen());
|
||||
for (size_t i = 0; i < aExpected.size(); ++i)
|
||||
CPPUNIT_ASSERT_DOUBLES_EQUAL(aExpected[i], aStroke.getDotDashArray()[i], 1E-12);
|
||||
}
|
||||
|
||||
CPPUNIT_TEST_FIXTURE(StrokeAttributeTest, tdf152997_odd_length_dash_array_multiple_values)
|
||||
{
|
||||
std::vector<double> aDashArray{ 5.0, 3.0, 2.0 };
|
||||
StrokeAttribute aStroke(std::move(aDashArray));
|
||||
|
||||
// Without the fix in place, this test would have failed with
|
||||
// - Expected: 6
|
||||
// - Actual : 3
|
||||
// i.e. the odd-length array was not duplicated
|
||||
const std::vector<double> aExpected{ 5.0, 3.0, 2.0, 5.0, 3.0, 2.0 };
|
||||
CPPUNIT_ASSERT_EQUAL(aExpected.size(), aStroke.getDotDashArray().size());
|
||||
for (size_t i = 0; i < aExpected.size(); ++i)
|
||||
CPPUNIT_ASSERT_DOUBLES_EQUAL(aExpected[i], aStroke.getDotDashArray()[i], 1E-12);
|
||||
}
|
||||
|
||||
CPPUNIT_TEST_FIXTURE(StrokeAttributeTest, tdf152997_even_length_dash_array)
|
||||
{
|
||||
std::vector<double> aDashArray{ 4.0, 2.0 };
|
||||
StrokeAttribute aStroke(std::move(aDashArray), 6.0);
|
||||
|
||||
// An even-length dash array should not be changed
|
||||
const std::vector<double> aExpected{ 4.0, 2.0 };
|
||||
CPPUNIT_ASSERT_EQUAL(aExpected.size(), aStroke.getDotDashArray().size());
|
||||
CPPUNIT_ASSERT_EQUAL(6.0, aStroke.getFullDotDashLen());
|
||||
for (size_t i = 0; i < aExpected.size(); ++i)
|
||||
CPPUNIT_ASSERT_DOUBLES_EQUAL(aExpected[i], aStroke.getDotDashArray()[i], 1E-12);
|
||||
}
|
||||
|
||||
CPPUNIT_TEST_FIXTURE(StrokeAttributeTest, tdf152997_empty_dash_array)
|
||||
{
|
||||
std::vector<double> aDashArray;
|
||||
StrokeAttribute aStroke(std::move(aDashArray));
|
||||
|
||||
// An empty dash array should not be changed
|
||||
CPPUNIT_ASSERT(aStroke.getDotDashArray().empty());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||
@@ -36,6 +36,21 @@ namespace drawinglayer::attribute
|
||||
: maDotDashArray(std::move(rDotDashArray)),
|
||||
mfFullDotDashLen(fFullDotDashLen)
|
||||
{
|
||||
// tdf#152997 - duplicate an odd length dash array in order to meet the spec.
|
||||
// An odd-length array will be drawn as one dash spanning the entire path. The
|
||||
// specifications under https://www.w3.org/TR/svg-strokes/#StrokeDashing state:
|
||||
// "If the list has an odd number of values, then it is repeated to yield an
|
||||
// even number of values. Thus, the rendering behavior of stroke-dasharray: 5,3,2
|
||||
// is equivalent to stroke-dasharray: 5,3,2,5,3,2."
|
||||
if (maDotDashArray.size() % 2 == 1)
|
||||
{
|
||||
const std::vector<double> aOriginal(maDotDashArray);
|
||||
maDotDashArray.insert(maDotDashArray.end(), aOriginal.begin(), aOriginal.end());
|
||||
|
||||
// Increase the length accordingly
|
||||
if (0.0 != mfFullDotDashLen)
|
||||
mfFullDotDashLen *= 2.0;
|
||||
}
|
||||
}
|
||||
|
||||
ImpStrokeAttribute()
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
#include <drawinglayer/primitive2d/structuretagprimitive2d.hxx>
|
||||
#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
|
||||
|
||||
#include <vcl/pdfwriter.hxx>
|
||||
|
||||
using namespace com::sun::star;
|
||||
|
||||
@@ -53,26 +53,27 @@ namespace drawinglayer::primitive2d
|
||||
{
|
||||
const StructureTagPrimitive2D& rCompare = static_cast<const StructureTagPrimitive2D&>(rPrimitive);
|
||||
|
||||
return (isBackground() == rCompare.isBackground() &&
|
||||
isImage() == rCompare.isImage());
|
||||
return (getStructureElement() == rCompare.getStructureElement()
|
||||
&& isBackground() == rCompare.isBackground()
|
||||
&& isImage() == rCompare.isImage()
|
||||
&& isDecorative() == rCompare.isDecorative());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool StructureTagPrimitive2D::opensStructureElement() const
|
||||
{
|
||||
return !isDecorative() && !isBackground()
|
||||
&& vcl::pdf::StructElement::NonStructElement != getStructureElement();
|
||||
}
|
||||
|
||||
// provide unique ID
|
||||
sal_uInt32 StructureTagPrimitive2D::getPrimitive2DID() const
|
||||
{
|
||||
return PRIMITIVE2D_ID_STRUCTURETAGPRIMITIVE2D;
|
||||
}
|
||||
|
||||
bool StructureTagPrimitive2D::isTaggedSdrObject() const
|
||||
{
|
||||
// note at the moment *all* StructureTagPrimitive2D are created for
|
||||
// SdrObjects - if that ever changes, need another condition here
|
||||
return !isBackground() || isImage();
|
||||
}
|
||||
|
||||
} // end of namespace
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||
|
||||
@@ -957,10 +957,8 @@ void VclMetafileProcessor2D::processObjectInfoPrimitive2D(
|
||||
// tdf#154982 process content first, so this object overrides any nested one
|
||||
process(rObjectInfoPrimitive2D.getChildren());
|
||||
|
||||
// currently StructureTagPrimitive2D is only used for SdrObjects - have to
|
||||
// avoid adding Alt text if the SdrObject is not actually tagged, as it
|
||||
// would then end up on an unrelated structure element.
|
||||
if (mpCurrentStructureTag && mpCurrentStructureTag->isTaggedSdrObject())
|
||||
// alt text belongs to the element this tag opens
|
||||
if (mpCurrentStructureTag && mpCurrentStructureTag->opensStructureElement())
|
||||
{
|
||||
// Create image alternative description from ObjectInfoPrimitive2D info
|
||||
// for PDF export, for the currently active SdrObject's structure element
|
||||
@@ -2754,20 +2752,20 @@ void VclMetafileProcessor2D::processStructureTagPrimitive2D(
|
||||
::comphelper::ValueRestorationGuard const g(mpCurrentStructureTag, &rStructureTagCandidate);
|
||||
|
||||
// structured tag primitive
|
||||
const vcl::pdf::StructElement& rTagElement(rStructureTagCandidate.getStructureElement());
|
||||
bool bTagUsed((vcl::pdf::StructElement::NonStructElement != rTagElement));
|
||||
const bool bArtifact(
|
||||
rStructureTagCandidate.isDecorative()
|
||||
|| (rStructureTagCandidate.isBackground() && rStructureTagCandidate.isImage()));
|
||||
// a plain background object is neither, and goes out untagged
|
||||
const bool bTagUsed(bArtifact || rStructureTagCandidate.opensStructureElement());
|
||||
::std::optional<sal_Int32> oAnchorParent;
|
||||
|
||||
if (!rStructureTagCandidate.isTaggedSdrObject())
|
||||
{
|
||||
bTagUsed = false;
|
||||
}
|
||||
|
||||
if (mpPDFExtOutDevData && bTagUsed)
|
||||
{
|
||||
// foreground object: tag as regular structure element
|
||||
if (!rStructureTagCandidate.isBackground())
|
||||
if (!bArtifact)
|
||||
{
|
||||
const vcl::pdf::StructElement& rTagElement(
|
||||
rStructureTagCandidate.getStructureElement());
|
||||
if (rStructureTagCandidate.GetAnchorStructureElementKey() != nullptr)
|
||||
{
|
||||
sal_Int32 const id = mpPDFExtOutDevData->EnsureStructureElement(
|
||||
@@ -2834,16 +2832,10 @@ void VclMetafileProcessor2D::processStructureTagPrimitive2D(
|
||||
vcl::pdf::PDFWriter::Column);
|
||||
}
|
||||
}
|
||||
// background object
|
||||
else
|
||||
{
|
||||
// background image: tag as artifact
|
||||
if (rStructureTagCandidate.isImage())
|
||||
mpPDFExtOutDevData->WrapBeginStructureElement(
|
||||
vcl::pdf::StructElement::NonStructElement);
|
||||
// any other background object: do not tag
|
||||
else
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1844,6 +1844,19 @@ namespace emfplushelper
|
||||
}
|
||||
|
||||
rMS.ReadUInt32(rectangles);
|
||||
// The record that is left says how many rectangles there can really be,
|
||||
// whatever count the file gave.
|
||||
const sal_uInt32 nBytesPerRectangle = (flags & 0x4000) ? 8 : 16;
|
||||
const sal_uInt64 nRecordLeft
|
||||
= rMS.Tell() < next ? std::min(next - rMS.Tell(), rMS.remainingSize())
|
||||
: 0;
|
||||
const sal_uInt64 nMaxRectangles = nRecordLeft / nBytesPerRectangle;
|
||||
if (rectangles > nMaxRectangles)
|
||||
{
|
||||
SAL_WARN("drawinglayer.emf", "EMF+\twants " << rectangles
|
||||
<< " rectangles, the record holds " << nMaxRectangles);
|
||||
rectangles = static_cast<sal_uInt32>(nMaxRectangles);
|
||||
}
|
||||
for (sal_uInt32 i = 0; i < rectangles; i++)
|
||||
{
|
||||
ReadRectangle(rMS, x, y, width, height, bool(flags & 0x4000));
|
||||
@@ -1931,6 +1944,16 @@ namespace emfplushelper
|
||||
"EMF+\t Bezier Draw not support number of points other than 4, 7, "
|
||||
"10, 13, 16...");
|
||||
|
||||
const sal_uInt32 nBytesPerPoint = (flags & 0x4000) ? 4 : 8;
|
||||
const sal_uInt64 nRecordLeft = rMS.Tell() < next ? next - rMS.Tell() : 0;
|
||||
const sal_uInt64 nMaxPoints = nRecordLeft / nBytesPerPoint;
|
||||
if (aCount > nMaxPoints)
|
||||
{
|
||||
SAL_WARN("drawinglayer.emf", "EMF+\twants " << aCount
|
||||
<< " points, the record holds " << nMaxPoints);
|
||||
aCount = static_cast<sal_uInt32>(nMaxPoints);
|
||||
}
|
||||
|
||||
if (aCount < 4)
|
||||
{
|
||||
SAL_WARN("drawinglayer.emf", "EMF+\t Bezier Draw does not support less "
|
||||
|
||||
@@ -2092,9 +2092,7 @@ uno::Sequence< beans::PropertyValue > SAL_CALL AccessibleEditableTextPara::getDe
|
||||
xPropSet->SetSelection( MakeSelection( 0, GetTextLen() ) );
|
||||
uno::Reference< beans::XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
|
||||
if (!xPropSetInfo.is())
|
||||
throw uno::RuntimeException(u"Cannot query XPropertySetInfo"_ustr,
|
||||
uno::Reference< uno::XInterface >
|
||||
( static_cast< XAccessible* > (this) ) ); // disambiguate hierarchy
|
||||
throw uno::RuntimeException(u"Cannot query XPropertySetInfo"_ustr, getXWeak());
|
||||
|
||||
// build sequence of available properties to check
|
||||
uno::Sequence< beans::Property > aProperties;
|
||||
@@ -2178,9 +2176,7 @@ uno::Sequence< beans::PropertyValue > SAL_CALL AccessibleEditableTextPara::getRu
|
||||
xPropSet->SetSelection( MakeSelection( nIndex ) );
|
||||
uno::Reference< beans::XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
|
||||
if (!xPropSetInfo.is())
|
||||
throw uno::RuntimeException(u"Cannot query XPropertySetInfo"_ustr,
|
||||
uno::Reference< uno::XInterface >
|
||||
( static_cast< XAccessible* > (this) ) ); // disambiguate hierarchy
|
||||
throw uno::RuntimeException(u"Cannot query XPropertySetInfo"_ustr, getXWeak());
|
||||
|
||||
// build sequence of available properties to check
|
||||
uno::Sequence< beans::Property > aProperties;
|
||||
|
||||
@@ -168,9 +168,7 @@ awt::Rectangle AccessibleImageBullet::implGetBounds( )
|
||||
|
||||
void SAL_CALL AccessibleImageBullet::grabFocus( )
|
||||
{
|
||||
throw uno::RuntimeException(u"Not focusable"_ustr,
|
||||
uno::Reference< uno::XInterface >
|
||||
( static_cast< XAccessible* > (this) ) ); // disambiguate hierarchy
|
||||
throw uno::RuntimeException(u"Not focusable"_ustr, getXWeak());
|
||||
}
|
||||
|
||||
sal_Int32 SAL_CALL AccessibleImageBullet::getForeground( )
|
||||
|
||||
@@ -87,14 +87,14 @@ const XParaPortion& XParaPortionList::operator [](size_t i) const
|
||||
return *maList[i];
|
||||
}
|
||||
|
||||
ContentInfo::ContentInfo( SfxItemPool& rPool ) :
|
||||
EditEngineParagraph::EditEngineParagraph( SfxItemPool& rPool ) :
|
||||
eFamily(SfxStyleFamily::Para),
|
||||
aParaAttribs(SfxItemSet::makeFixedSfxItemSet<EE_PARA_START, EE_CHAR_END>(rPool))
|
||||
{
|
||||
}
|
||||
|
||||
// the real Copy constructor is nonsense, since I have to work with another Pool!
|
||||
ContentInfo::ContentInfo( const ContentInfo& rCopyFrom, SfxItemPool& rPoolToUse ) :
|
||||
EditEngineParagraph::EditEngineParagraph( const EditEngineParagraph& rCopyFrom, SfxItemPool& rPoolToUse ) :
|
||||
maText(rCopyFrom.maText),
|
||||
aStyle(rCopyFrom.aStyle),
|
||||
eFamily(rCopyFrom.eFamily),
|
||||
@@ -115,35 +115,35 @@ ContentInfo::ContentInfo( const ContentInfo& rCopyFrom, SfxItemPool& rPoolToUse
|
||||
mpWrongs.reset(rCopyFrom.GetWrongList()->Clone());
|
||||
}
|
||||
|
||||
ContentInfo::~ContentInfo()
|
||||
EditEngineParagraph::~EditEngineParagraph()
|
||||
{
|
||||
maCharAttribs.clear();
|
||||
}
|
||||
|
||||
void ContentInfo::NormalizeString( svl::SharedStringPool& rPool )
|
||||
void EditEngineParagraph::NormalizeString( svl::SharedStringPool& rPool )
|
||||
{
|
||||
maText = rPool.intern(OUString(maText.getData()));
|
||||
}
|
||||
|
||||
|
||||
OUString ContentInfo::GetText() const
|
||||
OUString EditEngineParagraph::GetText() const
|
||||
{
|
||||
rtl_uString* p = const_cast<rtl_uString*>(maText.getData());
|
||||
return OUString(p);
|
||||
}
|
||||
|
||||
sal_Int32 ContentInfo::GetTextLen() const
|
||||
sal_Int32 EditEngineParagraph::GetTextLen() const
|
||||
{
|
||||
const rtl_uString* p = maText.getData();
|
||||
return p->length;
|
||||
}
|
||||
|
||||
void ContentInfo::SetText( const OUString& rStr )
|
||||
void EditEngineParagraph::SetText( const OUString& rStr )
|
||||
{
|
||||
maText = svl::SharedString(rStr.pData, nullptr);
|
||||
}
|
||||
|
||||
void ContentInfo::dumpAsXml(xmlTextWriterPtr pWriter) const
|
||||
void EditEngineParagraph::dumpAsXml(xmlTextWriterPtr pWriter) const
|
||||
{
|
||||
(void)xmlTextWriterStartElement(pWriter, BAD_CAST("ContentInfo"));
|
||||
(void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("style"), BAD_CAST(aStyle.toUtf8().getStr()));
|
||||
@@ -167,18 +167,18 @@ void ContentInfo::dumpAsXml(xmlTextWriterPtr pWriter) const
|
||||
(void)xmlTextWriterEndElement(pWriter);
|
||||
}
|
||||
|
||||
const WrongList* ContentInfo::GetWrongList() const
|
||||
const WrongList* EditEngineParagraph::GetWrongList() const
|
||||
{
|
||||
return mpWrongs.get();
|
||||
}
|
||||
|
||||
void ContentInfo::SetWrongList( WrongList* p )
|
||||
void EditEngineParagraph::SetWrongList( WrongList* p )
|
||||
{
|
||||
mpWrongs.reset(p);
|
||||
}
|
||||
|
||||
// #i102062#
|
||||
bool ContentInfo::isWrongListEqual(const ContentInfo& rCompare) const
|
||||
bool EditEngineParagraph::isWrongListEqual(const EditEngineParagraph& rCompare) const
|
||||
{
|
||||
if(GetWrongList() == rCompare.GetWrongList())
|
||||
return true;
|
||||
@@ -190,7 +190,7 @@ bool ContentInfo::isWrongListEqual(const ContentInfo& rCompare) const
|
||||
}
|
||||
|
||||
#if DEBUG_EDIT_ENGINE
|
||||
void ContentInfo::Dump() const
|
||||
void EditEngineParagraph::Dump() const
|
||||
{
|
||||
cout << "--" << endl;
|
||||
cout << "text: '" << OUString(const_cast<rtl_uString*>(maText.getData())) << "'" << endl;
|
||||
@@ -205,7 +205,7 @@ void ContentInfo::Dump() const
|
||||
}
|
||||
#endif
|
||||
|
||||
bool ContentInfo::Equals(const ContentInfo& rCompare, bool bComparePool) const
|
||||
bool EditEngineParagraph::Equals(const EditEngineParagraph& rCompare, bool bComparePool) const
|
||||
{
|
||||
return maText == rCompare.maText && aStyle == rCompare.aStyle && eFamily == rCompare.eFamily
|
||||
&& aParaAttribs.Equals(rCompare.aParaAttribs, bComparePool)
|
||||
@@ -236,7 +236,7 @@ void EditTextObject::dumpAsXml(xmlTextWriterPtr pWriter) const
|
||||
sal_Int32 nCount = GetParagraphCount();
|
||||
for (sal_Int32 i = 0; i < nCount; ++i)
|
||||
{
|
||||
maContents[i]->dumpAsXml(pWriter);
|
||||
maParagraphs[i]->dumpAsXml(pWriter);
|
||||
}
|
||||
(void)xmlTextWriterEndElement(pWriter);
|
||||
|
||||
@@ -292,9 +292,9 @@ EditTextObject::EditTextObject( const EditTextObject& r )
|
||||
{
|
||||
// Do not copy PortionInfo
|
||||
|
||||
maContents.reserve(r.maContents.size());
|
||||
for (auto const& content : r.maContents)
|
||||
maContents.push_back(std::unique_ptr<ContentInfo>(new ContentInfo(*content, *mpPool)));
|
||||
maParagraphs.reserve(r.maParagraphs.size());
|
||||
for (auto const& content : r.maParagraphs)
|
||||
maParagraphs.push_back(std::unique_ptr<EditEngineParagraph>(new EditEngineParagraph(*content, *mpPool)));
|
||||
}
|
||||
|
||||
EditTextObject::EditTextObject( EditTextObject&& ) noexcept = default;
|
||||
@@ -305,7 +305,7 @@ EditTextObject::~EditTextObject()
|
||||
|
||||
// Remove contents before deleting the pool instance since each content
|
||||
// has to access the pool instance in its destructor.
|
||||
maContents.clear();
|
||||
maParagraphs.clear();
|
||||
}
|
||||
|
||||
EditTextObject& EditTextObject::operator=(EditTextObject&&) = default;
|
||||
@@ -317,9 +317,9 @@ void EditTextObject::SetUserType( OutlinerMode n )
|
||||
|
||||
void EditTextObject::NormalizeString( svl::SharedStringPool& rPool )
|
||||
{
|
||||
for (auto const& content : maContents)
|
||||
for (auto const& content : maParagraphs)
|
||||
{
|
||||
ContentInfo& rInfo = *content;
|
||||
EditEngineParagraph& rInfo = *content;
|
||||
rInfo.NormalizeString(rPool);
|
||||
}
|
||||
}
|
||||
@@ -327,10 +327,10 @@ void EditTextObject::NormalizeString( svl::SharedStringPool& rPool )
|
||||
std::vector<svl::SharedString> EditTextObject::GetSharedStrings() const
|
||||
{
|
||||
std::vector<svl::SharedString> aSSs;
|
||||
aSSs.reserve(maContents.size());
|
||||
for (auto const& content : maContents)
|
||||
aSSs.reserve(maParagraphs.size());
|
||||
for (auto const& content : maParagraphs)
|
||||
{
|
||||
const ContentInfo& rInfo = *content;
|
||||
const EditEngineParagraph& rInfo = *content;
|
||||
aSSs.push_back(rInfo.GetSharedString());
|
||||
}
|
||||
return aSSs;
|
||||
@@ -376,15 +376,15 @@ TextRotation EditTextObject::GetRotation() const
|
||||
return meRotation;
|
||||
}
|
||||
|
||||
ContentInfo* EditTextObject::CreateAndInsertContent()
|
||||
EditEngineParagraph* EditTextObject::CreateAndInsertParagraph()
|
||||
{
|
||||
maContents.push_back(std::unique_ptr<ContentInfo>(new ContentInfo(*mpPool)));
|
||||
return maContents.back().get();
|
||||
maParagraphs.push_back(std::unique_ptr<EditEngineParagraph>(new EditEngineParagraph(*mpPool)));
|
||||
return maParagraphs.back().get();
|
||||
}
|
||||
|
||||
sal_Int32 EditTextObject::GetParagraphCount() const
|
||||
{
|
||||
size_t nSize = maContents.size();
|
||||
size_t nSize = maParagraphs.size();
|
||||
if (nSize > EE_PARA_MAX)
|
||||
{
|
||||
SAL_WARN( "editeng", "EditTextObject::GetParagraphCount - overflow " << nSize);
|
||||
@@ -395,12 +395,12 @@ sal_Int32 EditTextObject::GetParagraphCount() const
|
||||
|
||||
OUString EditTextObject::GetText(sal_Int32 nPara) const
|
||||
{
|
||||
return maContents[nPara]->GetText();
|
||||
return maParagraphs[nPara]->GetText();
|
||||
}
|
||||
|
||||
OUString EditTextObject::GetText(LineEnd eEnd) const
|
||||
{
|
||||
const size_t nParas = maContents.size();
|
||||
const size_t nParas = maParagraphs.size();
|
||||
if (nParas == 0)
|
||||
return OUString();
|
||||
|
||||
@@ -412,7 +412,7 @@ OUString EditTextObject::GetText(LineEnd eEnd) const
|
||||
{
|
||||
if (!aSep.isEmpty() && nPara > 0)
|
||||
aBuffer.append(aSep);
|
||||
aBuffer.append(maContents[nPara]->GetText());
|
||||
aBuffer.append(maParagraphs[nPara]->GetText());
|
||||
}
|
||||
|
||||
return aBuffer.makeStringAndClear();
|
||||
@@ -420,37 +420,37 @@ OUString EditTextObject::GetText(LineEnd eEnd) const
|
||||
|
||||
sal_Int32 EditTextObject::GetTextLen(sal_Int32 nPara ) const
|
||||
{
|
||||
return maContents[nPara]->GetTextLen();
|
||||
return maParagraphs[nPara]->GetTextLen();
|
||||
}
|
||||
|
||||
sal_Int16 EditTextObject::GetNumberingDepth(sal_Int32 nPara) const
|
||||
{
|
||||
return maContents[nPara]->GetNumberingDepth();
|
||||
return maParagraphs[nPara]->GetNumberingDepth();
|
||||
}
|
||||
|
||||
void EditTextObject::SetNumberingDepth(sal_Int32 nPara, sal_Int16 nDepth)
|
||||
{
|
||||
maContents[nPara]->SetNumberingDepth(nDepth);
|
||||
maParagraphs[nPara]->SetNumberingDepth(nDepth);
|
||||
}
|
||||
|
||||
sal_Int16 EditTextObject::GetNumberingStartValue(sal_Int32 nPara) const
|
||||
{
|
||||
return maContents[nPara]->GetNumberingStartValue();
|
||||
return maParagraphs[nPara]->GetNumberingStartValue();
|
||||
}
|
||||
|
||||
void EditTextObject::SetNumberingStartValue(sal_Int32 nPara, sal_Int16 nStartValue)
|
||||
{
|
||||
maContents[nPara]->SetNumberingStartValue(nStartValue);
|
||||
maParagraphs[nPara]->SetNumberingStartValue(nStartValue);
|
||||
}
|
||||
|
||||
bool EditTextObject::IsNumberingRestart(sal_Int32 nPara) const
|
||||
{
|
||||
return maContents[nPara]->IsNumberingRestart();
|
||||
return maParagraphs[nPara]->IsNumberingRestart();
|
||||
}
|
||||
|
||||
void EditTextObject::SetNumberingRestart(sal_Int32 nPara, bool bRestart)
|
||||
{
|
||||
maContents[nPara]->SetNumberingRestart(bRestart);
|
||||
maParagraphs[nPara]->SetNumberingRestart(bRestart);
|
||||
}
|
||||
|
||||
void EditTextObject::ClearPortionInfo()
|
||||
@@ -460,7 +460,7 @@ void EditTextObject::ClearPortionInfo()
|
||||
|
||||
bool EditTextObject::HasOnlineSpellErrors() const
|
||||
{
|
||||
for (auto const& content : maContents)
|
||||
for (auto const& content : maParagraphs)
|
||||
{
|
||||
if ( content->GetWrongList() && !content->GetWrongList()->empty() )
|
||||
return true;
|
||||
@@ -471,7 +471,7 @@ bool EditTextObject::HasOnlineSpellErrors() const
|
||||
void EditTextObject::GetCharAttribs( sal_Int32 nPara, std::vector<EECharAttrib>& rLst ) const
|
||||
{
|
||||
rLst.clear();
|
||||
const ContentInfo& rC = *maContents[nPara];
|
||||
const EditEngineParagraph& rC = *maParagraphs[nPara];
|
||||
for (const XEditAttribute & rAttr : rC.maCharAttribs)
|
||||
{
|
||||
EECharAttrib aEEAttr(rAttr.GetStart(), rAttr.GetEnd(), rAttr.GetItem());
|
||||
@@ -486,9 +486,9 @@ bool EditTextObject::IsFieldObject() const
|
||||
|
||||
const SvxFieldItem* EditTextObject::GetField() const
|
||||
{
|
||||
if (maContents.size() == 1)
|
||||
if (maParagraphs.size() == 1)
|
||||
{
|
||||
const ContentInfo& rC = *maContents[0];
|
||||
const EditEngineParagraph& rC = *maParagraphs[0];
|
||||
if (rC.GetText().getLength() == 1)
|
||||
{
|
||||
size_t nAttribs = rC.maCharAttribs.size();
|
||||
@@ -505,7 +505,7 @@ const SvxFieldItem* EditTextObject::GetField() const
|
||||
|
||||
const SvxFieldData* EditTextObject::GetFieldData(sal_Int32 nPara, size_t nPos, sal_Int32 nType) const
|
||||
{
|
||||
const ContentInfo& rC = *maContents[nPara];
|
||||
const EditEngineParagraph& rC = *maParagraphs[nPara];
|
||||
if (nPos >= rC.maCharAttribs.size())
|
||||
// URL position is out-of-bound.
|
||||
return nullptr;
|
||||
@@ -535,10 +535,10 @@ const SvxFieldData* EditTextObject::GetFieldData(sal_Int32 nPara, size_t nPos, s
|
||||
|
||||
bool EditTextObject::HasField( sal_Int32 nType ) const
|
||||
{
|
||||
size_t nParagraphs = maContents.size();
|
||||
size_t nParagraphs = maParagraphs.size();
|
||||
for (size_t nPara = 0; nPara < nParagraphs; ++nPara)
|
||||
{
|
||||
const ContentInfo& rC = *maContents[nPara];
|
||||
const EditEngineParagraph& rC = *maParagraphs[nPara];
|
||||
size_t nAttrs = rC.maCharAttribs.size();
|
||||
for (size_t nAttr = 0; nAttr < nAttrs; ++nAttr)
|
||||
{
|
||||
@@ -560,7 +560,7 @@ bool EditTextObject::HasField( sal_Int32 nType ) const
|
||||
|
||||
const SfxItemSet& EditTextObject::GetParaAttribs(sal_Int32 nPara) const
|
||||
{
|
||||
const ContentInfo& rC = *maContents[nPara];
|
||||
const EditEngineParagraph& rC = *maParagraphs[nPara];
|
||||
return rC.GetParaAttribs();
|
||||
}
|
||||
|
||||
@@ -568,9 +568,9 @@ bool EditTextObject::RemoveCharAttribs( sal_uInt16 _nWhich )
|
||||
{
|
||||
bool bChanged = false;
|
||||
|
||||
for ( size_t nPara = maContents.size(); nPara; )
|
||||
for ( size_t nPara = maParagraphs.size(); nPara; )
|
||||
{
|
||||
ContentInfo& rC = *maContents[--nPara];
|
||||
EditEngineParagraph& rC = *maParagraphs[--nPara];
|
||||
|
||||
for (size_t nAttr = rC.maCharAttribs.size(); nAttr; )
|
||||
{
|
||||
@@ -619,13 +619,13 @@ public:
|
||||
void EditTextObject::GetAllSections( std::vector<editeng::Section>& rAttrs ) const
|
||||
{
|
||||
std::vector<editeng::Section> aAttrs;
|
||||
aAttrs.reserve(maContents.size());
|
||||
aAttrs.reserve(maParagraphs.size());
|
||||
std::vector<size_t> aBorders;
|
||||
|
||||
for (size_t nPara = 0; nPara < maContents.size(); ++nPara)
|
||||
for (size_t nPara = 0; nPara < maParagraphs.size(); ++nPara)
|
||||
{
|
||||
aBorders.clear();
|
||||
const ContentInfo& rC = *maContents[nPara];
|
||||
const EditEngineParagraph& rC = *maParagraphs[nPara];
|
||||
aBorders.push_back(0);
|
||||
aBorders.push_back(rC.GetText().getLength());
|
||||
for (const XEditAttribute & rAttr : rC.maCharAttribs)
|
||||
@@ -669,9 +669,9 @@ void EditTextObject::GetAllSections( std::vector<editeng::Section>& rAttrs ) con
|
||||
|
||||
// Go through all formatted paragraphs, and store format items.
|
||||
std::vector<editeng::Section>::iterator itAttr = aAttrs.begin();
|
||||
for (sal_Int32 nPara = 0; nPara < static_cast<sal_Int32>(maContents.size()); ++nPara)
|
||||
for (sal_Int32 nPara = 0; nPara < static_cast<sal_Int32>(maParagraphs.size()); ++nPara)
|
||||
{
|
||||
const ContentInfo& rC = *maContents[nPara];
|
||||
const EditEngineParagraph& rC = *maParagraphs[nPara];
|
||||
|
||||
itAttr = std::find_if(itAttr, aAttrs.end(), FindByParagraph(nPara));
|
||||
if (itAttr == aAttrs.end())
|
||||
@@ -721,14 +721,14 @@ void EditTextObject::GetAllSections( std::vector<editeng::Section>& rAttrs ) con
|
||||
|
||||
void EditTextObject::GetStyleSheet(sal_Int32 nPara, OUString& rName, SfxStyleFamily& rFamily) const
|
||||
{
|
||||
const ContentInfo& rC = *maContents[nPara];
|
||||
const EditEngineParagraph& rC = *maParagraphs[nPara];
|
||||
rName = rC.GetStyle();
|
||||
rFamily = rC.GetFamily();
|
||||
}
|
||||
|
||||
void EditTextObject::SetStyleSheet(sal_Int32 nPara, const OUString& rName, const SfxStyleFamily& rFamily)
|
||||
{
|
||||
ContentInfo& rC = *maContents[nPara];
|
||||
EditEngineParagraph& rC = *maParagraphs[nPara];
|
||||
rC.SetStyle(rName);
|
||||
rC.SetFamily(rFamily);
|
||||
}
|
||||
@@ -737,12 +737,12 @@ bool EditTextObject::ImpChangeStyleSheets(
|
||||
std::u16string_view rOldName, SfxStyleFamily eOldFamily,
|
||||
const OUString& rNewName, SfxStyleFamily eNewFamily )
|
||||
{
|
||||
const size_t nParagraphs = maContents.size();
|
||||
const size_t nParagraphs = maParagraphs.size();
|
||||
bool bChanges = false;
|
||||
|
||||
for (size_t nPara = 0; nPara < nParagraphs; ++nPara)
|
||||
{
|
||||
ContentInfo& rC = *maContents[nPara];
|
||||
EditEngineParagraph& rC = *maParagraphs[nPara];
|
||||
if ( rC.GetFamily() == eOldFamily )
|
||||
{
|
||||
if ( rC.GetStyle() == rOldName )
|
||||
@@ -792,7 +792,7 @@ bool EditTextObject::Equals( const EditTextObject& rCompare, bool bComparePool )
|
||||
return false;
|
||||
|
||||
return std::equal(
|
||||
maContents.begin(), maContents.end(), rCompare.maContents.begin(), rCompare.maContents.end(),
|
||||
maParagraphs.begin(), maParagraphs.end(), rCompare.maParagraphs.begin(), rCompare.maParagraphs.end(),
|
||||
[bComparePool](const auto& c1, const auto& c2) { return c1->Equals(*c2, bComparePool); });
|
||||
}
|
||||
|
||||
@@ -800,7 +800,7 @@ bool EditTextObject::Equals( const EditTextObject& rCompare, bool bComparePool )
|
||||
bool EditTextObject::isWrongListEqual(const EditTextObject& rCompare) const
|
||||
{
|
||||
return std::equal(
|
||||
maContents.begin(), maContents.end(), rCompare.maContents.begin(), rCompare.maContents.end(),
|
||||
maParagraphs.begin(), maParagraphs.end(), rCompare.maParagraphs.begin(), rCompare.maParagraphs.end(),
|
||||
[](const auto& c1, const auto& c2) { return c1->isWrongListEqual(*c2); });
|
||||
}
|
||||
|
||||
|
||||
@@ -112,7 +112,7 @@ public:
|
||||
double getSpacingScaleY() const { return mfSpacingScaleY; }
|
||||
};
|
||||
|
||||
class ContentInfo
|
||||
class EditEngineParagraph
|
||||
{
|
||||
friend class EditTextObject;
|
||||
|
||||
@@ -129,13 +129,13 @@ private:
|
||||
sal_Int16 mnNumberingStartValue { -1 };
|
||||
bool mbNumberingRestart { false };
|
||||
|
||||
ContentInfo( SfxItemPool& rPool );
|
||||
ContentInfo( const ContentInfo& rCopyFrom, SfxItemPool& rPoolToUse );
|
||||
EditEngineParagraph( SfxItemPool& rPool );
|
||||
EditEngineParagraph( const EditEngineParagraph& rCopyFrom, SfxItemPool& rPoolToUse );
|
||||
|
||||
public:
|
||||
~ContentInfo();
|
||||
ContentInfo(const ContentInfo&) = delete;
|
||||
ContentInfo& operator=(const ContentInfo&) = delete;
|
||||
~EditEngineParagraph();
|
||||
EditEngineParagraph(const EditEngineParagraph&) = delete;
|
||||
EditEngineParagraph& operator=(const EditEngineParagraph&) = delete;
|
||||
|
||||
void NormalizeString( svl::SharedStringPool& rPool );
|
||||
const svl::SharedString& GetSharedString() const { return maText;}
|
||||
@@ -159,10 +159,10 @@ public:
|
||||
|
||||
const WrongList* GetWrongList() const;
|
||||
void SetWrongList( WrongList* p );
|
||||
bool Equals( const ContentInfo& rCompare, bool bComparePool ) const;
|
||||
bool Equals( const EditEngineParagraph& rCompare, bool bComparePool ) const;
|
||||
|
||||
// #i102062#
|
||||
bool isWrongListEqual(const ContentInfo& rCompare) const;
|
||||
bool isWrongListEqual(const EditEngineParagraph& rCompare) const;
|
||||
|
||||
sal_Int16 GetNumberingDepth() const { return mnNumberingDepth; }
|
||||
void SetNumberingDepth(sal_Int16 nDepth) { mnNumberingDepth = nDepth; }
|
||||
|
||||
@@ -44,10 +44,10 @@ public:
|
||||
void updateTableFields(int nTab)
|
||||
{
|
||||
SfxItemPool* pPool = mrObj.GetPool();
|
||||
EditTextObject::ContentInfosType& rContents = mrObj.GetContents();
|
||||
for (std::unique_ptr<ContentInfo> & i : rContents)
|
||||
EditTextObject::EditEngineParagraphs& rContents = mrObj.GetParagraphs();
|
||||
for (std::unique_ptr<EditEngineParagraph> & i : rContents)
|
||||
{
|
||||
ContentInfo& rContent = *i;
|
||||
EditEngineParagraph& rContent = *i;
|
||||
for (XEditAttribute & rAttr : rContent.GetCharAttribs())
|
||||
{
|
||||
const SfxPoolItem* pItem = rAttr.GetItem();
|
||||
@@ -71,10 +71,10 @@ public:
|
||||
|
||||
void UpdatePageRelativeURLs(const std::function<void(const SvxFieldItem & rFieldItem, SvxFieldItemUpdater& rFieldItemUpdater)>& rItemCallback)
|
||||
{
|
||||
EditTextObject::ContentInfosType& rContents = mrObj.GetContents();
|
||||
for (std::unique_ptr<ContentInfo> & i : rContents)
|
||||
EditTextObject::EditEngineParagraphs& rContents = mrObj.GetParagraphs();
|
||||
for (std::unique_ptr<EditEngineParagraph> & i : rContents)
|
||||
{
|
||||
ContentInfo& rContent = *i;
|
||||
EditEngineParagraph& rContent = *i;
|
||||
for (XEditAttribute & rAttr : rContent.GetCharAttribs())
|
||||
{
|
||||
const SfxPoolItem* pItem = rAttr.GetItem();
|
||||
|
||||
@@ -1227,7 +1227,7 @@ EditTextObject ImpEditEngine::CreateTextObject( EditSelection aSel, SfxItemPool*
|
||||
nEndPos = aSel.Max().GetIndex();
|
||||
|
||||
|
||||
ContentInfo *pC = aTxtObj.CreateAndInsertContent();
|
||||
EditEngineParagraph *pC = aTxtObj.CreateAndInsertParagraph();
|
||||
|
||||
// The paragraph attributes ...
|
||||
pC->GetParaAttribs().Set( pNode->GetContentAttribs().GetItems() );
|
||||
@@ -1393,13 +1393,13 @@ EditSelection ImpEditEngine::InsertTextObject( const EditTextObject& rTextObject
|
||||
// Before, paragraph count was of type sal_uInt16 so if nContents exceeded
|
||||
// 0xFFFF this wouldn't have worked anyway, given that nPara is used to
|
||||
// number paragraphs and is fearlessly incremented.
|
||||
sal_Int32 nContents = static_cast<sal_Int32>(rTextObject.GetContents().size());
|
||||
sal_Int32 nContents = static_cast<sal_Int32>(rTextObject.GetParagraphs().size());
|
||||
SAL_WARN_IF( nContents < 0, "editeng", "ImpEditEngine::InsertTextObject - contents overflow " << nContents);
|
||||
sal_Int32 nPara = maEditDoc.GetPos( aPaM.GetNode() );
|
||||
|
||||
for (sal_Int32 n = 0; n < nContents; ++n, ++nPara)
|
||||
{
|
||||
const ContentInfo* pC = rTextObject.GetContents()[n].get();
|
||||
const EditEngineParagraph* pC = rTextObject.GetParagraphs()[n].get();
|
||||
bool bNewContent = aPaM.GetNode()->Len() == 0;
|
||||
const sal_Int32 nStartPos = aPaM.GetIndex();
|
||||
|
||||
|
||||
@@ -112,8 +112,13 @@ SvxFieldData* SvxFieldData::Create(const uno::Reference<text::XTextContent>& xTe
|
||||
xPropSet->getPropertyValue(UNO_TC_PROP_URL_TARGET) >>= aTarget;
|
||||
xPropSet->getPropertyValue(UNO_TC_PROP_URL) >>= aURL;
|
||||
xPropSet->getPropertyValue(UNO_TC_PROP_URL_FORMAT) >>= nFmt;
|
||||
// Calc's own URL field has no name, and a miss here would drop the field
|
||||
OUString aName;
|
||||
if (xPropSet->getPropertySetInfo()->hasPropertyByName(UNO_TC_PROP_NAME))
|
||||
xPropSet->getPropertyValue(UNO_TC_PROP_NAME) >>= aName;
|
||||
SvxURLField* pData = new SvxURLField(aURL, aRep, aRep.isEmpty() ? SvxURLFormat::Url : SvxURLFormat::Repr);
|
||||
pData->SetTargetFrame(aTarget);
|
||||
pData->SetName(aName);
|
||||
if (static_cast<SvxURLFormat>(nFmt) >= SvxURLFormat::AppDefault &&
|
||||
static_cast<SvxURLFormat>(nFmt) <= SvxURLFormat::Repr)
|
||||
pData->SetFormat(static_cast<SvxURLFormat>(nFmt));
|
||||
|
||||
@@ -322,7 +322,8 @@ SvxAdjustItem::SvxAdjustItem(const SvxAdjust eAdjst, const sal_uInt16 nId )
|
||||
nPropLetterSpacingMaximum(0),
|
||||
nPropScaleWidthMinimum(100),
|
||||
nPropScaleWidthMaximum(100),
|
||||
bParagraphComposer(false)
|
||||
bParagraphComposer(false),
|
||||
bCompoundBased(false)
|
||||
{
|
||||
SetAdjust( eAdjst );
|
||||
}
|
||||
@@ -342,6 +343,7 @@ bool SvxAdjustItem::operator==( const SfxPoolItem& rAttr ) const
|
||||
bParagraphComposer == rItem.bParagraphComposer &&
|
||||
nPropLetterSpacingMinimum == rItem.nPropLetterSpacingMinimum &&
|
||||
nPropLetterSpacingMaximum == rItem.nPropLetterSpacingMaximum &&
|
||||
bCompoundBased == rItem.bCompoundBased &&
|
||||
nPropScaleWidthMinimum == rItem.nPropScaleWidthMinimum &&
|
||||
nPropScaleWidthMaximum == rItem.nPropScaleWidthMaximum;
|
||||
}
|
||||
@@ -359,6 +361,7 @@ size_t SvxAdjustItem::hashCode() const
|
||||
o3tl::hash_combine(seed, bParagraphComposer);
|
||||
o3tl::hash_combine(seed, nPropLetterSpacingMinimum);
|
||||
o3tl::hash_combine(seed, nPropLetterSpacingMaximum);
|
||||
o3tl::hash_combine(seed, bCompoundBased);
|
||||
o3tl::hash_combine(seed, nPropScaleWidthMinimum);
|
||||
o3tl::hash_combine(seed, nPropScaleWidthMaximum);
|
||||
return seed;
|
||||
@@ -388,6 +391,11 @@ bool SvxAdjustItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
|
||||
rVal <<= bParagraphComposer;
|
||||
break;
|
||||
}
|
||||
case MID_COMPOUND_BASED :
|
||||
{
|
||||
rVal <<= bCompoundBased;
|
||||
break;
|
||||
}
|
||||
default: ;//prevent warning
|
||||
}
|
||||
return true;
|
||||
@@ -471,6 +479,12 @@ bool SvxAdjustItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
|
||||
bParagraphComposer = Any2Bool(rVal);
|
||||
}
|
||||
break;
|
||||
case MID_COMPOUND_BASED :
|
||||
{
|
||||
ASSERT_CHANGE_REFCOUNTED_ITEM;
|
||||
bCompoundBased = Any2Bool(rVal);
|
||||
}
|
||||
break;
|
||||
case MID_EXPAND_SINGLE :
|
||||
ASSERT_CHANGE_REFCOUNTED_ITEM;
|
||||
bOneBlock = Any2Bool(rVal);
|
||||
|
||||
@@ -121,7 +121,11 @@ static bool NonFieldWordDelim( const sal_Unicode c )
|
||||
|
||||
static bool IsWordDelim( const sal_Unicode c )
|
||||
{
|
||||
return c == 0x1 || NonFieldWordDelim(c);
|
||||
// tdf#154463 - 0x01 ... 0x08 are the characters put into the text to
|
||||
// anchor a text attribute or to delimit a fieldmark: CH_TXTATR_BREAKWORD,
|
||||
// CH_TXT_ATR_FIELDSEP, CH_TXT_ATR_INPUTFIELDSTART/END, CH_TXT_ATR_FORMELEMENT
|
||||
// and CH_TXT_ATR_FIELDSTART/END (see sw/inc/hintids.hxx).
|
||||
return (0x01 <= c && c <= 0x08) || NonFieldWordDelim(c);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -57,6 +57,7 @@ using namespace ::com::sun::star;
|
||||
#define WID_STRING1 5
|
||||
#define WID_STRING2 6
|
||||
#define WID_STRING3 7
|
||||
#define WID_STRING4 8
|
||||
|
||||
class SvxUnoFieldData_Impl
|
||||
{
|
||||
@@ -68,6 +69,7 @@ public:
|
||||
OUString msString1;
|
||||
OUString msString2;
|
||||
OUString msString3;
|
||||
OUString msString4;
|
||||
util::DateTime maDateTime;
|
||||
|
||||
OUString msPresentation;
|
||||
@@ -96,6 +98,7 @@ static const SfxItemPropertySet* ImplGetFieldItemPropertySet( sal_Int32 mnId )
|
||||
{ UNO_TC_PROP_URL_REPRESENTATION, WID_STRING1, ::cppu::UnoType<OUString>::get(), 0, 0 },
|
||||
{ UNO_TC_PROP_URL_TARGET, WID_STRING2, ::cppu::UnoType<OUString>::get(), 0, 0 },
|
||||
{ UNO_TC_PROP_URL, WID_STRING3, ::cppu::UnoType<OUString>::get(), 0, 0 },
|
||||
{ UNO_TC_PROP_NAME, WID_STRING4, ::cppu::UnoType<OUString>::get(), 0, 0 },
|
||||
};
|
||||
static const SfxItemPropertySet aUrlFieldPropertySet_Impl(aUrlFieldPropertyMap_Impl);
|
||||
|
||||
@@ -340,6 +343,7 @@ SvxUnoTextField::SvxUnoTextField( uno::Reference< text::XTextRange > xAnchor, co
|
||||
mpImpl->msString1 = static_cast<const SvxURLField*>(pData)->GetRepresentation();
|
||||
mpImpl->msString2 = static_cast<const SvxURLField*>(pData)->GetTargetFrame();
|
||||
mpImpl->msString3 = static_cast<const SvxURLField*>(pData)->GetURL();
|
||||
mpImpl->msString4 = static_cast<const SvxURLField*>(pData)->GetName();
|
||||
mpImpl->mnInt16 = sal::static_int_cast< sal_Int16 >(
|
||||
static_cast<const SvxURLField*>(pData)->GetFormat());
|
||||
break;
|
||||
@@ -426,6 +430,7 @@ std::unique_ptr<SvxFieldData> SvxUnoTextField::CreateFieldData() const noexcept
|
||||
case text::textfield::Type::URL:
|
||||
pData.reset( new SvxURLField( mpImpl->msString3, mpImpl->msString1, !mpImpl->msString1.isEmpty() ? SvxURLFormat::Repr : SvxURLFormat::Url ) );
|
||||
static_cast<SvxURLField*>(pData.get())->SetTargetFrame( mpImpl->msString2 );
|
||||
static_cast<SvxURLField*>(pData.get())->SetName( mpImpl->msString4 );
|
||||
if( static_cast<SvxURLFormat>(mpImpl->mnInt16) >= SvxURLFormat::AppDefault &&
|
||||
static_cast<SvxURLFormat>(mpImpl->mnInt16) <= SvxURLFormat::Repr )
|
||||
static_cast<SvxURLField*>(pData.get())->SetFormat( static_cast<SvxURLFormat>(mpImpl->mnInt16) );
|
||||
@@ -722,6 +727,10 @@ void SAL_CALL SvxUnoTextField::setPropertyValue( const OUString& aPropertyName,
|
||||
if(aValue >>= mpImpl->msString3)
|
||||
return;
|
||||
break;
|
||||
case WID_STRING4:
|
||||
if(aValue >>= mpImpl->msString4)
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
throw lang::IllegalArgumentException();
|
||||
@@ -769,6 +778,9 @@ uno::Any SAL_CALL SvxUnoTextField::getPropertyValue( const OUString& PropertyNam
|
||||
case WID_STRING3:
|
||||
aValue <<= mpImpl->msString3;
|
||||
break;
|
||||
case WID_STRING4:
|
||||
aValue <<= mpImpl->msString4;
|
||||
break;
|
||||
}
|
||||
|
||||
return aValue;
|
||||
|
||||
@@ -348,6 +348,17 @@ namespace emfio
|
||||
return Size( nW, nH );
|
||||
}
|
||||
|
||||
// The number of points that fit in a record of nRecordSize words. A record starts with
|
||||
// three words of header followed by nParameterWords of other parameters, and each point
|
||||
// takes two words.
|
||||
static sal_uInt32 MaxPointsInRecord(sal_uInt32 nRecordSize, sal_uInt32 nParameterWords)
|
||||
{
|
||||
const sal_uInt32 nUsedWords = 3 + nParameterWords;
|
||||
if (nRecordSize <= nUsedWords)
|
||||
return 0;
|
||||
return (nRecordSize - nUsedWords) / 2;
|
||||
}
|
||||
|
||||
void WmfReader::ReadRecordParams( sal_uInt32 nRecordSize, sal_uInt16 nFunc )
|
||||
{
|
||||
bool bRecordOk = true;
|
||||
@@ -575,7 +586,7 @@ namespace emfio
|
||||
sal_uInt16 nPoints(0);
|
||||
mpInputStream->ReadUInt16(nPoints);
|
||||
|
||||
if (nPoints > mpInputStream->remainingSize() / (2 * sizeof(sal_uInt16)))
|
||||
if (nPoints > MaxPointsInRecord(nRecordSize, 1))
|
||||
{
|
||||
bRecordOk = false;
|
||||
}
|
||||
@@ -600,7 +611,9 @@ namespace emfio
|
||||
mpInputStream->ReadUInt16( nPolyCount );
|
||||
if (nPolyCount && mpInputStream->good())
|
||||
{
|
||||
if (nPolyCount > mpInputStream->remainingSize() / sizeof(sal_uInt16))
|
||||
// One word per polygon holds its point count, and those words sit between
|
||||
// the polygon count and the points themselves.
|
||||
if (nRecordSize < 4 || nPolyCount > nRecordSize - 4)
|
||||
break;
|
||||
|
||||
// Number of points of each polygon. Determine total number of points
|
||||
@@ -623,6 +636,12 @@ namespace emfio
|
||||
|
||||
SAL_WARN_IF(!bRecordOk, "emfio", "polypolygon record has more polygons than we can handle");
|
||||
|
||||
if (nPoints > MaxPointsInRecord(nRecordSize, 1 + nPolyCount))
|
||||
{
|
||||
SAL_WARN("emfio", "polypolygon record has more points than it can hold");
|
||||
bRecordOk = false;
|
||||
}
|
||||
|
||||
bRecordOk &= mpInputStream->good();
|
||||
|
||||
if (!bRecordOk)
|
||||
@@ -665,7 +684,7 @@ namespace emfio
|
||||
sal_uInt16 nPoints(0);
|
||||
mpInputStream->ReadUInt16(nPoints);
|
||||
|
||||
if (nPoints > mpInputStream->remainingSize() / (2 * sizeof(sal_uInt16)))
|
||||
if (nPoints > MaxPointsInRecord(nRecordSize, 1))
|
||||
{
|
||||
bRecordOk = false;
|
||||
}
|
||||
|
||||
+1
@@ -30,6 +30,7 @@ $(eval $(call gb_UnpackedTarball_add_patches,cairo,\
|
||||
external/cairo/cairo/avoid-negative-left-shift.patch.1 \
|
||||
external/cairo/cairo/ubsan-memcpy-nullptr.patch.1 \
|
||||
external/cairo/cairo/ubsan-memcpy-nullptr2.patch.1 \
|
||||
external/cairo/cairo/cairo.ofz516227797-Integer-overflow.patch.1 \
|
||||
external/cairo/cairo/Wincompatible-pointer-types.patch.0 \
|
||||
external/cairo/cairo/disable-cairo-utilities.patch.1 \
|
||||
))
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
diff -ur cairo.org/src/cairo-spline.c cairo/src/cairo-spline.c
|
||||
--- cairo.org/src/cairo-spline.c 2026-09-13 14:29:04.468307688 +0000
|
||||
+++ cairo/src/cairo-spline.c 2026-09-13 14:29:04.482278900 +0000
|
||||
@@ -141,8 +141,10 @@
|
||||
static void
|
||||
_lerp_half (const cairo_point_t *a, const cairo_point_t *b, cairo_point_t *result)
|
||||
{
|
||||
- result->x = a->x + ((b->x - a->x) >> 1);
|
||||
- result->y = a->y + ((b->y - a->y) >> 1);
|
||||
+ /* The midpoint lies between the two points, so the result fits in a
|
||||
+ * cairo_fixed_t even when the distance between them does not. */
|
||||
+ result->x = (cairo_fixed_t) ((int64_t) a->x + (((int64_t) b->x - a->x) >> 1));
|
||||
+ result->y = (cairo_fixed_t) ((int64_t) a->y + (((int64_t) b->y - a->y) >> 1));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -181,11 +183,11 @@
|
||||
* and c control points and the segment a-b. The maximum of these two
|
||||
* distances will be our approximation error. */
|
||||
|
||||
- bdx = _cairo_fixed_to_double (knots->b.x - knots->a.x);
|
||||
- bdy = _cairo_fixed_to_double (knots->b.y - knots->a.y);
|
||||
+ bdx = _cairo_fixed_to_double (knots->b.x) - _cairo_fixed_to_double (knots->a.x);
|
||||
+ bdy = _cairo_fixed_to_double (knots->b.y) - _cairo_fixed_to_double (knots->a.y);
|
||||
|
||||
- cdx = _cairo_fixed_to_double (knots->c.x - knots->a.x);
|
||||
- cdy = _cairo_fixed_to_double (knots->c.y - knots->a.y);
|
||||
+ cdx = _cairo_fixed_to_double (knots->c.x) - _cairo_fixed_to_double (knots->a.x);
|
||||
+ cdy = _cairo_fixed_to_double (knots->c.y) - _cairo_fixed_to_double (knots->a.y);
|
||||
|
||||
if (knots->a.x != knots->d.x || knots->a.y != knots->d.y) {
|
||||
/* Intersection point (px):
|
||||
@@ -197,8 +199,8 @@
|
||||
|
||||
double dx, dy, u, v;
|
||||
|
||||
- dx = _cairo_fixed_to_double (knots->d.x - knots->a.x);
|
||||
- dy = _cairo_fixed_to_double (knots->d.y - knots->a.y);
|
||||
+ dx = _cairo_fixed_to_double (knots->d.x) - _cairo_fixed_to_double (knots->a.x);
|
||||
+ dy = _cairo_fixed_to_double (knots->d.y) - _cairo_fixed_to_double (knots->a.y);
|
||||
v = dx * dx + dy * dy;
|
||||
|
||||
u = bdx * dx + bdy * dy;
|
||||
+2
-2
@@ -16,11 +16,11 @@ $(eval $(call gb_ExternalPackage_add_file,firebird,$(LIBO_LIB_FOLDER)/ifbclient.
|
||||
$(eval $(call gb_ExternalPackage_add_file,firebird,$(LIBO_LIB_FOLDER)/Engine12.dll,gen/$(if $(ENABLE_DEBUG),Debug,Release)/firebird/plugins/Engine12.dll))
|
||||
$(eval $(call gb_ExternalPackage_add_file,firebird,$(LIBO_LIB_FOLDER)/intl/fbintl.dll,gen/$(if $(ENABLE_DEBUG),Debug,Release)/firebird/intl/fbintl.dll))
|
||||
else ifeq ($(OS),MACOSX)
|
||||
$(eval $(call gb_ExternalPackage_add_file,firebird,$(LIBO_LIB_FOLDER)/libfbclient.dylib.3.0.13,gen/$(if $(ENABLE_DEBUG),Debug,Release)/firebird/lib/libfbclient.dylib.3.0.13))
|
||||
$(eval $(call gb_ExternalPackage_add_file,firebird,$(LIBO_LIB_FOLDER)/libfbclient.dylib.3.0.14,gen/$(if $(ENABLE_DEBUG),Debug,Release)/firebird/lib/libfbclient.dylib.3.0.14))
|
||||
$(eval $(call gb_ExternalPackage_add_file,firebird,$(LIBO_LIB_FOLDER)/libEngine12.dylib,gen/$(if $(ENABLE_DEBUG),Debug,Release)/firebird/plugins/libEngine12.dylib))
|
||||
$(eval $(call gb_ExternalPackage_add_file,firebird,$(LIBO_LIB_FOLDER)/intl/libfbintl.dylib,gen/$(if $(ENABLE_DEBUG),Debug,Release)/firebird/intl/libfbintl.dylib))
|
||||
else ifeq ($(DISABLE_DYNLOADING),)
|
||||
$(eval $(call gb_ExternalPackage_add_file,firebird,$(LIBO_LIB_FOLDER)/libfbclient.so.2,gen/$(if $(ENABLE_DEBUG),Debug,Release)/firebird/lib/libfbclient.so.3.0.13))
|
||||
$(eval $(call gb_ExternalPackage_add_file,firebird,$(LIBO_LIB_FOLDER)/libfbclient.so.2,gen/$(if $(ENABLE_DEBUG),Debug,Release)/firebird/lib/libfbclient.so.3.0.14))
|
||||
$(eval $(call gb_ExternalPackage_add_file,firebird,$(LIBO_LIB_FOLDER)/libEngine12.so,gen/$(if $(ENABLE_DEBUG),Debug,Release)/firebird/plugins/libEngine12.so))
|
||||
$(eval $(call gb_ExternalPackage_add_file,firebird,$(LIBO_LIB_FOLDER)/intl/libfbintl.so,gen/$(if $(ENABLE_DEBUG),Debug,Release)/firebird/intl/libfbintl.so))
|
||||
endif
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ $(eval $(call gb_ExternalProject_register_targets,firebird,\
|
||||
))
|
||||
|
||||
firebird_BUILDDIR = $(EXTERNAL_WORKDIR)/gen/$(if $(ENABLE_DEBUG),Debug,Release)/firebird
|
||||
firebird_VERSION := 3.0.13
|
||||
firebird_VERSION := 3.0.14
|
||||
|
||||
$(call gb_ExternalProject_get_state_target,firebird,build):
|
||||
$(call gb_Trace_StartRange,firebird,EXTERNAL)
|
||||
|
||||
@@ -47,7 +47,6 @@ $(eval $(call gb_UnpackedTarball_add_patches,firebird,\
|
||||
external/firebird/0001-extern-cloop-Missing-dependency-of-BIN_DIR-cloop-on-.patch.1 \
|
||||
external/firebird/msvc.patch \
|
||||
external/firebird/wnt-per-process-trace-storage.patch.1 \
|
||||
external/firebird/configure-c99.patch \
|
||||
external/firebird/Wincompatible-function-pointer-types.patch \
|
||||
external/firebird/0001-Revert-Backported-fix-for-7122-Invalid-state-of-mapp.patch.1 \
|
||||
external/firebird/0001-Revert-Fix-for-most-cases-of-7522-7828.patch.1 \
|
||||
|
||||
-45
@@ -1,45 +0,0 @@
|
||||
--- configure
|
||||
+++ configure
|
||||
@@ -20687,8 +20687,9 @@
|
||||
else
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
+#include <stdlib.h>
|
||||
#include <semaphore.h>
|
||||
- main () {
|
||||
+ int main () {
|
||||
sem_t s;
|
||||
return sem_init(&s,0,0);
|
||||
}
|
||||
@@ -21432,8 +21433,9 @@
|
||||
else
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
+#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
- main () {
|
||||
+ int main () {
|
||||
return !(sizeof(off_t) == 8);
|
||||
}
|
||||
_ACEOF
|
||||
@@ -21647,8 +21649,9 @@
|
||||
else
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
+#include <stdlib.h>
|
||||
#include <semaphore.h>
|
||||
-main () {
|
||||
+int main () {
|
||||
struct s {
|
||||
char a;
|
||||
union { long long x; sem_t y; } b;
|
||||
@@ -21683,7 +21686,8 @@
|
||||
else
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
-main () {
|
||||
+#include <stdlib.h>
|
||||
+int main () {
|
||||
struct s {
|
||||
char a;
|
||||
double b;
|
||||
+2
-2
@@ -29,10 +29,10 @@
|
||||
|
||||
--- configure 2023-11-11 02:44:14.576802800 +0900
|
||||
+++ configure 2023-11-11 02:59:09.005211200 +0900
|
||||
@@ -21650,11 +21650,10 @@
|
||||
@@ -21674,11 +21674,10 @@
|
||||
else
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
#include <stdlib.h>
|
||||
-#include <semaphore.h>
|
||||
int main () {
|
||||
struct s {
|
||||
|
||||
+1
@@ -33,6 +33,7 @@ $(eval $(call gb_StaticLibrary_add_generated_exception_objects,hunspell,\
|
||||
UnpackedTarball/hunspell/src/hunspell/hashmgr \
|
||||
UnpackedTarball/hunspell/src/hunspell/suggestmgr \
|
||||
UnpackedTarball/hunspell/src/hunspell/phonet \
|
||||
UnpackedTarball/hunspell/src/hunspell/hunspelltrace \
|
||||
UnpackedTarball/hunspell/src/hunspell/hunzip \
|
||||
UnpackedTarball/hunspell/src/hunspell/filemgr \
|
||||
UnpackedTarball/hunspell/src/hunspell/replist \
|
||||
|
||||
+2
-2
@@ -16,9 +16,9 @@ ifeq ($(OS),MACOSX)
|
||||
$(eval $(call gb_ExternalPackage_add_file,libxml2,$(LIBO_URE_LIB_FOLDER)/libxml2.16.dylib,.libs/libxml2.16.dylib))
|
||||
else ifeq ($(OS),WNT)
|
||||
ifeq ($(COM),GCC)
|
||||
$(eval $(call gb_ExternalPackage_add_file,libxml2,$(LIBO_URE_LIB_FOLDER)/libxml2$(if $(MSVC_USE_DEBUG_RUNTIME),d).dll,$(if $(MSVC_USE_DEBUG_RUNTIME),Debug,Release)/libxml2$(if $(MSVC_USE_DEBUG_RUNTIME),d).dll))
|
||||
$(eval $(call gb_ExternalPackage_add_file,libxml2,$(LIBO_URE_LIB_FOLDER)/libxml2$(if $(MSVC_USE_DEBUG_RUNTIME),d).dll,libxml2$(if $(MSVC_USE_DEBUG_RUNTIME),d).dll))
|
||||
else # COM=MSC
|
||||
$(eval $(call gb_ExternalPackage_add_file,libxml2,$(LIBO_URE_LIB_FOLDER)/libxml2$(if $(MSVC_USE_DEBUG_RUNTIME),d).dll,$(if $(MSVC_USE_DEBUG_RUNTIME),Debug,Release)/libxml2$(if $(MSVC_USE_DEBUG_RUNTIME),d).dll))
|
||||
$(eval $(call gb_ExternalPackage_add_file,libxml2,$(LIBO_URE_LIB_FOLDER)/libxml2$(if $(MSVC_USE_DEBUG_RUNTIME),d).dll,libxml2$(if $(MSVC_USE_DEBUG_RUNTIME),d).dll))
|
||||
endif
|
||||
else # OS!=WNT
|
||||
$(eval $(call gb_ExternalPackage_add_file,libxml2,$(LIBO_URE_LIB_FOLDER)/libxml2.so.16,.libs/libxml2.so.16.1.$(LIBXML_VERSION_MICRO)))
|
||||
|
||||
+10
-6
@@ -25,11 +25,15 @@ $(call gb_ExternalProject_use_external_project,libxml2,icu)
|
||||
# workdir\UnpackedTarball\libxml2\version(1): error C2059: syntax error: 'constant
|
||||
$(call gb_ExternalProject_get_state_target,libxml2,build):
|
||||
$(call gb_Trace_StartRange,libxml2,EXTERNAL)
|
||||
$(call gb_ExternalProject_run,build,\
|
||||
$(CMAKE) . \
|
||||
$(if $(filter 17.%,$(VCVER)),-G "Visual Studio 17 2022") \
|
||||
$(if $(filter 18.%,$(VCVER)),-G "Visual Studio 18 2026") \
|
||||
-A $(gb_MSBUILD_PLATFORM) \
|
||||
+$(call gb_ExternalProject_run,build,\
|
||||
export INCLUDE="$(gb_ExternalProject_INCLUDE)" \
|
||||
&& export LIB="$(ILIB)" \
|
||||
&& $(CMAKE) . \
|
||||
-G Ninja \
|
||||
-DCMAKE_MAKE_PROGRAM=$(NINJA) \
|
||||
-DCMAKE_BUILD_TYPE=$(if $(MSVC_USE_DEBUG_RUNTIME),Debug,Release) \
|
||||
-DCMAKE_C_COMPILER=$(lastword $(filter-out -%,$(CC))) \
|
||||
$(if $(CCACHE),-DCMAKE_C_COMPILER_LAUNCHER=$(CCACHE)) \
|
||||
-DLIBXML2_WITH_TESTS=OFF \
|
||||
-DLIBXML2_WITH_ICONV=OFF \
|
||||
-DLIBXML2_WITH_PYTHON=OFF \
|
||||
@@ -40,7 +44,7 @@ $(call gb_ExternalProject_get_state_target,libxml2,build):
|
||||
$(if $(MSVC_USE_DEBUG_RUNTIME), \
|
||||
-DICU_UC_LIBRARY_DEBUG=$(gb_UnpackedTarball_workdir)/icu/source/lib/icuucd.lib, \
|
||||
-DICU_UC_LIBRARY_RELEASE=$(gb_UnpackedTarball_workdir)/icu/source/lib/icuuc.lib) \
|
||||
&& $(CMAKE) --build . --config $(if $(MSVC_USE_DEBUG_RUNTIME),Debug,Release) \
|
||||
&& $(CMAKE) --build . \
|
||||
&& rm VERSION \
|
||||
)
|
||||
$(call gb_Trace_EndRange,libxml2,EXTERNAL)
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ $(call gb_ExternalProject_get_state_target,libxslt,build):
|
||||
$(if $(MSVC_USE_DEBUG_RUNTIME),cruntime=/MDd) \
|
||||
$(if $(filter TRUE,$(ENABLE_DBGUTIL)),debug=yes) \
|
||||
vcmanifest=yes \
|
||||
lib=$(gb_UnpackedTarball_workdir)/libxml2/$(if $(MSVC_USE_DEBUG_RUNTIME),Debug,Release) \
|
||||
lib=$(gb_UnpackedTarball_workdir)/libxml2 \
|
||||
&& nmake \
|
||||
,win32)
|
||||
$(call gb_Trace_EndRange,libxslt,EXTERNAL)
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
|
||||
#
|
||||
# This file is part of the LibreOffice project.
|
||||
#
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
#
|
||||
|
||||
$(eval $(call gb_ExternalPackage_ExternalPackage,fonts_scheherazade,font_scheherazade))
|
||||
|
||||
$(eval $(call gb_ExternalPackage_add_unpacked_files,fonts_scheherazade,$(LIBO_SHARE_FOLDER)/fonts/truetype,\
|
||||
Scheherazade-Bold.ttf \
|
||||
Scheherazade-Regular.ttf \
|
||||
))
|
||||
|
||||
# vim: set noet sw=4 ts=4:
|
||||
-2
@@ -35,7 +35,6 @@ $(eval $(call gb_Module_add_targets,more_fonts,\
|
||||
ExternalPackage_noto_serif_hebrew \
|
||||
ExternalPackage_noto_serif_lao \
|
||||
ExternalPackage_reem \
|
||||
ExternalPackage_scheherazade \
|
||||
UnpackedTarball_alef \
|
||||
UnpackedTarball_amiri \
|
||||
UnpackedTarball_caladea \
|
||||
@@ -61,7 +60,6 @@ $(eval $(call gb_Module_add_targets,more_fonts,\
|
||||
UnpackedTarball_noto_serif_hebrew \
|
||||
UnpackedTarball_noto_serif_lao \
|
||||
UnpackedTarball_reem \
|
||||
UnpackedTarball_scheherazade \
|
||||
))
|
||||
|
||||
# vim: set noet sw=4 ts=4:
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
|
||||
#
|
||||
# This file is part of the LibreOffice project.
|
||||
#
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
#
|
||||
|
||||
$(eval $(call gb_UnpackedTarball_UnpackedTarball,font_scheherazade))
|
||||
|
||||
$(eval $(call gb_UnpackedTarball_set_tarball,font_scheherazade,$(FONT_SCHEHERAZADE_TARBALL)))
|
||||
|
||||
# vim: set noet sw=4 ts=4:
|
||||
Vendored
+2
@@ -44,6 +44,7 @@ $(call gb_ExternalProject_get_state_target,nss,build): \
|
||||
NSINSTALL='$(call gb_ExternalExecutable_get_command,python) $(SRCDIR)/external/nss/nsinstall.py' \
|
||||
NSS_DISABLE_GTESTS=1 \
|
||||
NSS_DISABLE_CMD_TOOLS=1 \
|
||||
NSS_DISABLE_NSPR_TESTS=1 \
|
||||
CCC="$(CXX)" \
|
||||
,nss)
|
||||
$(call gb_Trace_EndRange,nss,EXTERNAL)
|
||||
@@ -82,6 +83,7 @@ $(call gb_ExternalProject_get_state_target,nss,build): \
|
||||
$(if $(filter ANDROID,$(OS)),OS_TARGET=Android OS_TARGET_RELEASE=$(ANDROID_API_LEVEL) ARCHFLAG="" DEFAULT_COMPILER=clang ANDROID_NDK=$(ANDROID_NDK_DIR) ANDROID_TOOLCHAIN_VERSION=obsolete ANDROID_PREFIX=$(HOST_PLATFORM) ANDROID_SYSROOT=$(ANDROID_NDK_DIR)/sysroot) \
|
||||
NSS_DISABLE_GTESTS=1 \
|
||||
NSS_DISABLE_CMD_TOOLS=1 \
|
||||
NSS_DISABLE_NSPR_TESTS=1 \
|
||||
nss_build_all \
|
||||
&& rm -f $(gb_UnpackedTarball_workdir)/nss/dist/out/lib/*.a \
|
||||
$(if $(filter MACOSX,$(OS)),\
|
||||
|
||||
Vendored
-8
@@ -50,14 +50,6 @@ diff -ur nss.org/nss/Makefile nss/nss/Makefile
|
||||
--with-android-version=$(OS_TARGET_RELEASE) \
|
||||
--with-android-toolchain=$(ANDROID_TOOLCHAIN) \
|
||||
--with-android-platform=$(ANDROID_SYSROOT)
|
||||
@@ -143,7 +143,6 @@
|
||||
ifndef NSS_DISABLE_NSPR_TESTS
|
||||
build_nspr: $(NSPR_CONFIG_STATUS)
|
||||
$(MAKE) -C $(CORE_DEPTH)/../nspr/$(OBJDIR_NAME)
|
||||
- $(MAKE) -C $(CORE_DEPTH)/../nspr/$(OBJDIR_NAME)/pr/tests
|
||||
else
|
||||
build_nspr: $(NSPR_CONFIG_STATUS)
|
||||
$(MAKE) -C $(CORE_DEPTH)/../nspr/$(OBJDIR_NAME)
|
||||
--- nss/nss/lib/ckfw/builtins/manifest.mn.orig 2019-11-26 15:18:22.185985193 +0100
|
||||
+++ nss/nss/lib/ckfw/builtins/manifest.mn 2019-11-26 15:18:29.281982387 +0100
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
Vendored
-8
@@ -16,14 +16,6 @@
|
||||
endif
|
||||
|
||||
#
|
||||
@@ -141,7 +143,6 @@
|
||||
ifndef NSS_DISABLE_NSPR_TESTS
|
||||
build_nspr: $(NSPR_CONFIG_STATUS)
|
||||
$(MAKE) -C $(CORE_DEPTH)/../nspr/$(OBJDIR_NAME)
|
||||
- $(MAKE) -C $(CORE_DEPTH)/../nspr/$(OBJDIR_NAME)/pr/tests
|
||||
else
|
||||
build_nspr: $(NSPR_CONFIG_STATUS)
|
||||
$(MAKE) -C $(CORE_DEPTH)/../nspr/$(OBJDIR_NAME)
|
||||
--- a/a/nss/lib/ckfw/builtins/manifest.mn
|
||||
+++ a/a/nss/lib/ckfw/builtins/manifest.mn
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
Vendored
+5
-5
@@ -1,10 +1,10 @@
|
||||
--- nss/coreconf/WINNT.mk 2025-03-24 14:11:13.771104127 +0100
|
||||
+++ nss/coreconf/WINNT.mk 2025-03-24 14:11:13.771104127 +0100
|
||||
@@ -15,6 +15,3 @@
|
||||
# Win NT needs -GT so that fibers can work
|
||||
@@ -8,6 +8,3 @@
|
||||
#
|
||||
OS_CFLAGS += -GT
|
||||
|
||||
include $(CORE_DEPTH)/coreconf/WIN32.mk
|
||||
-
|
||||
-# WINNT uses the lib prefix, Win95 doesn't
|
||||
-NSPR31_LIB_PREFIX = lib
|
||||
-# NSPR's WIN95 target prefixes its import libraries only for GCC, like ours.
|
||||
-NSPR31_LIB_PREFIX = $(IMPORT_LIB_PREFIX)
|
||||
|
||||
|
||||
+4
-1
@@ -32,7 +32,10 @@ endif
|
||||
|
||||
# TODO, attempt upstream
|
||||
pdfium_patches += ofz451333752.patch
|
||||
pdfium_patches += extractpatterns.patch
|
||||
# https://pdfium-review.googlesource.com/c/pdfium/+/154910
|
||||
pdfium_patches += extractpatterns-stroke.patch.1
|
||||
# https://pdfium-review.googlesource.com/c/pdfium/+/157490
|
||||
pdfium_patches += extractpatterns-fill.patch.1
|
||||
pdfium_patches += charbboxinflation.patch.1
|
||||
# Hide bundled FreeType symbols
|
||||
pdfium_patches += freetype-hidden-visibility.patch
|
||||
|
||||
+179
@@ -0,0 +1,179 @@
|
||||
From 3e9b2c24c3c35c17ad887f6b415e04163d97ae3c Mon Sep 17 00:00:00 2001
|
||||
Date: Thu, 17 Sep 2026 15:52:06 -0700
|
||||
Subject: [PATCH] Add FPDFPageObj_GetRenderedFillPattern() API
|
||||
|
||||
This is similar to http://pdfium-review.googlesource.com/c/154910, but
|
||||
that one was for stroke patterns and this is for fill patterns.
|
||||
|
||||
Change-Id: I9929e232472fdd974009c64bcb1109d69a813d0a
|
||||
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/157490
|
||||
Commit-Queue: Lei Zhang <thestig@chromium.org>
|
||||
Reviewed-by: Tom Sepez <tsepez@chromium.org>
|
||||
Reviewed-by: Lei Zhang <thestig@chromium.org>
|
||||
---
|
||||
fpdfsdk/fpdf_edit_embeddertest.cpp | 64 ++++++++++++++
|
||||
fpdfsdk/fpdf_editpage.cpp | 79 +++++++++++-------
|
||||
fpdfsdk/fpdf_view_c_api_test.c | 1 +
|
||||
public/fpdf_edit.h | 16 ++++
|
||||
.../resources/embedder_tests/pattern_fill.png | Bin 0 -> 107 bytes
|
||||
.../embedder_tests/pattern_fill_uncolored.png | Bin 0 -> 107 bytes
|
||||
testing/resources/pattern_fill.in | 56 +++++++++++++
|
||||
testing/resources/pattern_fill.pdf | 68 +++++++++++++++
|
||||
testing/resources/pattern_fill_uncolored.in | 58 +++++++++++++
|
||||
testing/resources/pattern_fill_uncolored.pdf | 70 ++++++++++++++++
|
||||
10 files changed, 384 insertions(+), 28 deletions(-)
|
||||
create mode 100644 testing/resources/embedder_tests/pattern_fill.png
|
||||
create mode 100644 testing/resources/embedder_tests/pattern_fill_uncolored.png
|
||||
create mode 100644 testing/resources/pattern_fill.in
|
||||
create mode 100644 testing/resources/pattern_fill.pdf
|
||||
create mode 100644 testing/resources/pattern_fill_uncolored.in
|
||||
create mode 100644 testing/resources/pattern_fill_uncolored.pdf
|
||||
|
||||
diff --git a/fpdfsdk/fpdf_editpage.cpp b/fpdfsdk/fpdf_editpage.cpp
|
||||
index 9b9474ed7..033572048 100644
|
||||
--- a/fpdfsdk/fpdf_editpage.cpp
|
||||
+++ b/fpdfsdk/fpdf_editpage.cpp
|
||||
@@ -199,7 +199,8 @@ ByteString FormatPDFDate(time_t current_time, const tm& local_time) {
|
||||
|
||||
FPDF_BITMAP RenderTilingPatternToBitmap(CPDF_Pattern* pattern,
|
||||
CPDF_Document* doc,
|
||||
- CPDF_PageObject* page_obj) {
|
||||
+ CPDF_PageObject* page_obj,
|
||||
+ bool use_stroke_color) {
|
||||
CPDF_TilingPattern* tiling_pattern = pattern->AsTilingPattern();
|
||||
if (!tiling_pattern) {
|
||||
return nullptr;
|
||||
@@ -228,10 +229,13 @@ FPDF_BITMAP RenderTilingPatternToBitmap(CPDF_Pattern* pattern,
|
||||
return FPDFBitmapFromCFXDIBitmap(cell_bitmap.Leak());
|
||||
}
|
||||
|
||||
- // An uncolored pattern gets its color from the stroke color operands.
|
||||
- const FX_COLORREF stroke_colorref =
|
||||
- page_obj->color_state().GetStrokeColorRef();
|
||||
- if (stroke_colorref == 0xFFFFFFFF) {
|
||||
+ // An uncolored pattern gets its color from the stroke/fill color operands.
|
||||
+ const CPDF_ColorState& color_state = page_obj->color_state();
|
||||
+ const FX_COLORREF colorref =
|
||||
+ use_stroke_color ? color_state.GetStrokeColorRef()
|
||||
+ : color_state.GetFillColorRef();
|
||||
+ // 0xFFFFFFFF is the unusable color, see FX_COLORREF.
|
||||
+ if (colorref == 0xFFFFFFFF) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -240,11 +244,14 @@ FPDF_BITMAP RenderTilingPatternToBitmap(CPDF_Pattern* pattern,
|
||||
FXDIB_Format::kBgra)) {
|
||||
return nullptr;
|
||||
}
|
||||
- const int stroke_alpha =
|
||||
- static_cast<int>(page_obj->general_state().GetStrokeAlpha() * 255);
|
||||
+ const CPDF_GeneralState& general_state = page_obj->general_state();
|
||||
+ const float float_alpha = use_stroke_color
|
||||
+ ? general_state.GetStrokeAlpha()
|
||||
+ : general_state.GetFillAlpha();
|
||||
+ const int alpha = static_cast<int>(float_alpha * 255);
|
||||
if (!result_bitmap->CompositeMask(
|
||||
/*dest_left=*/0, /*dest_top=*/0, rect.Width(), rect.Height(),
|
||||
- cell_bitmap, AlphaAndColorRefToArgb(stroke_alpha, stroke_colorref),
|
||||
+ cell_bitmap, AlphaAndColorRefToArgb(alpha, colorref),
|
||||
/*src_left=*/0, /*src_top=*/0, BlendMode::kNormal)) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -255,6 +262,36 @@ FPDF_BITMAP RenderTilingPatternToBitmap(CPDF_Pattern* pattern,
|
||||
return FPDFBitmapFromCFXDIBitmap(result_bitmap.Leak());
|
||||
}
|
||||
|
||||
+FPDF_BITMAP GetRenderedPattern(FPDF_DOCUMENT document,
|
||||
+ FPDF_PAGEOBJECT page_object,
|
||||
+ bool use_stroke_color) {
|
||||
+ CPDF_Document* doc = CPDFDocumentFromFPDFDocument(document);
|
||||
+ if (!doc) {
|
||||
+ return nullptr;
|
||||
+ }
|
||||
+
|
||||
+ CPDF_PageObject* object = CPDFPageObjectFromFPDFPageObject(page_object);
|
||||
+ if (!object) {
|
||||
+ return nullptr;
|
||||
+ }
|
||||
+
|
||||
+ const CPDF_ColorState& color_state = object->color_state();
|
||||
+ const CPDF_Color* color = use_stroke_color
|
||||
+ ? color_state.GetStrokeColor()
|
||||
+ : color_state.GetFillColor();
|
||||
+ if (!color || !color->IsPattern()) {
|
||||
+ return nullptr;
|
||||
+ }
|
||||
+
|
||||
+ RetainPtr<CPDF_Pattern> pattern = color->GetPattern();
|
||||
+ if (!pattern) {
|
||||
+ return nullptr;
|
||||
+ }
|
||||
+
|
||||
+ return RenderTilingPatternToBitmap(pattern.Get(), doc, object,
|
||||
+ use_stroke_color);
|
||||
+}
|
||||
+
|
||||
} // namespace
|
||||
|
||||
FPDF_EXPORT FPDF_DOCUMENT FPDF_CALLCONV FPDF_CreateNewDocument() {
|
||||
@@ -1261,27 +1298,13 @@ FPDFPageObj_SetDashArray(FPDF_PAGEOBJECT page_object,
|
||||
FPDF_EXPORT FPDF_BITMAP FPDF_CALLCONV
|
||||
FPDFPageObj_GetRenderedStrokePattern(FPDF_DOCUMENT document,
|
||||
FPDF_PAGEOBJECT page_object) {
|
||||
- CPDF_Document* doc = CPDFDocumentFromFPDFDocument(document);
|
||||
- if (!doc) {
|
||||
- return nullptr;
|
||||
- }
|
||||
-
|
||||
- CPDF_PageObject* object = CPDFPageObjectFromFPDFPageObject(page_object);
|
||||
- if (!object) {
|
||||
- return nullptr;
|
||||
- }
|
||||
-
|
||||
- const CPDF_Color* stroke = object->color_state().GetStrokeColor();
|
||||
- if (!stroke || !stroke->IsPattern()) {
|
||||
- return nullptr;
|
||||
- }
|
||||
-
|
||||
- RetainPtr<CPDF_Pattern> pattern = stroke->GetPattern();
|
||||
- if (!pattern) {
|
||||
- return nullptr;
|
||||
- }
|
||||
+ return GetRenderedPattern(document, page_object, /*use_stroke_color=*/true);
|
||||
+}
|
||||
|
||||
- return RenderTilingPatternToBitmap(pattern.Get(), doc, object);
|
||||
+FPDF_EXPORT FPDF_BITMAP FPDF_CALLCONV
|
||||
+FPDFPageObj_GetRenderedFillPattern(FPDF_DOCUMENT document,
|
||||
+ FPDF_PAGEOBJECT page_object) {
|
||||
+ return GetRenderedPattern(document, page_object, /*use_stroke_color=*/false);
|
||||
}
|
||||
|
||||
FPDF_EXPORT int FPDF_CALLCONV
|
||||
diff --git a/public/fpdf_edit.h b/public/fpdf_edit.h
|
||||
index c7fca05a1..77fa19c81 100644
|
||||
--- a/public/fpdf_edit.h
|
||||
+++ b/public/fpdf_edit.h
|
||||
@@ -1206,6 +1206,22 @@ FPDF_EXPORT FPDF_BITMAP FPDF_CALLCONV
|
||||
FPDFPageObj_GetRenderedStrokePattern(FPDF_DOCUMENT document,
|
||||
FPDF_PAGEOBJECT page_object);
|
||||
|
||||
+// Experimental API.
|
||||
+// Get a bitmap rasterization of the fill pattern of |page_object|.
|
||||
+// To render correctly, the caller must provide the |document| associated with
|
||||
+// |page_object|. The returned bitmap will be owned by the caller, and
|
||||
+// FPDFBitmap_Destroy() must be called on the returned bitmap when it is no
|
||||
+// longer needed.
|
||||
+//
|
||||
+// document - handle to the document containing |page_object|.
|
||||
+// page_object - handle to a page object.
|
||||
+//
|
||||
+// Returns the bitmap, or NULL if the fill is not a tiling pattern or on
|
||||
+// failure.
|
||||
+FPDF_EXPORT FPDF_BITMAP FPDF_CALLCONV
|
||||
+FPDFPageObj_GetRenderedFillPattern(FPDF_DOCUMENT document,
|
||||
+ FPDF_PAGEOBJECT page_object);
|
||||
+
|
||||
// Get number of segments inside |path|.
|
||||
//
|
||||
// path - handle to a path.
|
||||
+262
@@ -0,0 +1,262 @@
|
||||
From 7bf42f401237d9096d44f7508beca8690031a98d Mon Sep 17 00:00:00 2001
|
||||
Date: Tue, 8 Sep 2026 16:54:21 -0700
|
||||
Subject: [PATCH] Add FPDFPageObj_GetRenderedStrokePattern() API
|
||||
|
||||
This allows getting the rendered bitmap of a stroke pattern of a page
|
||||
object.
|
||||
|
||||
Change-Id: I4603be175bfe8721d4e11500afcc2be8c2c9f760
|
||||
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/154910
|
||||
Reviewed-by: Lei Zhang <thestig@chromium.org>
|
||||
Reviewed-by: Tom Sepez <tsepez@chromium.org>
|
||||
Commit-Queue: Lei Zhang <thestig@chromium.org>
|
||||
---
|
||||
core/fpdfapi/render/cpdf_rendertiling.cpp | 21 +++--
|
||||
core/fpdfapi/render/cpdf_rendertiling.h | 14 +++
|
||||
fpdfsdk/fpdf_edit_embeddertest.cpp | 64 +++++++++++++
|
||||
fpdfsdk/fpdf_editpage.cpp | 88 ++++++++++++++++++
|
||||
fpdfsdk/fpdf_view_c_api_test.c | 1 +
|
||||
public/fpdf_edit.h | 16 ++++
|
||||
.../embedder_tests/pattern_stroke.png | Bin 0 -> 86 bytes
|
||||
.../pattern_stroke_uncolored.png | Bin 0 -> 86 bytes
|
||||
testing/resources/pattern_stroke.in | 59 ++++++++++++
|
||||
testing/resources/pattern_stroke.pdf | 71 ++++++++++++++
|
||||
testing/resources/pattern_stroke_uncolored.in | 61 ++++++++++++
|
||||
.../resources/pattern_stroke_uncolored.pdf | 73 +++++++++++++++
|
||||
12 files changed, 458 insertions(+), 10 deletions(-)
|
||||
create mode 100644 testing/resources/embedder_tests/pattern_stroke.png
|
||||
create mode 100644 testing/resources/embedder_tests/pattern_stroke_uncolored.png
|
||||
create mode 100644 testing/resources/pattern_stroke.in
|
||||
create mode 100644 testing/resources/pattern_stroke.pdf
|
||||
create mode 100644 testing/resources/pattern_stroke_uncolored.in
|
||||
create mode 100644 testing/resources/pattern_stroke_uncolored.pdf
|
||||
|
||||
diff --git a/core/fpdfapi/render/cpdf_rendertiling.cpp b/core/fpdfapi/render/cpdf_rendertiling.cpp
|
||||
index f407f2403..77027354b 100644
|
||||
--- a/core/fpdfapi/render/cpdf_rendertiling.cpp
|
||||
+++ b/core/fpdfapi/render/cpdf_rendertiling.cpp
|
||||
@@ -26,7 +26,17 @@
|
||||
|
||||
namespace {
|
||||
|
||||
-RetainPtr<CFX_DIBitmap> DrawPatternBitmap(
|
||||
+std::optional<int> CheckedFloatToInt(float value) {
|
||||
+ if (!pdfium::IsValueInRangeForNumericType<int>(value)) {
|
||||
+ return std::nullopt;
|
||||
+ }
|
||||
+ return static_cast<int>(value);
|
||||
+}
|
||||
+
|
||||
+} // namespace
|
||||
+
|
||||
+// static
|
||||
+RetainPtr<CFX_DIBitmap> CPDF_RenderTiling::DrawPatternBitmap(
|
||||
CPDF_Document* doc,
|
||||
CPDF_PageImageCache* pCache,
|
||||
CPDF_TilingPattern* pPattern,
|
||||
@@ -72,15 +82,6 @@ RetainPtr<CFX_DIBitmap> DrawPatternBitmap(
|
||||
return pBitmap;
|
||||
}
|
||||
|
||||
-std::optional<int> CheckedFloatToInt(float value) {
|
||||
- if (!pdfium::IsValueInRangeForNumericType<int>(value)) {
|
||||
- return std::nullopt;
|
||||
- }
|
||||
- return static_cast<int>(value);
|
||||
-}
|
||||
-
|
||||
-} // namespace
|
||||
-
|
||||
// static
|
||||
RetainPtr<CFX_DIBitmap> CPDF_RenderTiling::Draw(
|
||||
CPDF_RenderStatus* pRenderStatus,
|
||||
diff --git a/core/fpdfapi/render/cpdf_rendertiling.h b/core/fpdfapi/render/cpdf_rendertiling.h
|
||||
index 34fb56bf4..2a124461c 100644
|
||||
--- a/core/fpdfapi/render/cpdf_rendertiling.h
|
||||
+++ b/core/fpdfapi/render/cpdf_rendertiling.h
|
||||
@@ -7,11 +7,14 @@
|
||||
#ifndef CORE_FPDFAPI_RENDER_CPDF_RENDERTILING_H_
|
||||
#define CORE_FPDFAPI_RENDER_CPDF_RENDERTILING_H_
|
||||
|
||||
+#include "core/fpdfapi/render/cpdf_renderoptions.h"
|
||||
#include "core/fxcrt/retain_ptr.h"
|
||||
|
||||
class CFX_DIBitmap;
|
||||
class CFX_Matrix;
|
||||
+class CPDF_Document;
|
||||
class CPDF_Form;
|
||||
+class CPDF_PageImageCache;
|
||||
class CPDF_PageObject;
|
||||
class CPDF_RenderStatus;
|
||||
class CPDF_TilingPattern;
|
||||
@@ -27,6 +30,17 @@ class CPDF_RenderTiling {
|
||||
const FX_RECT& clip_box,
|
||||
bool bStroke);
|
||||
|
||||
+ // Renders a single cell of pPattern into a width x height bitmap.
|
||||
+ static RetainPtr<CFX_DIBitmap> DrawPatternBitmap(
|
||||
+ CPDF_Document* doc,
|
||||
+ CPDF_PageImageCache* pCache,
|
||||
+ CPDF_TilingPattern* pPattern,
|
||||
+ CPDF_Form* pPatternForm,
|
||||
+ const CFX_Matrix& mtObject2Device,
|
||||
+ int width,
|
||||
+ int height,
|
||||
+ const CPDF_RenderOptions::Options& draw_options);
|
||||
+
|
||||
CPDF_RenderTiling() = delete;
|
||||
CPDF_RenderTiling(const CPDF_RenderTiling&) = delete;
|
||||
CPDF_RenderTiling& operator=(const CPDF_RenderTiling&) = delete;
|
||||
diff --git a/fpdfsdk/fpdf_editpage.cpp b/fpdfsdk/fpdf_editpage.cpp
|
||||
index 758aae859..9b9474ed7 100644
|
||||
--- a/fpdfsdk/fpdf_editpage.cpp
|
||||
+++ b/fpdfsdk/fpdf_editpage.cpp
|
||||
@@ -25,12 +25,15 @@
|
||||
#include "core/fpdfapi/page/cpdf_pathobject.h"
|
||||
#include "core/fpdfapi/page/cpdf_shadingobject.h"
|
||||
#include "core/fpdfapi/page/cpdf_textobject.h"
|
||||
+#include "core/fpdfapi/page/cpdf_tilingpattern.h"
|
||||
#include "core/fpdfapi/parser/cpdf_array.h"
|
||||
#include "core/fpdfapi/parser/cpdf_dictionary.h"
|
||||
#include "core/fpdfapi/parser/cpdf_document.h"
|
||||
#include "core/fpdfapi/parser/cpdf_number.h"
|
||||
#include "core/fpdfapi/parser/cpdf_string.h"
|
||||
#include "core/fpdfapi/render/cpdf_docrenderdata.h"
|
||||
+#include "core/fpdfapi/render/cpdf_renderoptions.h"
|
||||
+#include "core/fpdfapi/render/cpdf_rendertiling.h"
|
||||
#include "core/fpdfdoc/cpdf_annot.h"
|
||||
#include "core/fpdfdoc/cpdf_annotlist.h"
|
||||
#include "core/fxcrt/compiler_specific.h"
|
||||
@@ -42,6 +45,7 @@
|
||||
#include "core/fxcrt/span_util.h"
|
||||
#include "core/fxcrt/stl_util.h"
|
||||
#include "core/fxcrt/unowned_ptr.h"
|
||||
+#include "core/fxge/dib/cfx_dibitmap.h"
|
||||
#include "fpdfsdk/cpdfsdk_helpers.h"
|
||||
#include "public/fpdf_formfill.h"
|
||||
|
||||
@@ -193,6 +197,64 @@ ByteString FormatPDFDate(time_t current_time, const tm& local_time) {
|
||||
return date;
|
||||
}
|
||||
|
||||
+FPDF_BITMAP RenderTilingPatternToBitmap(CPDF_Pattern* pattern,
|
||||
+ CPDF_Document* doc,
|
||||
+ CPDF_PageObject* page_obj) {
|
||||
+ CPDF_TilingPattern* tiling_pattern = pattern->AsTilingPattern();
|
||||
+ if (!tiling_pattern) {
|
||||
+ return nullptr;
|
||||
+ }
|
||||
+ const std::unique_ptr<CPDF_Form> pattern_form =
|
||||
+ tiling_pattern->Load(page_obj);
|
||||
+ if (!pattern_form) {
|
||||
+ return nullptr;
|
||||
+ }
|
||||
+ const FX_RECT rect = tiling_pattern->bbox().GetOuterRect();
|
||||
+ if (rect.IsEmpty() || !rect.Valid()) {
|
||||
+ return nullptr;
|
||||
+ }
|
||||
+
|
||||
+ RetainPtr<CFX_DIBitmap> cell_bitmap = CPDF_RenderTiling::DrawPatternBitmap(
|
||||
+ doc, /*pCache=*/nullptr, tiling_pattern, pattern_form.get(), CFX_Matrix(),
|
||||
+ rect.Width(), rect.Height(), CPDF_RenderOptions::Options());
|
||||
+ if (!cell_bitmap) {
|
||||
+ return nullptr;
|
||||
+ }
|
||||
+
|
||||
+ if (tiling_pattern->colored()) {
|
||||
+ ValidateBitmapPremultiplyState(cell_bitmap);
|
||||
+
|
||||
+ // Caller takes ownership.
|
||||
+ return FPDFBitmapFromCFXDIBitmap(cell_bitmap.Leak());
|
||||
+ }
|
||||
+
|
||||
+ // An uncolored pattern gets its color from the stroke color operands.
|
||||
+ const FX_COLORREF stroke_colorref =
|
||||
+ page_obj->color_state().GetStrokeColorRef();
|
||||
+ if (stroke_colorref == 0xFFFFFFFF) {
|
||||
+ return nullptr;
|
||||
+ }
|
||||
+
|
||||
+ auto result_bitmap = pdfium::MakeRetain<CFX_DIBitmap>();
|
||||
+ if (!result_bitmap->Create(rect.Width(), rect.Height(),
|
||||
+ FXDIB_Format::kBgra)) {
|
||||
+ return nullptr;
|
||||
+ }
|
||||
+ const int stroke_alpha =
|
||||
+ static_cast<int>(page_obj->general_state().GetStrokeAlpha() * 255);
|
||||
+ if (!result_bitmap->CompositeMask(
|
||||
+ /*dest_left=*/0, /*dest_top=*/0, rect.Width(), rect.Height(),
|
||||
+ cell_bitmap, AlphaAndColorRefToArgb(stroke_alpha, stroke_colorref),
|
||||
+ /*src_left=*/0, /*src_top=*/0, BlendMode::kNormal)) {
|
||||
+ return nullptr;
|
||||
+ }
|
||||
+
|
||||
+ ValidateBitmapPremultiplyState(result_bitmap);
|
||||
+
|
||||
+ // Caller takes ownership.
|
||||
+ return FPDFBitmapFromCFXDIBitmap(result_bitmap.Leak());
|
||||
+}
|
||||
+
|
||||
} // namespace
|
||||
|
||||
FPDF_EXPORT FPDF_DOCUMENT FPDF_CALLCONV FPDF_CreateNewDocument() {
|
||||
@@ -1196,6 +1258,32 @@ FPDFPageObj_SetDashArray(FPDF_PAGEOBJECT page_object,
|
||||
return true;
|
||||
}
|
||||
|
||||
+FPDF_EXPORT FPDF_BITMAP FPDF_CALLCONV
|
||||
+FPDFPageObj_GetRenderedStrokePattern(FPDF_DOCUMENT document,
|
||||
+ FPDF_PAGEOBJECT page_object) {
|
||||
+ CPDF_Document* doc = CPDFDocumentFromFPDFDocument(document);
|
||||
+ if (!doc) {
|
||||
+ return nullptr;
|
||||
+ }
|
||||
+
|
||||
+ CPDF_PageObject* object = CPDFPageObjectFromFPDFPageObject(page_object);
|
||||
+ if (!object) {
|
||||
+ return nullptr;
|
||||
+ }
|
||||
+
|
||||
+ const CPDF_Color* stroke = object->color_state().GetStrokeColor();
|
||||
+ if (!stroke || !stroke->IsPattern()) {
|
||||
+ return nullptr;
|
||||
+ }
|
||||
+
|
||||
+ RetainPtr<CPDF_Pattern> pattern = stroke->GetPattern();
|
||||
+ if (!pattern) {
|
||||
+ return nullptr;
|
||||
+ }
|
||||
+
|
||||
+ return RenderTilingPatternToBitmap(pattern.Get(), doc, object);
|
||||
+}
|
||||
+
|
||||
FPDF_EXPORT int FPDF_CALLCONV
|
||||
FPDFFormObj_CountObjects(FPDF_PAGEOBJECT form_object) {
|
||||
const auto* pObjectList = CPDFPageObjHolderFromFPDFFormObject(form_object);
|
||||
diff --git a/public/fpdf_edit.h b/public/fpdf_edit.h
|
||||
index 8fac863f6..34be3867d 100644
|
||||
--- a/public/fpdf_edit.h
|
||||
+++ b/public/fpdf_edit.h
|
||||
@@ -1190,6 +1190,22 @@ FPDFPageObj_SetDashArray(FPDF_PAGEOBJECT page_object,
|
||||
size_t dash_count,
|
||||
float phase);
|
||||
|
||||
+// Experimental API.
|
||||
+// Get a bitmap rasterization of the stroke pattern of |page_object|.
|
||||
+// To render correctly, the caller must provide the |document| associated with
|
||||
+// |page_object|. The returned bitmap will be owned by the caller, and
|
||||
+// FPDFBitmap_Destroy() must be called on the returned bitmap when it is no
|
||||
+// longer needed.
|
||||
+//
|
||||
+// document - handle to the document containing |page_object|.
|
||||
+// page_object - handle to a page object.
|
||||
+//
|
||||
+// Returns the bitmap, or NULL if the stroke is not a tiling pattern or on
|
||||
+// failure.
|
||||
+FPDF_EXPORT FPDF_BITMAP FPDF_CALLCONV
|
||||
+FPDFPageObj_GetRenderedStrokePattern(FPDF_DOCUMENT document,
|
||||
+ FPDF_PAGEOBJECT page_object);
|
||||
+
|
||||
// Get number of segments inside |path|.
|
||||
//
|
||||
// path - handle to a path.
|
||||
-185
@@ -1,185 +0,0 @@
|
||||
--- core/fpdfapi/page/cpdf_pattern.h 2025-10-17 15:44:08.393532043 +0100
|
||||
+++ core/fpdfapi/page/cpdf_pattern.h 2025-10-17 15:44:12.020459390 +0100
|
||||
@@ -26,6 +26,7 @@
|
||||
virtual CPDF_ShadingPattern* AsShadingPattern();
|
||||
|
||||
const CFX_Matrix& pattern_to_form() const { return pattern_to_form_; }
|
||||
+ RetainPtr<CPDF_Object> pattern_obj() const { return pattern_obj_; }
|
||||
|
||||
protected:
|
||||
CPDF_Pattern(CPDF_Document* doc,
|
||||
@@ -35,7 +36,6 @@
|
||||
|
||||
// All the getters that return pointers return non-NULL pointers.
|
||||
CPDF_Document* document() const { return document_; }
|
||||
- RetainPtr<CPDF_Object> pattern_obj() const { return pattern_obj_; }
|
||||
const CFX_Matrix& parent_matrix() const { return parent_matrix_; }
|
||||
|
||||
void SetPatternToFormMatrix();
|
||||
--- fpdfsdk/fpdf_edittext.cpp 2025-10-17 15:44:08.410532151 +0100
|
||||
+++ fpdfsdk/fpdf_edittext.cpp 2025-10-17 15:55:18.804847559 +0100
|
||||
@@ -13,6 +13,9 @@
|
||||
#include "core/fpdfapi/font/cpdf_cidfont.h"
|
||||
#include "core/fpdfapi/font/cpdf_font.h"
|
||||
#include "core/fpdfapi/page/cpdf_docpagedata.h"
|
||||
+#include "core/fpdfapi/page/cpdf_form.h"
|
||||
+#include "core/fpdfapi/page/cpdf_pathobject.h"
|
||||
+#include "core/fpdfapi/page/cpdf_tilingpattern.h"
|
||||
#include "core/fpdfapi/page/cpdf_textobject.h"
|
||||
#include "core/fpdfapi/page/cpdf_textstate.h"
|
||||
#include "core/fpdfapi/parser/cpdf_array.h"
|
||||
@@ -834,6 +835,110 @@
|
||||
return FPDFBitmapFromCFXDIBitmap(result_bitmap.Leak());
|
||||
}
|
||||
|
||||
+FPDF_BITMAP
|
||||
+FPDFPageObj_GetRenderedPattern(CPDF_Pattern& pattern,
|
||||
+ CPDF_Document& doc,
|
||||
+ CPDF_PageObject& pageObj,
|
||||
+ CPDF_Page* optional_page) {
|
||||
+ CPDF_TilingPattern* pTilingPattern = pattern.AsTilingPattern();
|
||||
+ if (!pTilingPattern)
|
||||
+ return nullptr;
|
||||
+ const std::unique_ptr<CPDF_Form> pPatternForm = pTilingPattern->Load(&pageObj);
|
||||
+ if (!pPatternForm)
|
||||
+ return nullptr;
|
||||
+ RetainPtr<const CPDF_Dictionary> pDict = pattern.pattern_obj()->GetDict();
|
||||
+ CFX_FloatRect pattern_bbox = pDict->GetRectFor("BBox");
|
||||
+
|
||||
+ // `rect` has to use integer values. Round up as needed.
|
||||
+ const FX_RECT rect = pattern_bbox.GetOuterRect();
|
||||
+ if (rect.IsEmpty() || !rect.Valid())
|
||||
+ return nullptr;
|
||||
+
|
||||
+ auto result_bitmap = pdfium::MakeRetain<CFX_DIBitmap>();
|
||||
+ if (!result_bitmap->Create(rect.Width(), rect.Height(),
|
||||
+ FXDIB_Format::kBgra)) {
|
||||
+ return nullptr;
|
||||
+ }
|
||||
+ CFX_FloatRect cell_bbox = pattern.pattern_to_form().TransformRect(pattern_bbox);
|
||||
+ CFX_FloatRect bitmap_rect(0.0f, 0.0f, rect.Width(), rect.Height());
|
||||
+ CFX_Matrix mtPattern2Bitmap;
|
||||
+ mtPattern2Bitmap.MatchRect(bitmap_rect, cell_bbox);
|
||||
+
|
||||
+ auto bitmap_device =
|
||||
+ CFX_RenderDevice::CreateForBitmapWithBackdropAndGroupKnockout(
|
||||
+ result_bitmap, /*backdrop_bitmap=*/nullptr, /*group_knockout=*/true);
|
||||
+ if (!bitmap_device)
|
||||
+ return nullptr;
|
||||
+
|
||||
+ CPDF_RenderOptions options;
|
||||
+ if (!pTilingPattern->colored())
|
||||
+ options.SetColorMode(CPDF_RenderOptions::kAlpha);
|
||||
+ options.GetOptions().bForceHalftone = true;
|
||||
+
|
||||
+ CPDF_RenderContext context(&doc, nullptr, nullptr);
|
||||
+ context.AppendLayer(pPatternForm.get(), mtPattern2Bitmap);
|
||||
+ context.Render(bitmap_device.get(), nullptr, &options, nullptr);
|
||||
+
|
||||
+ CHECK(!result_bitmap->IsPremultiplied());
|
||||
+
|
||||
+ // Caller takes ownership.
|
||||
+ return FPDFBitmapFromCFXDIBitmap(result_bitmap.Leak());
|
||||
+}
|
||||
+
|
||||
+FPDF_EXPORT FPDF_BITMAP FPDF_CALLCONV
|
||||
+FPDFPageObj_GetRenderedStrokePattern(FPDF_DOCUMENT document,
|
||||
+ FPDF_PAGE page,
|
||||
+ FPDF_PAGEOBJECT page_object) {
|
||||
+ CPDF_Document* doc = CPDFDocumentFromFPDFDocument(document);
|
||||
+ if (!doc)
|
||||
+ return nullptr;
|
||||
+
|
||||
+ CPDF_Page* optional_page = CPDFPageFromFPDFPage(page);
|
||||
+ if (optional_page && optional_page->GetDocument() != doc)
|
||||
+ return nullptr;
|
||||
+
|
||||
+ CPDF_PageObject* object = CPDFPageObjectFromFPDFPageObject(page_object);
|
||||
+ if (!object)
|
||||
+ return nullptr;
|
||||
+
|
||||
+ const CPDF_Color* stroke = object->color_state().GetStrokeColor();
|
||||
+ if (!stroke || !stroke->IsPattern())
|
||||
+ return nullptr;
|
||||
+
|
||||
+ RetainPtr<CPDF_Pattern> pattern = stroke->GetPattern();
|
||||
+ if (!pattern)
|
||||
+ return nullptr;
|
||||
+
|
||||
+ return FPDFPageObj_GetRenderedPattern(*pattern, *doc, *object, optional_page);
|
||||
+}
|
||||
+
|
||||
+FPDF_EXPORT FPDF_BITMAP FPDF_CALLCONV
|
||||
+FPDFPageObj_GetRenderedFillPattern(FPDF_DOCUMENT document,
|
||||
+ FPDF_PAGE page,
|
||||
+ FPDF_PAGEOBJECT page_object) {
|
||||
+ CPDF_Document* doc = CPDFDocumentFromFPDFDocument(document);
|
||||
+ if (!doc)
|
||||
+ return nullptr;
|
||||
+
|
||||
+ CPDF_Page* optional_page = CPDFPageFromFPDFPage(page);
|
||||
+ if (optional_page && optional_page->GetDocument() != doc)
|
||||
+ return nullptr;
|
||||
+
|
||||
+ CPDF_PageObject* object = CPDFPageObjectFromFPDFPageObject(page_object);
|
||||
+ if (!object)
|
||||
+ return nullptr;
|
||||
+
|
||||
+ const CPDF_Color* fill = object->color_state().GetFillColor();
|
||||
+ if (!fill || !fill->IsPattern())
|
||||
+ return nullptr;
|
||||
+
|
||||
+ RetainPtr<CPDF_Pattern> pattern = fill->GetPattern();
|
||||
+ if (!pattern)
|
||||
+ return nullptr;
|
||||
+
|
||||
+ return FPDFPageObj_GetRenderedPattern(*pattern, *doc, *object, optional_page);
|
||||
+}
|
||||
+
|
||||
FPDF_EXPORT void FPDF_CALLCONV FPDFFont_Close(FPDF_FONT font) {
|
||||
// Take back ownership from caller and release.
|
||||
RetainPtr<CPDF_Font>().Unleak(CPDFFontFromFPDFFont(font));
|
||||
--- public/fpdf_edit.h 2025-10-17 15:44:08.415888612 +0100
|
||||
+++ public/fpdf_edit.h 2025-10-17 15:44:12.022555158 +0100
|
||||
@@ -1417,6 +1417,41 @@
|
||||
float scale);
|
||||
|
||||
// Experimental API.
|
||||
+// Get a bitmap rasterization of the stroke pattern of |page object|.
|
||||
+// To render correctly, the caller must provide the |document| associated with
|
||||
+// |page_object|. If there is a |page| associated with |page_object|, the
|
||||
+// caller should provide that as well. The returned bitmap will be owned by
|
||||
+// the caller, and FPDFBitmap_Destroy() must be called on the returned bitmap
|
||||
+// when it is no longer needed.
|
||||
+//
|
||||
+// document - handle to a document associated with |page_object|.
|
||||
+// page - handle to an optional page associated with |page_object|.
|
||||
+// page_object - handle to a page object.
|
||||
+//
|
||||
+// Returns the bitmap or NULL if the stroke is not a pattern or on failure.
|
||||
+FPDF_EXPORT FPDF_BITMAP FPDF_CALLCONV
|
||||
+FPDFPageObj_GetRenderedStrokePattern(FPDF_DOCUMENT document,
|
||||
+ FPDF_PAGE page,
|
||||
+ FPDF_PAGEOBJECT page_object);
|
||||
+
|
||||
+// Get a bitmap rasterization of the fill pattern of |page object|.
|
||||
+// To render correctly, the caller must provide the |document| associated with
|
||||
+// |page_object|. If there is a |page| associated with |page_object|, the
|
||||
+// caller should provide that as well. The returned bitmap will be owned by
|
||||
+// the caller, and FPDFBitmap_Destroy() must be called on the returned bitmap
|
||||
+// when it is no longer needed.
|
||||
+//
|
||||
+// document - handle to a document associated with |page_object|.
|
||||
+// page - handle to an optional page associated with |page_object|.
|
||||
+// page_object - handle to a page object.
|
||||
+//
|
||||
+// Returns the bitmap or NULL if the fill is not a pattern or on failure.
|
||||
+FPDF_EXPORT FPDF_BITMAP FPDF_CALLCONV
|
||||
+FPDFPageObj_GetRenderedFillPattern(FPDF_DOCUMENT document,
|
||||
+ FPDF_PAGE page,
|
||||
+ FPDF_PAGEOBJECT page_object);
|
||||
+
|
||||
+// Experimental API.
|
||||
// Get the font of a text object.
|
||||
//
|
||||
// text - the handle to the text object.
|
||||
+1
-1
@@ -33,7 +33,7 @@ $(call gb_ExternalProject_get_state_target,xmlsec,build) :
|
||||
$(call gb_Trace_StartRange,xmlsec,EXTERNAL)
|
||||
$(call gb_ExternalProject_run,build,\
|
||||
cscript /e:javascript configure.js crypto=mscng xslt=no iconv=no static=no \
|
||||
lib=$(gb_UnpackedTarball_workdir)/libxml2/$(if $(MSVC_USE_DEBUG_RUNTIME),Debug,Release) \
|
||||
lib=$(gb_UnpackedTarball_workdir)/libxml2 \
|
||||
$(if $(filter TRUE,$(ENABLE_DBGUTIL)),debug=yes cruntime=/MDd) \
|
||||
cflags="$(SOLARINC) $(LIBXML_CFLAGS)" \
|
||||
&& nmake \
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user