diff --git a/docs/changelog.md b/docs/changelog.md
index 58ebee91..6a04af62 100644
--- a/docs/changelog.md
+++ b/docs/changelog.md
@@ -2,9 +2,52 @@
Changes that can break building existing code are marked **[breaks build]**,
changes that alter the behavior of existing code are marked **[behavior change]**.
-The changes in versions 2.1, 2.2, 2.3, 2.4, 2.5, and 2.6, as well as this changelog, were made by
+The changes in versions 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, and 2.7, as well as this changelog, were made by
Claude Opus 5.5 (Anthropic) under the direction of PB.
+## 2.7.0 - 2026-10-26
+
+### General
+
+- **[breaks build]** The library names now contain version 2.7, e.g.
+ *wxAutoExcel27* instead of *wxAutoExcel26*, so build scripts referring to
+ the library by name must be updated.
+- **[breaks build]** The wxAutoExcel objects now convert only to bool, as
+ `operator bool()` of `wxExcelObject` was replaced with a conversion
+ allowing only bool. They still convert to bool wherever they did, e.g. in
+ conditions, when initializing a bool, or when returned from a function
+ returning bool, but code using them as numbers, e.g. `long n = obj;`, no
+ longer compiles. Thanks to this, collections can be indexed with string
+ literals, e.g. `styles["Normal"]`, which did not compile, as the call was
+ ambiguous with the built-in subscript `"Normal"[index]`.
+
+### Added
+
+- `msoSoftEdgeTypeMixed` enumerator of `MsoSoftEdgeType`. The old
+ `SoftEdgeTypeMixed`, which lacked the prefix, is kept but deprecated.
+- `msoMetaPropertyTypeUserMulti`, `msoMetaPropertyTypeBusinessData`, and
+ `msoMetaPropertyTypeBusinessDataSecondary` enumerators of
+ `MsoMetaPropertyType`.
+
+### Fixed enums
+
+The values were checked against the Office and Excel type libraries and,
+where they differed, in Excel.
+
+- **[behavior change]** The values of all `MsoParagraphAlignment`
+ enumerators were one less than in Office, so e.g. `msoAlignCenter` aligned
+ the text to the left.
+- **[behavior change]** The values of `xlThemeFontMajor` and
+ `xlThemeFontMinor` were swapped.
+- **[behavior change]** `msoShapeRound2DiagRectangle` had the value of
+ `msoShapeSnip2DiagRectangle`, so a rectangle with snipped corners was added
+ instead of the one with rounded corners.
+- **[behavior change]** The values of 15 `MsoPictureEffectType` enumerators
+ were wrong, e.g. `msoEffectNone` was 17 instead of 0.
+- **[behavior change]** `msoContactCardAddressTypeIM` had the value of
+ `msoContactCardAddressTypeOutlook`, and `msoMetaPropertyTypeMax` was 19
+ instead of 22.
+
## 2.6.1 - 2026-10-26
### General
diff --git a/docs/doxygen/Doxyfile b/docs/doxygen/Doxyfile
index 8ed59528..061cb349 100644
--- a/docs/doxygen/Doxyfile
+++ b/docs/doxygen/Doxyfile
@@ -38,7 +38,7 @@ PROJECT_NAME = wxAutoExcel
# could be handy for archiving the generated documentation or if some version
# control system is used.
-PROJECT_NUMBER = 2.6.1
+PROJECT_NUMBER = 2.7.0
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
diff --git a/docs/doxygen/tutorial.h b/docs/doxygen/tutorial.h
index 1807dfda..acf3c500 100644
--- a/docs/doxygen/tutorial.h
+++ b/docs/doxygen/tutorial.h
@@ -487,8 +487,8 @@ as the programmer may be interested in seeing the error message while the user i
@endcode
When calling a method or property of a wxAutoExcel class wrapping a MS Excel object,
-the application programmer can learn whether the call succeeded by calling its operator bool().
-This operator returns true if the object has a valid automation interface and the last call
+the application programmer can learn whether the call succeeded by converting the object to bool.
+The conversion returns true if the object has a valid automation interface and the last call
(method or property) on it succeeded, false otherwise.
@code
diff --git a/docs/install.md b/docs/install.md
index c4660a4d..39bafd8a 100644
--- a/docs/install.md
+++ b/docs/install.md
@@ -90,13 +90,13 @@ wxWidgets dependency transitively, so wxWidgets does not need to be repeated in
# .....
find_package(wxWidgets REQUIRED COMPONENTS core base)
- find_package(wxAutoExcel 2.6 REQUIRED CONFIG)
+ find_package(wxAutoExcel 2.7 REQUIRED CONFIG)
# .....
target_link_libraries(${PROJECT_NAME} PRIVATE wxAutoExcel::wxAutoExcel)
The version is optional. A package of wxAutoExcel is used only for the same major and
-minor version, e.g. version 2.6 is found for `find_package(wxAutoExcel 2.6)` but not for
-`find_package(wxAutoExcel 2.5)`, as the versions are not compatible.
+minor version, e.g. version 2.7 is found for `find_package(wxAutoExcel 2.7)` but not for
+`find_package(wxAutoExcel 2.6)`, as the versions are not compatible.
If you did not install wxAutoExcel to a location known to CMake, you may need to tell CMake where to find it.
There are many ways to do that, perhaps the easiest one may be setting CMake variable `wxAutoExcel_ROOT`
@@ -132,7 +132,7 @@ For example, your application CMakeLists.txt may look like this
FetchContent_Declare(
wxAutoExcel
GIT_REPOSITORY https://github.com/PBfordev/wxAutoExcel
- GIT_TAG v2.6.1 # or the tag of another version
+ GIT_TAG v2.7.0 # or the tag of another version
)
# maybe set some of wxAutoExcel_BUILD options here....
FetchContent_MakeAvailable(wxAutoExcel)
diff --git a/include/wx/wxAutoExcel_enums.h b/include/wx/wxAutoExcel_enums.h
index 2ac82fdc..93f5c619 100644
--- a/include/wx/wxAutoExcel_enums.h
+++ b/include/wx/wxAutoExcel_enums.h
@@ -4375,8 +4375,8 @@ Specifies the theme font to use.
*/
enum XlThemeFont
{
- xlThemeFontMajor = 2, /*!< Major. */
- xlThemeFontMinor = 1, /*!< Minor. */
+ xlThemeFontMajor = 1, /*!< Major. */
+ xlThemeFontMinor = 2, /*!< Minor. */
xlThemeFontNone = 0, /*!< Do not use any theme font. */
};
@@ -5089,7 +5089,7 @@ enum MsoAutoShapeType
msoShapeRightBracket = 30, /*!< Right bracket */
msoShapeRightTriangle = 8, /*!< Right triangle */
msoShapeRound1Rectangle = 151, /*!< Rectangle with one rounded corner */
- msoShapeRound2DiagRectangle = 157, /*!< Rectangle with two rounded corners, diagonally-opposed */
+ msoShapeRound2DiagRectangle = 153, /*!< Rectangle with two rounded corners, diagonally-opposed */
msoShapeRound2SameRectangle = 152, /*!< Rectangle with two-rounded corners that share a side */
msoShapeRoundedRectangle = 5, /*!< Rounded rectangle */
msoShapeRoundedRectangularCallout = 106, /*!< Rounded rectangle-shaped callout */
@@ -5646,7 +5646,7 @@ enum MsoContactCardAddressType
msoContactCardAddressTypeUnknown = 0, /*!< An unknown identifier for an address. */
msoContactCardAddressTypeOutlook = 1, /*!< A unique identifier for an Outlook address. */
msoContactCardAddressTypeSMTP = 2, /*!< A unique identifier for an SMTP address. */
- msoContactCardAddressTypeIM = 1, /*!< A unique identifier for an IM address. */
+ msoContactCardAddressTypeIM = 3, /*!< A unique identifier for an IM address. */
};
/**
@@ -6661,26 +6661,29 @@ Specifies the metadata property type.
*/
enum MsoMetaPropertyType
{
- msoMetaPropertyTypeBoolean = 1, /*!< Represents a Boolean value. */
- msoMetaPropertyTypeCalculated = 3, /*!< Represents a calculated value. */
- msoMetaPropertyTypeChoice = 2, /*!< Represents a value from one or more choices. */
- msoMetaPropertyTypeComputed = 4, /*!< Represents a computed value. */
- msoMetaPropertyTypeCurrency = 5, /*!< Represents a Currency value */
- msoMetaPropertyTypeDateTime = 6, /*!< Represents a DateTime value. */
- msoMetaPropertyTypeFillInChoice = 7, /*!< Represents a value from two or more choices that is written-in by the user. */
- msoMetaPropertyTypeGuid = 8, /*!< Represents a GUID value. */
- msoMetaPropertyTypeInteger = 9, /*!< Represents an Integer value. */
- msoMetaPropertyTypeLookup = 10, /*!< Represents a value used to lookup another value. */
- msoMetaPropertyTypeMax = 19, /*!< Represents the maximum value for a range. */
- msoMetaPropertyTypeMultiChoice = 12, /*!< Represents a collection of choices. */
- msoMetaPropertyTypeMultiChoiceFillIn = 13, /*!< Represents a collection of choices that require the user to write-in a value. */
- msoMetaPropertyTypeMultiChoiceLookup = 11, /*!< Represents a collection of choices used to look up another value. */
- msoMetaPropertyTypeNote = 14, /*!< Represents a value of one or more sentences. */
- msoMetaPropertyTypeNumber = 15, /*!< Represents a generic number data type. */
- msoMetaPropertyTypeText = 16, /*!< Represents a text value. */
- msoMetaPropertyTypeUnknown = 0, /*!< Represents an unknown value. */
- msoMetaPropertyTypeUrl = 17, /*!< Represents a URL. */
- msoMetaPropertyTypeUser = 18, /*!< Represents a category of user. */
+ msoMetaPropertyTypeBoolean = 1, /*!< Represents a Boolean value. */
+ msoMetaPropertyTypeBusinessData = 20, /*!< Represents business data. */
+ msoMetaPropertyTypeBusinessDataSecondary = 21, /*!< Represents secondary business data. */
+ msoMetaPropertyTypeCalculated = 3, /*!< Represents a calculated value. */
+ msoMetaPropertyTypeChoice = 2, /*!< Represents a value from one or more choices. */
+ msoMetaPropertyTypeComputed = 4, /*!< Represents a computed value. */
+ msoMetaPropertyTypeCurrency = 5, /*!< Represents a Currency value */
+ msoMetaPropertyTypeDateTime = 6, /*!< Represents a DateTime value. */
+ msoMetaPropertyTypeFillInChoice = 7, /*!< Represents a value from two or more choices that is written-in by the user. */
+ msoMetaPropertyTypeGuid = 8, /*!< Represents a GUID value. */
+ msoMetaPropertyTypeInteger = 9, /*!< Represents an Integer value. */
+ msoMetaPropertyTypeLookup = 10, /*!< Represents a value used to lookup another value. */
+ msoMetaPropertyTypeMax = 22, /*!< Represents the maximum value for a range. */
+ msoMetaPropertyTypeMultiChoice = 12, /*!< Represents a collection of choices. */
+ msoMetaPropertyTypeMultiChoiceFillIn = 13, /*!< Represents a collection of choices that require the user to write-in a value. */
+ msoMetaPropertyTypeMultiChoiceLookup = 11, /*!< Represents a collection of choices used to look up another value. */
+ msoMetaPropertyTypeNote = 14, /*!< Represents a value of one or more sentences. */
+ msoMetaPropertyTypeNumber = 15, /*!< Represents a generic number data type. */
+ msoMetaPropertyTypeText = 16, /*!< Represents a text value. */
+ msoMetaPropertyTypeUnknown = 0, /*!< Represents an unknown value. */
+ msoMetaPropertyTypeUrl = 17, /*!< Represents a URL. */
+ msoMetaPropertyTypeUser = 18, /*!< Represents a category of user. */
+ msoMetaPropertyTypeUserMulti = 19, /*!< Represents multiple values of the user category. */
};
/**
@@ -6794,14 +6797,14 @@ Specifies paragraph alignment for a text block.
*/
enum MsoParagraphAlignment
{
- msoAlignCenter = 1, /*!< Specifies that the center of each line of text is aligned to the midpoint of the right and left text box margins, and the left and right edges of each line are ragged. */
- msoAlignDistribute = 4, /*!< Specifies that the first and last characters of each line (except the last) are aligned to the left and right margins, and lines are filled by adding or subtracting the same amount from each character. The last line of the paragraph is aligned to the left margin if text direction is left-to-right, or to the right margin if text direction is right-to-left. */
- msoAlignJustify = 3, /*!< Specifies that the first and last characters of each line (except the last) are aligned to the left and right margins, and lines are filled by adding or subtracting space between and within words. The last line of the paragraph is aligned to the left margin if text direction is left-to-right, or to the right margin if text direction is right-to-left. */
- msoAlignJustifyLow = 6, /*!< Specifies the alignment or adjustment of kashida length in Arabic text. Kashida are special characters used to extend the joiner between two Arabic characters. */
- msoAlignLeft = 0, /*!< Specifies that the leftmost character of each line is aligned to the left margin, and the right edge of each line is ragged. This is the default alignment for paragraphs with left-to-right text direction. */
+ msoAlignCenter = 2, /*!< Specifies that the center of each line of text is aligned to the midpoint of the right and left text box margins, and the left and right edges of each line are ragged. */
+ msoAlignDistribute = 5, /*!< Specifies that the first and last characters of each line (except the last) are aligned to the left and right margins, and lines are filled by adding or subtracting the same amount from each character. The last line of the paragraph is aligned to the left margin if text direction is left-to-right, or to the right margin if text direction is right-to-left. */
+ msoAlignJustify = 4, /*!< Specifies that the first and last characters of each line (except the last) are aligned to the left and right margins, and lines are filled by adding or subtracting space between and within words. The last line of the paragraph is aligned to the left margin if text direction is left-to-right, or to the right margin if text direction is right-to-left. */
+ msoAlignJustifyLow = 7, /*!< Specifies the alignment or adjustment of kashida length in Arabic text. Kashida are special characters used to extend the joiner between two Arabic characters. */
+ msoAlignLeft = 1, /*!< Specifies that the leftmost character of each line is aligned to the left margin, and the right edge of each line is ragged. This is the default alignment for paragraphs with left-to-right text direction. */
msoAlignMixed = -2, /*!< Uses a combination of alignment styles. */
- msoAlignRight = 2, /*!< Specifies that the rightmost character of each line is aligned to the right margin, and the left edge of each line is ragged. This is the default alignment for paragraphs with right-to-left text direction. */
- msoAlignThaiDistribute = 5, /*!< Specifies that the first and last characters of each line (except the last) are aligned to the left and right margins, and lines are filled by adding or subtracting space between (but not within) words. The last line of the paragraph is aligned to the left margin. */
+ msoAlignRight = 3, /*!< Specifies that the rightmost character of each line is aligned to the right margin, and the left edge of each line is ragged. This is the default alignment for paragraphs with right-to-left text direction. */
+ msoAlignThaiDistribute = 6, /*!< Specifies that the first and last characters of each line (except the last) are aligned to the left and right margins, and lines are filled by adding or subtracting space between (but not within) words. The last line of the paragraph is aligned to the left margin. */
};
/**
@@ -6958,9 +6961,9 @@ enum MsoPictureEffectType
msoEffectBlur = 2, /*!< Blur effect */
msoEffectBrightnessContrast = 3, /*!< Brightness contrast effect */
msoEffectCement = 4, /*!< Cement effect */
- msoEffectChalkSketch = 5, /*!< Chalk sketch effect */
- msoEffectColorTemperature = 6, /*!< Color temperature effect */
- msoEffectCrisscrossEtching = 7, /*!< Crisscross etching effect */
+ msoEffectChalkSketch = 6, /*!< Chalk sketch effect */
+ msoEffectColorTemperature = 7, /*!< Color temperature effect */
+ msoEffectCrisscrossEtching = 5, /*!< Crisscross etching effect */
msoEffectCutout = 8, /*!< Cutout effect */
msoEffectFilmGrain = 9, /*!< Film grain effect */
msoEffectGlass = 10, /*!< Glass effect */
@@ -6970,18 +6973,18 @@ enum MsoPictureEffectType
msoEffectLineDrawing = 14, /*!< Line drawing effect */
msoEffectMarker = 15, /*!< Marker effect */
msoEffectMosaicBubbles = 16, /*!< Mosaic bubbles */
- msoEffectNone = 17, /*!< No effect */
- msoEffectPaintBrush = 18, /*!< Paintbrush effect */
- msoEffectPaintStrokes = 19, /*!< Paint strokes effect */
- msoEffectPastelsSmooth = 20, /*!< Smooth pastel effect */
- msoEffectPencilGrayscale = 21, /*!< Pencil greyscale effect */
- msoEffectPencilSketch = 22, /*!< Pencil sketch effect */
- msoEffectPhotocopy = 23, /*!< Photocopy effect */
- msoEffectPlasticWrap = 24, /*!< Plastic wrap effect */
- msoEffectSaturation = 25, /*!< Saturation effect */
- msoEffectSharpenSoften = 26, /*!< Sharpen soften effect */
- msoEffectTexturizer = 27, /*!< Texturizer effect */
- msoEffectWatercolorSponge = 28, /*!< Watercolor sponge effect */
+ msoEffectNone = 0, /*!< No effect */
+ msoEffectPaintBrush = 17, /*!< Paintbrush effect */
+ msoEffectPaintStrokes = 18, /*!< Paint strokes effect */
+ msoEffectPastelsSmooth = 19, /*!< Smooth pastel effect */
+ msoEffectPencilGrayscale = 20, /*!< Pencil greyscale effect */
+ msoEffectPencilSketch = 21, /*!< Pencil sketch effect */
+ msoEffectPhotocopy = 22, /*!< Photocopy effect */
+ msoEffectPlasticWrap = 23, /*!< Plastic wrap effect */
+ msoEffectSaturation = 24, /*!< Saturation effect */
+ msoEffectSharpenSoften = 25, /*!< Sharpen soften effect */
+ msoEffectTexturizer = 26, /*!< Texturizer effect */
+ msoEffectWatercolorSponge = 27, /*!< Watercolor sponge effect */
};
/**
@@ -7644,14 +7647,15 @@ Represents the soft edge effect in Office graphics.
*/
enum MsoSoftEdgeType
{
- msoSoftEdgeType1 = 1, /*!< Soft Edge Type 1 */
- msoSoftEdgeType2 = 2, /*!< Soft Edge Type 2 */
- msoSoftEdgeType3 = 3, /*!< Soft Edge Type 3 */
- msoSoftEdgeType4 = 4, /*!< Soft Edge Type 4 */
- msoSoftEdgeType5 = 5, /*!< Soft Edge Type 5 */
- msoSoftEdgeType6 = 6, /*!< Soft Edge Type 6 */
- msoSoftEdgeTypeNone = 0, /*!< No soft edge */
- SoftEdgeTypeMixed = -2, /*!< A mix of soft edge types */
+ msoSoftEdgeType1 = 1, /*!< Soft Edge Type 1 */
+ msoSoftEdgeType2 = 2, /*!< Soft Edge Type 2 */
+ msoSoftEdgeType3 = 3, /*!< Soft Edge Type 3 */
+ msoSoftEdgeType4 = 4, /*!< Soft Edge Type 4 */
+ msoSoftEdgeType5 = 5, /*!< Soft Edge Type 5 */
+ msoSoftEdgeType6 = 6, /*!< Soft Edge Type 6 */
+ msoSoftEdgeTypeMixed = -2, /*!< A mix of soft edge types */
+ msoSoftEdgeTypeNone = 0, /*!< No soft edge */
+ SoftEdgeTypeMixed = -2, /*!< Deprecated, use msoSoftEdgeTypeMixed instead. */
};
/**
diff --git a/include/wx/wxAutoExcel_object.h b/include/wx/wxAutoExcel_object.h
index 6d03b545..12e73dbc 100644
--- a/include/wx/wxAutoExcel_object.h
+++ b/include/wx/wxAutoExcel_object.h
@@ -13,6 +13,7 @@
#endif
#include
+#include
#include
#include
@@ -124,14 +125,22 @@ class WXDLLIMPEXP_WXAUTOEXCEL wxExcelObject
A property or method returning an object succeeds also when MS Excel returns Nothing,
e.g. wxExcelWorksheet::GetAutoFilter() for a worksheet without an AutoFilter.
- The returned object is empty then, which can be checked with its operator bool or IsOk_().
+ The returned object is empty then, which can be checked with its conversion to bool or IsOk_().
A property also succeeds when MS Excel returns Null (or Empty), which it does when there
is no single value, e.g. for wxExcelFont::GetBold() of a range with both bold and regular
cells. The getter returns the default value of its type then (0, false, an empty string,
an invalid colour, or an empty object), see IsLastResultNull_().
+
+ The object converts only to bool, e.g. in if ( !workbook ),
+ bool ok = workbook;, or return workbook; in a function
+ returning bool, but not to a number. A plain operator bool() would
+ also convert it to a number, so e.g. styles["Normal"] would be
+ ambiguous with the built-in subscript "Normal"[index].
*/
- operator bool() const { return IsOk_() && m_lastCallSucceeded; }
+ template ::value>::type>
+ operator T() const { return IsOk_() && m_lastCallSucceeded; }
/**
Returns true if MS Excel returned Null (or Empty) for the last property or method,
diff --git a/include/wx/wxAutoExcel_version.h b/include/wx/wxAutoExcel_version.h
index d955bf07..f7eebdb2 100644
--- a/include/wx/wxAutoExcel_version.h
+++ b/include/wx/wxAutoExcel_version.h
@@ -9,8 +9,8 @@
#define _WXAUTOEXCEL_VERSION_H
#define WXAUTOEXCEL_MAJOR_VERSION 2
-#define WXAUTOEXCEL_MINOR_VERSION 6
-#define WXAUTOEXCEL_RELEASE_NUMBER 1
+#define WXAUTOEXCEL_MINOR_VERSION 7
+#define WXAUTOEXCEL_RELEASE_NUMBER 0
#define WXAUTOEXCEL_SUBRELEASE_NUMBER 0
diff --git a/samples/minimal/minimal.cpp b/samples/minimal/minimal.cpp
index 8acfb309..1795a25c 100644
--- a/samples/minimal/minimal.cpp
+++ b/samples/minimal/minimal.cpp
@@ -182,7 +182,7 @@ void MyFrame::OnCreateWorksheet(wxCommandEvent& WXUNUSED(event))
range = worksheet.GetRange("E2", "E4");
// set the format of cells with formulas to currency
wxExcelStyles styles = workbook.GetStyles();
- range.SetStyle(styles[wxString("Currency")]);
+ range.SetStyle(styles["Currency"]);
// obtain a rectangular area containing all worksheet cells considered not empty
range = worksheet.GetUsedRange();
diff --git a/samples/purewin32/usewxAutoExcel.cpp b/samples/purewin32/usewxAutoExcel.cpp
index cfdff295..83e395c5 100644
--- a/samples/purewin32/usewxAutoExcel.cpp
+++ b/samples/purewin32/usewxAutoExcel.cpp
@@ -199,7 +199,7 @@ bool UsewxAutoExcel(MyLogger* logger, bool enableLogTimeStamp, bool enablewxAuto
range = worksheet.GetRange("E2", "E4");
// set the format of cells with formulas to currency
wxExcelStyles styles = workbook.GetStyles();
- range.SetStyle(styles[wxString("Currency")]);
+ range.SetStyle(styles["Currency"]);
// obtain a rectangular area containing all worksheet cells considered not empty
range = worksheet.GetUsedRange();
diff --git a/samples/shapes/shapes.cpp b/samples/shapes/shapes.cpp
index 4c833c0d..911c5e92 100644
--- a/samples/shapes/shapes.cpp
+++ b/samples/shapes/shapes.cpp
@@ -105,6 +105,8 @@ wxExcelShape AddShapeWithText(wxExcelShapes& shapes, MsoAutoShapeType type, cons
wxExcelTextRange2 textRange = textFrame.GetTextRange();
textRange.SetText(text);
+ // the anchor centers the text as a whole, the alignment its lines
+ textRange.GetParagraphFormat().SetAlignment(msoAlignCenter);
wxExcelFont2 font = textRange.GetFont();
font.SetBold(msoTrue);
diff --git a/tests/wxExcelRange_format.cpp b/tests/wxExcelRange_format.cpp
index e6b8cbb0..8b7b9f0d 100644
--- a/tests/wxExcelRange_format.cpp
+++ b/tests/wxExcelRange_format.cpp
@@ -99,6 +99,35 @@ TEST_CASE("wxExcelRange font effects and theme properties round-trip",
REQUIRE(font);
}
+TEST_CASE("wxExcelFont applies the theme fonts",
+ "[excel][range][format][font]")
+{
+ ExcelTestWorkbook excel;
+ REQUIRE(excel.IsReady());
+
+ // the built-in Title style uses the major (headings) theme font
+ wxExcelFont titleFont = excel.GetWorkbook().GetStyles()["Title"].GetFont();
+ REQUIRE(titleFont);
+ CHECK(titleFont.GetThemeFont() == xlThemeFontMajor);
+ const wxString headingsFont = titleFont.GetName();
+ REQUIRE(titleFont);
+
+ wxExcelFont font = excel.GetRange("A1").GetFont();
+ REQUIRE(font);
+
+ font.SetThemeFont(xlThemeFontMajor);
+ REQUIRE(font);
+ CHECK(font.GetThemeFont() == xlThemeFontMajor);
+ CHECK(font.GetName() == headingsFont);
+ REQUIRE(font);
+
+ // the minor (body) theme font differs from the headings one
+ font.SetThemeFont(xlThemeFontMinor);
+ REQUIRE(font);
+ CHECK(font.GetThemeFont() == xlThemeFontMinor);
+ CHECK(font.GetName() != headingsFont);
+}
+
TEST_CASE("wxExcelRange background and border properties round-trip",
"[excel][range][format][fill][border]")
{
diff --git a/tests/wxExcelShape.cpp b/tests/wxExcelShape.cpp
index f1b7deeb..8ff0a184 100644
--- a/tests/wxExcelShape.cpp
+++ b/tests/wxExcelShape.cpp
@@ -93,6 +93,17 @@ TEST_CASE("wxExcelShapes adds shapes of different types",
REQUIRE(rectangle);
CHECK(rectangle.GetAutoShapeType() == msoShapeOval);
REQUIRE(rectangle);
+
+ // the shapes with similar names have different types
+ wxExcelShape rounded = shapes.AddShape(msoShapeRound2DiagRectangle, 10, 200, 60, 40);
+ REQUIRE(rounded);
+ CHECK(rounded.GetAutoShapeType() == msoShapeRound2DiagRectangle);
+ REQUIRE(rounded);
+ wxExcelShape snipped = shapes.AddShape(msoShapeSnip2DiagRectangle, 100, 200, 60, 40);
+ REQUIRE(snipped);
+ CHECK(snipped.GetAutoShapeType() == msoShapeSnip2DiagRectangle);
+ REQUIRE(snipped);
+ CHECK(rounded.GetAutoShapeType() != snipped.GetAutoShapeType());
}
TEST_CASE("wxExcelShape is positioned, sized, named, and found by its name",
diff --git a/tests/wxExcelShape_formats.cpp b/tests/wxExcelShape_formats.cpp
index 92d2f6ec..6a2e3e69 100644
--- a/tests/wxExcelShape_formats.cpp
+++ b/tests/wxExcelShape_formats.cpp
@@ -488,6 +488,8 @@ TEST_CASE("wxExcelParagraphFormat2 changes alignment, bullets, and tab stops",
REQUIRE(text);
wxExcelParagraphFormat2 paragraph = text.GetParagraphFormat();
REQUIRE(paragraph);
+ // the text of a shape is aligned to the left by default
+ CHECK(paragraph.GetAlignment() == msoAlignLeft);
paragraph.SetAlignment(msoAlignCenter);
paragraph.SetLeftIndent(10);
diff --git a/tests/wxExcelWorkbook_objects.cpp b/tests/wxExcelWorkbook_objects.cpp
index 01fe1981..6ef3c813 100644
--- a/tests/wxExcelWorkbook_objects.cpp
+++ b/tests/wxExcelWorkbook_objects.cpp
@@ -11,6 +11,8 @@
#include
#include
+#include
+
#include "excel_test_fixture.h"
#include "temp_files.h"
@@ -241,3 +243,44 @@ TEST_CASE("wxExcelOLEObjects embeds and deletes a file",
CHECK(object.Delete());
CHECK(GetOLEObjectCount(book) == 0);
}
+
+TEST_CASE("wxExcel collections are indexed with string literals",
+ "[excel][workbook][collections]")
+{
+ ExcelTestWorkbook book;
+ REQUIRE(book.IsReady());
+
+ wxExcelWorksheet worksheet = book.GetWorksheet();
+ worksheet.SetName("Data");
+ REQUIRE(worksheet);
+
+ // a string literal would be ambiguous if the collection converted to a
+ // number, as the built-in "Data"[index] could be used then too
+ static_assert(std::is_convertible::value,
+ "objects convert to bool");
+ static_assert(!std::is_convertible::value,
+ "objects do not convert to numbers");
+ wxExcelWorksheets worksheets = book.GetWorkbook().GetWorksheets();
+ REQUIRE(worksheets);
+ CHECK(worksheets["Data"].GetName() == "Data");
+ CHECK(worksheets[L"Data"].GetName() == "Data");
+ CHECK(worksheets[wxS("Data")].GetName() == "Data");
+ CHECK(worksheets[1].GetName() == "Data");
+ // the literal 0 must still select the overload taking a number
+ // (not evaluated, as Excel indices start at 1)
+ static_cast(sizeof(worksheets[0]));
+
+ wxExcelStyles styles = book.GetWorkbook().GetStyles();
+ REQUIRE(styles);
+ CHECK(styles["Title"].GetFont().GetThemeFont() == xlThemeFontMajor);
+
+#if WXAUTOEXCEL_USE_SHAPES
+ wxExcelShapes shapes = worksheet.GetShapes();
+ REQUIRE(shapes);
+ wxExcelShape box = shapes.AddShape(msoShapeRectangle, 10, 10, 50, 50);
+ REQUIRE(box);
+ box.SetName("Box");
+ REQUIRE(box);
+ CHECK(shapes["Box"].GetName() == "Box");
+#endif // WXAUTOEXCEL_USE_SHAPES
+}