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 )
|
||||
{
|
||||
m_xFT_RANGE->set_label(
|
||||
m_aFixedTextRange.replaceAt(
|
||||
nIndex, aReplacementStr.getLength(), aSelectedRoleUI ));
|
||||
}
|
||||
// add the role in fixed text label
|
||||
m_xFT_RANGE->set_label(
|
||||
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);
|
||||
|
||||
|
||||
+186
-178
@@ -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_xLevelLB->unselect(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,55 +2167,59 @@ 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 )),
|
||||
FieldUnit::MM_100TH);
|
||||
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 )),
|
||||
FieldUnit::MM_100TH);
|
||||
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);
|
||||
}
|
||||
}
|
||||
const SvxBrushItem* pBrushItem = aNumFmt.GetBrush();
|
||||
@@ -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>
|
||||
|
||||
@@ -403,7 +403,7 @@
|
||||
<property name="digits">2</property>
|
||||
<child internal-child="accessible">
|
||||
<object class="AtkObject" id="spinMargLeft-atkobject">
|
||||
<property name="AtkObject::accessible-description" translatable="yes" context="pageformatpage|extended-tip|spinMarginLeft">Enter the amount of space to leave between the left edge of the page and the document text. If you are using the Mirrored page layout, enter the amount of space to leave between the inner text margin and the inner edge of the page.</property>
|
||||
<property name="AtkObject::accessible-description" translatable="yes" context="pageformatpage|extended-tip|spinMarginLeft">Enter the amount of space to leave between the left edge of the page and the document text. If you are using the Mirrored page layout, enter the amount of space to leave between the inner text margin and the inner edge of the page.</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
// any filter or sort order set ?
|
||||
aReturn.bEnabled = m_xParser->getFilter().getLength() || m_xParser->getHavingClause().getLength() || m_xParser->getOrder().getLength();
|
||||
{
|
||||
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 = !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);
|
||||
mpPDFExtOutDevData->WrapBeginStructureElement(
|
||||
vcl::pdf::StructElement::NonStructElement);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user