xlsxwriter 0.2.1.pre → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (121) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +4 -3
  3. data/ext/xlsxwriter/chart.c +88 -80
  4. data/ext/xlsxwriter/chart.h +2 -2
  5. data/ext/xlsxwriter/chartsheet.c +307 -0
  6. data/ext/xlsxwriter/chartsheet.h +15 -0
  7. data/ext/xlsxwriter/common.h +104 -0
  8. data/ext/xlsxwriter/extconf.rb +8 -8
  9. data/ext/xlsxwriter/libxlsxwriter/License.txt +24 -2
  10. data/ext/xlsxwriter/libxlsxwriter/Makefile +46 -12
  11. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/app.h +1 -1
  12. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/chart.h +196 -30
  13. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/chartsheet.h +3 -3
  14. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/comment.h +76 -0
  15. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/common.h +24 -5
  16. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/content_types.h +5 -1
  17. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/core.h +1 -1
  18. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/custom.h +1 -1
  19. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/drawing.h +6 -17
  20. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/format.h +20 -6
  21. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/hash_table.h +1 -1
  22. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/packager.h +3 -1
  23. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/relationships.h +1 -1
  24. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/shared_strings.h +1 -1
  25. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/styles.h +11 -5
  26. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/theme.h +1 -1
  27. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/third_party/md5.h +43 -0
  28. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/utility.h +42 -3
  29. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/vml.h +55 -0
  30. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/workbook.h +83 -18
  31. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/worksheet.h +1519 -109
  32. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/xmlwriter.h +4 -2
  33. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter.h +3 -2
  34. data/ext/xlsxwriter/libxlsxwriter/src/Makefile +25 -7
  35. data/ext/xlsxwriter/libxlsxwriter/src/app.c +1 -1
  36. data/ext/xlsxwriter/libxlsxwriter/src/chart.c +332 -48
  37. data/ext/xlsxwriter/libxlsxwriter/src/chartsheet.c +20 -19
  38. data/ext/xlsxwriter/libxlsxwriter/src/comment.c +443 -0
  39. data/ext/xlsxwriter/libxlsxwriter/src/content_types.c +20 -1
  40. data/ext/xlsxwriter/libxlsxwriter/src/core.c +2 -2
  41. data/ext/xlsxwriter/libxlsxwriter/src/custom.c +1 -1
  42. data/ext/xlsxwriter/libxlsxwriter/src/drawing.c +58 -20
  43. data/ext/xlsxwriter/libxlsxwriter/src/format.c +98 -25
  44. data/ext/xlsxwriter/libxlsxwriter/src/hash_table.c +1 -1
  45. data/ext/xlsxwriter/libxlsxwriter/src/packager.c +269 -12
  46. data/ext/xlsxwriter/libxlsxwriter/src/relationships.c +1 -1
  47. data/ext/xlsxwriter/libxlsxwriter/src/shared_strings.c +2 -4
  48. data/ext/xlsxwriter/libxlsxwriter/src/styles.c +334 -48
  49. data/ext/xlsxwriter/libxlsxwriter/src/theme.c +1 -1
  50. data/ext/xlsxwriter/libxlsxwriter/src/utility.c +71 -8
  51. data/ext/xlsxwriter/libxlsxwriter/src/vml.c +1032 -0
  52. data/ext/xlsxwriter/libxlsxwriter/src/workbook.c +343 -27
  53. data/ext/xlsxwriter/libxlsxwriter/src/worksheet.c +3759 -478
  54. data/ext/xlsxwriter/libxlsxwriter/src/xmlwriter.c +81 -2
  55. data/ext/xlsxwriter/libxlsxwriter/third_party/md5/Makefile +42 -0
  56. data/ext/xlsxwriter/libxlsxwriter/third_party/md5/md5.c +291 -0
  57. data/ext/xlsxwriter/libxlsxwriter/third_party/md5/md5.h +43 -0
  58. data/ext/xlsxwriter/shared_strings.c +65 -0
  59. data/ext/xlsxwriter/shared_strings.h +15 -0
  60. data/ext/xlsxwriter/workbook.c +96 -20
  61. data/ext/xlsxwriter/worksheet.c +125 -235
  62. data/ext/xlsxwriter/worksheet.h +2 -1
  63. data/ext/xlsxwriter/xlsxwriter.c +4 -0
  64. data/lib/xlsxwriter/rich_string.rb +0 -2
  65. data/lib/xlsxwriter/version.rb +1 -1
  66. data/lib/xlsxwriter/worksheet.rb +2 -2
  67. data/test/{run-test.rb → run_test.rb} +3 -3
  68. data/test/support/chart_test.rb +3 -3
  69. data/test/support/with_xlsx_file.rb +4 -2
  70. data/test/support/xlsx_comparable.rb +40 -26
  71. data/test/test_array_formula.rb +42 -0
  72. data/test/test_autofilter.rb +72 -0
  73. data/test/{test-chart-area.rb → test_chart_area.rb} +2 -2
  74. data/test/{test-chart-axis.rb → test_chart_axis.rb} +16 -16
  75. data/test/test_chart_bar.rb +382 -0
  76. data/test/test_chart_blank.rb +27 -0
  77. data/test/{test-chart-column.rb → test_chart_column.rb} +2 -2
  78. data/test/{test-chart-doughnut.rb → test_chart_doughnut.rb} +2 -2
  79. data/test/{test-chart-legend.rb → test_chart_legend.rb} +2 -2
  80. data/test/{test-chart-pie.rb → test_chart_pie.rb} +2 -2
  81. data/test/{test-chart-scatter.rb → test_chart_scatter.rb} +3 -4
  82. data/test/{test-chart-size.rb → test_chart_size.rb} +2 -2
  83. data/test/{test-chart-title.rb → test_chart_title.rb} +3 -3
  84. data/test/test_chartsheet.rb +201 -0
  85. data/test/{test-data.rb → test_data.rb} +1 -1
  86. data/test/{test-data-validation.rb → test_data_validation.rb} +23 -24
  87. data/test/{test-default-row.rb → test_default_row.rb} +1 -1
  88. data/test/{test-defined-name.rb → test_defined_name.rb} +12 -12
  89. data/test/{test-escapes.rb → test_escapes.rb} +5 -2
  90. data/test/{test-fit-to-pages.rb → test_fit_to_pages.rb} +6 -6
  91. data/test/{test-formatting.rb → test_formatting.rb} +10 -10
  92. data/test/{test-gridlines.rb → test_gridlines.rb} +3 -3
  93. data/test/{test-hyperlink.rb → test_hyperlink.rb} +22 -11
  94. data/test/{test-image.rb → test_image.rb} +6 -4
  95. data/test/{test-macro.rb → test_macro.rb} +1 -1
  96. data/test/{test-merge-range.rb → test_merge_range.rb} +1 -1
  97. data/test/{test-misc.rb → test_misc.rb} +2 -2
  98. data/test/{test-optimize.rb → test_optimize.rb} +2 -4
  99. data/test/{test-outline.rb → test_outline.rb} +14 -14
  100. data/test/{test-page-breaks.rb → test_page_breaks.rb} +2 -2
  101. data/test/{test-page-setup.rb → test_page_setup.rb} +2 -2
  102. data/test/{test-panes.rb → test_panes.rb} +1 -1
  103. data/test/{test-print-area.rb → test_print_area.rb} +3 -3
  104. data/test/{test-print-options.rb → test_print_options.rb} +7 -7
  105. data/test/{test-print-scale.rb → test_print_scale.rb} +2 -2
  106. data/test/{test-properties.rb → test_properties.rb} +2 -2
  107. data/test/{test-protect.rb → test_protect.rb} +3 -3
  108. data/test/{test-repeat.rb → test_repeat.rb} +3 -3
  109. data/test/{test-rich-string.rb → test_rich_string.rb} +5 -9
  110. data/test/{test-row-col-format.rb → test_row_col_format.rb} +1 -1
  111. data/test/{test-ruby-worksheet.rb → test_ruby_worksheet.rb} +2 -2
  112. data/test/{test-set-selection.rb → test_set_selection.rb} +2 -2
  113. data/test/{test-set-start-page.rb → test_set_start_page.rb} +2 -2
  114. data/test/{test-simple.rb → test_simple.rb} +10 -10
  115. data/test/{test-types.rb → test_types.rb} +1 -1
  116. data/test/{xlsx-func-testcase.rb → xlsx_func_testcase.rb} +1 -0
  117. metadata +135 -104
  118. data/test/test-array-formula.rb +0 -35
  119. data/test/test-autofilter.rb +0 -72
  120. data/test/test-chart-bar.rb +0 -74
  121. /data/test/{test-errors.rb → test_errors.rb} +0 -0
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  * libxlsxwriter
3
3
  *
4
- * Copyright 2014-2019, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
4
+ * Copyright 2014-2020, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
5
5
  */
6
6
 
7
7
  /**
@@ -46,7 +46,6 @@
46
46
  #include <stdio.h>
47
47
  #include <stdlib.h>
48
48
  #include <stdint.h>
49
- #include <string.h>
50
49
 
51
50
  #include "shared_strings.h"
52
51
  #include "chart.h"
@@ -55,13 +54,16 @@
55
54
  #include "format.h"
56
55
  #include "styles.h"
57
56
  #include "utility.h"
57
+ #include "relationships.h"
58
58
 
59
- #define LXW_ROW_MAX 1048576
60
- #define LXW_COL_MAX 16384
61
- #define LXW_COL_META_MAX 128
62
- #define LXW_HEADER_FOOTER_MAX 255
63
- #define LXW_MAX_NUMBER_URLS 65530
64
- #define LXW_PANE_NAME_LENGTH 12 /* bottomRight + 1 */
59
+ #define LXW_ROW_MAX 1048576
60
+ #define LXW_COL_MAX 16384
61
+ #define LXW_COL_META_MAX 128
62
+ #define LXW_HEADER_FOOTER_MAX 255
63
+ #define LXW_MAX_NUMBER_URLS 65530
64
+ #define LXW_PANE_NAME_LENGTH 12 /* bottomRight + 1 */
65
+ #define LXW_IMAGE_BUFFER_SIZE 1024
66
+ #define LXW_HEADER_FOOTER_OBJS_MAX 6 /* Header/footer image objs. */
65
67
 
66
68
  /* The Excel 2007 specification says that the maximum number of page
67
69
  * breaks is 1026. However, in practice it is actually 1023. */
@@ -202,6 +204,391 @@ enum lxw_validation_error_types {
202
204
  LXW_VALIDATION_ERROR_TYPE_INFORMATION
203
205
  };
204
206
 
207
+ /** Set the display type for a cell comment. This is hidden by default but
208
+ * can be set to visible with the `worksheet_show_comments()` function. */
209
+ enum lxw_comment_display_types {
210
+ /** Default to the worksheet default which can be hidden or visible.*/
211
+ LXW_COMMENT_DISPLAY_DEFAULT,
212
+
213
+ /** Hide the cell comment. Usually the default. */
214
+ LXW_COMMENT_DISPLAY_HIDDEN,
215
+
216
+ /** Show the cell comment. Can also be set for the worksheet with the
217
+ * `worksheet_show_comments()` function.*/
218
+ LXW_COMMENT_DISPLAY_VISIBLE
219
+ };
220
+
221
+ /** @brief Type definitions for conditional formats.
222
+ *
223
+ * Values used to set the "type" field of conditional format.
224
+ */
225
+ enum lxw_conditional_format_types {
226
+ LXW_CONDITIONAL_TYPE_NONE,
227
+
228
+ /** The Cell type is the most common conditional formatting type. It is
229
+ * used when a format is applied to a cell based on a simple
230
+ * criterion. */
231
+ LXW_CONDITIONAL_TYPE_CELL,
232
+
233
+ /** The Text type is used to specify Excel's "Specific Text" style
234
+ * conditional format. */
235
+ LXW_CONDITIONAL_TYPE_TEXT,
236
+
237
+ /** The Time Period type is used to specify Excel's "Dates Occurring"
238
+ * style conditional format. */
239
+ LXW_CONDITIONAL_TYPE_TIME_PERIOD,
240
+
241
+ /** The Average type is used to specify Excel's "Average" style
242
+ * conditional format. */
243
+ LXW_CONDITIONAL_TYPE_AVERAGE,
244
+
245
+ /** The Duplicate type is used to highlight duplicate cells in a range. */
246
+ LXW_CONDITIONAL_TYPE_DUPLICATE,
247
+
248
+ /** The Unique type is used to highlight unique cells in a range. */
249
+ LXW_CONDITIONAL_TYPE_UNIQUE,
250
+
251
+ /** The Top type is used to specify the top n values by number or
252
+ * percentage in a range. */
253
+ LXW_CONDITIONAL_TYPE_TOP,
254
+
255
+ /** The Bottom type is used to specify the bottom n values by number or
256
+ * percentage in a range. */
257
+ LXW_CONDITIONAL_TYPE_BOTTOM,
258
+
259
+ /** The Blanks type is used to highlight blank cells in a range. */
260
+ LXW_CONDITIONAL_TYPE_BLANKS,
261
+
262
+ /** The No Blanks type is used to highlight non blank cells in a range. */
263
+ LXW_CONDITIONAL_TYPE_NO_BLANKS,
264
+
265
+ /** The Errors type is used to highlight error cells in a range. */
266
+ LXW_CONDITIONAL_TYPE_ERRORS,
267
+
268
+ /** The No Errors type is used to highlight non error cells in a range. */
269
+ LXW_CONDITIONAL_TYPE_NO_ERRORS,
270
+
271
+ /** The Formula type is used to specify a conditional format based on a
272
+ * user defined formula. */
273
+ LXW_CONDITIONAL_TYPE_FORMULA,
274
+
275
+ /** The 2 Color Scale type is used to specify Excel's "2 Color Scale"
276
+ * style conditional format. */
277
+ LXW_CONDITIONAL_2_COLOR_SCALE,
278
+
279
+ /** The 3 Color Scale type is used to specify Excel's "3 Color Scale"
280
+ * style conditional format. */
281
+ LXW_CONDITIONAL_3_COLOR_SCALE,
282
+
283
+ /** The Data Bar type is used to specify Excel's "Data Bar" style
284
+ * conditional format. */
285
+ LXW_CONDITIONAL_DATA_BAR,
286
+
287
+ /** The Icon Set type is used to specify a conditional format with a set
288
+ * of icons such as traffic lights or arrows. */
289
+ LXW_CONDITIONAL_TYPE_ICON_SETS,
290
+
291
+ LXW_CONDITIONAL_TYPE_LAST
292
+ };
293
+
294
+ /** @brief The criteria used in a conditional format.
295
+ *
296
+ * Criteria used to define how a conditional format works.
297
+ */
298
+ enum lxw_conditional_criteria {
299
+ LXW_CONDITIONAL_CRITERIA_NONE,
300
+
301
+ /** Format cells equal to a value. */
302
+ LXW_CONDITIONAL_CRITERIA_EQUAL_TO,
303
+
304
+ /** Format cells not equal to a value. */
305
+ LXW_CONDITIONAL_CRITERIA_NOT_EQUAL_TO,
306
+
307
+ /** Format cells greater than a value. */
308
+ LXW_CONDITIONAL_CRITERIA_GREATER_THAN,
309
+
310
+ /** Format cells less than a value. */
311
+ LXW_CONDITIONAL_CRITERIA_LESS_THAN,
312
+
313
+ /** Format cells greater than or equal to a value. */
314
+ LXW_CONDITIONAL_CRITERIA_GREATER_THAN_OR_EQUAL_TO,
315
+
316
+ /** Format cells less than or equal to a value. */
317
+ LXW_CONDITIONAL_CRITERIA_LESS_THAN_OR_EQUAL_TO,
318
+
319
+ /** Format cells between two values. */
320
+ LXW_CONDITIONAL_CRITERIA_BETWEEN,
321
+
322
+ /** Format cells that is not between two values. */
323
+ LXW_CONDITIONAL_CRITERIA_NOT_BETWEEN,
324
+
325
+ /** Format cells that contain the specified text. */
326
+ LXW_CONDITIONAL_CRITERIA_TEXT_CONTAINING,
327
+
328
+ /** Format cells that don't contain the specified text. */
329
+ LXW_CONDITIONAL_CRITERIA_TEXT_NOT_CONTAINING,
330
+
331
+ /** Format cells that begin with the specified text. */
332
+ LXW_CONDITIONAL_CRITERIA_TEXT_BEGINS_WITH,
333
+
334
+ /** Format cells that end with the specified text. */
335
+ LXW_CONDITIONAL_CRITERIA_TEXT_ENDS_WITH,
336
+
337
+ /** Format cells with a date of yesterday. */
338
+ LXW_CONDITIONAL_CRITERIA_TIME_PERIOD_YESTERDAY,
339
+
340
+ /** Format cells with a date of today. */
341
+ LXW_CONDITIONAL_CRITERIA_TIME_PERIOD_TODAY,
342
+
343
+ /** Format cells with a date of tomorrow. */
344
+ LXW_CONDITIONAL_CRITERIA_TIME_PERIOD_TOMORROW,
345
+
346
+ /** Format cells with a date in the last 7 days. */
347
+ LXW_CONDITIONAL_CRITERIA_TIME_PERIOD_LAST_7_DAYS,
348
+
349
+ /** Format cells with a date in the last week. */
350
+ LXW_CONDITIONAL_CRITERIA_TIME_PERIOD_LAST_WEEK,
351
+
352
+ /** Format cells with a date in the current week. */
353
+ LXW_CONDITIONAL_CRITERIA_TIME_PERIOD_THIS_WEEK,
354
+
355
+ /** Format cells with a date in the next week. */
356
+ LXW_CONDITIONAL_CRITERIA_TIME_PERIOD_NEXT_WEEK,
357
+
358
+ /** Format cells with a date in the last month. */
359
+ LXW_CONDITIONAL_CRITERIA_TIME_PERIOD_LAST_MONTH,
360
+
361
+ /** Format cells with a date in the current month. */
362
+ LXW_CONDITIONAL_CRITERIA_TIME_PERIOD_THIS_MONTH,
363
+
364
+ /** Format cells with a date in the next month. */
365
+ LXW_CONDITIONAL_CRITERIA_TIME_PERIOD_NEXT_MONTH,
366
+
367
+ /** Format cells above the average for the range. */
368
+ LXW_CONDITIONAL_CRITERIA_AVERAGE_ABOVE,
369
+
370
+ /** Format cells below the average for the range. */
371
+ LXW_CONDITIONAL_CRITERIA_AVERAGE_BELOW,
372
+
373
+ /** Format cells above or equal to the average for the range. */
374
+ LXW_CONDITIONAL_CRITERIA_AVERAGE_ABOVE_OR_EQUAL,
375
+
376
+ /** Format cells below or equal to the average for the range. */
377
+ LXW_CONDITIONAL_CRITERIA_AVERAGE_BELOW_OR_EQUAL,
378
+
379
+ /** Format cells 1 standard deviation above the average for the range. */
380
+ LXW_CONDITIONAL_CRITERIA_AVERAGE_1_STD_DEV_ABOVE,
381
+
382
+ /** Format cells 1 standard deviation below the average for the range. */
383
+ LXW_CONDITIONAL_CRITERIA_AVERAGE_1_STD_DEV_BELOW,
384
+
385
+ /** Format cells 2 standard deviation above the average for the range. */
386
+ LXW_CONDITIONAL_CRITERIA_AVERAGE_2_STD_DEV_ABOVE,
387
+
388
+ /** Format cells 2 standard deviation below the average for the range. */
389
+ LXW_CONDITIONAL_CRITERIA_AVERAGE_2_STD_DEV_BELOW,
390
+
391
+ /** Format cells 3 standard deviation above the average for the range. */
392
+ LXW_CONDITIONAL_CRITERIA_AVERAGE_3_STD_DEV_ABOVE,
393
+
394
+ /** Format cells 3 standard deviation below the average for the range. */
395
+ LXW_CONDITIONAL_CRITERIA_AVERAGE_3_STD_DEV_BELOW,
396
+
397
+ /** Format cells in the top of bottom percentage. */
398
+ LXW_CONDITIONAL_CRITERIA_TOP_OR_BOTTOM_PERCENT
399
+ };
400
+
401
+ /** @brief Conditional format rule types.
402
+ *
403
+ * Conditional format rule types that apply to Color Scale and Data Bars.
404
+ */
405
+ enum lxw_conditional_format_rule_types {
406
+ LXW_CONDITIONAL_RULE_TYPE_NONE,
407
+
408
+ /** Conditional format rule type: matches the minimum values in the
409
+ * range. Can only be applied to min_rule_type.*/
410
+ LXW_CONDITIONAL_RULE_TYPE_MINIMUM,
411
+
412
+ /** Conditional format rule type: use a number to set the bound.*/
413
+ LXW_CONDITIONAL_RULE_TYPE_NUMBER,
414
+
415
+ /** Conditional format rule type: use a percentage to set the bound.*/
416
+ LXW_CONDITIONAL_RULE_TYPE_PERCENT,
417
+
418
+ /** Conditional format rule type: use a percentile to set the bound.*/
419
+ LXW_CONDITIONAL_RULE_TYPE_PERCENTILE,
420
+
421
+ /** Conditional format rule type: use a formula to set the bound.*/
422
+ LXW_CONDITIONAL_RULE_TYPE_FORMULA,
423
+
424
+ /** Conditional format rule type: matches the maximum values in the
425
+ * range. Can only be applied to max_rule_type.*/
426
+ LXW_CONDITIONAL_RULE_TYPE_MAXIMUM,
427
+
428
+ /* Used internally for Excel2010 bars. Not documented. */
429
+ LXW_CONDITIONAL_RULE_TYPE_AUTO_MIN,
430
+
431
+ /* Used internally for Excel2010 bars. Not documented. */
432
+ LXW_CONDITIONAL_RULE_TYPE_AUTO_MAX
433
+ };
434
+
435
+ /** @brief Conditional format data bar directions.
436
+ *
437
+ * Values used to set the bar direction of a conditional format data bar.
438
+ */
439
+ enum lxw_conditional_format_bar_direction {
440
+
441
+ /** Data bar direction is set by Excel based on the context of the data
442
+ * displayed. */
443
+ LXW_CONDITIONAL_BAR_DIRECTION_CONTEXT,
444
+
445
+ /** Data bar direction is from right to left. */
446
+ LXW_CONDITIONAL_BAR_DIRECTION_RIGHT_TO_LEFT,
447
+
448
+ /** Data bar direction is from left to right. */
449
+ LXW_CONDITIONAL_BAR_DIRECTION_LEFT_TO_RIGHT
450
+ };
451
+
452
+ /** @brief Conditional format data bar axis options.
453
+ *
454
+ * Values used to set the position of the axis in a conditional format data
455
+ * bar.
456
+ */
457
+ enum lxw_conditional_bar_axis_position {
458
+
459
+ /** Data bar axis position is set by Excel based on the context of the
460
+ * data displayed. */
461
+ LXW_CONDITIONAL_BAR_AXIS_AUTOMATIC,
462
+
463
+ /** Data bar axis position is set at the midpoint. */
464
+ LXW_CONDITIONAL_BAR_AXIS_MIDPOINT,
465
+
466
+ /** Data bar axis is turned off. */
467
+ LXW_CONDITIONAL_BAR_AXIS_NONE
468
+ };
469
+
470
+ /** @brief Icon types used in the #lxw_conditional_format icon_style field.
471
+ *
472
+ * Definitions of icon styles used with Icon Set conditional formats.
473
+ */
474
+ enum lxw_conditional_icon_types {
475
+
476
+ /** Icon style: 3 colored arrows showing up, sideways and down. */
477
+ LXW_CONDITIONAL_ICONS_3_ARROWS_COLORED,
478
+
479
+ /** Icon style: 3 gray arrows showing up, sideways and down. */
480
+ LXW_CONDITIONAL_ICONS_3_ARROWS_GRAY,
481
+
482
+ /** Icon style: 3 colored flags in red, yellow and green. */
483
+ LXW_CONDITIONAL_ICONS_3_FLAGS,
484
+
485
+ /** Icon style: 3 traffic lights - rounded. */
486
+ LXW_CONDITIONAL_ICONS_3_TRAFFIC_LIGHTS_UNRIMMED,
487
+
488
+ /** Icon style: 3 traffic lights with a rim - squarish. */
489
+ LXW_CONDITIONAL_ICONS_3_TRAFFIC_LIGHTS_RIMMED,
490
+
491
+ /** Icon style: 3 colored shapes - a circle, triangle and diamond. */
492
+ LXW_CONDITIONAL_ICONS_3_SIGNS,
493
+
494
+ /** Icon style: 3 circled symbols with tick mark, exclamation and
495
+ * cross. */
496
+ LXW_CONDITIONAL_ICONS_3_SYMBOLS_CIRCLED,
497
+
498
+ /** Icon style: 3 symbols with tick mark, exclamation and cross. */
499
+ LXW_CONDITIONAL_ICONS_3_SYMBOLS_UNCIRCLED,
500
+
501
+ /** Icon style: 3 colored arrows showing up, diagonal up, diagonal down
502
+ * and down. */
503
+ LXW_CONDITIONAL_ICONS_4_ARROWS_COLORED,
504
+
505
+ /** Icon style: 3 gray arrows showing up, diagonal up, diagonal down and
506
+ * down. */
507
+ LXW_CONDITIONAL_ICONS_4_ARROWS_GRAY,
508
+
509
+ /** Icon style: 4 circles in 4 colors going from red to black. */
510
+ LXW_CONDITIONAL_ICONS_4_RED_TO_BLACK,
511
+
512
+ /** Icon style: 4 histogram ratings. */
513
+ LXW_CONDITIONAL_ICONS_4_RATINGS,
514
+
515
+ /** Icon style: 4 traffic lights. */
516
+ LXW_CONDITIONAL_ICONS_4_TRAFFIC_LIGHTS,
517
+
518
+ /** Icon style: 5 colored arrows showing up, diagonal up, sideways,
519
+ * diagonal down and down. */
520
+ LXW_CONDITIONAL_ICONS_5_ARROWS_COLORED,
521
+
522
+ /** Icon style: 5 gray arrows showing up, diagonal up, sideways, diagonal
523
+ * down and down. */
524
+ LXW_CONDITIONAL_ICONS_5_ARROWS_GRAY,
525
+
526
+ /** Icon style: 5 histogram ratings. */
527
+ LXW_CONDITIONAL_ICONS_5_RATINGS,
528
+
529
+ /** Icon style: 5 quarters, from 0 to 4 quadrants filled. */
530
+ LXW_CONDITIONAL_ICONS_5_QUARTERS
531
+ };
532
+
533
+ /** Options to control the positioning of worksheet objects such as images
534
+ * or charts. See @ref working_with_object_positioning. */
535
+ enum lxw_object_position {
536
+
537
+ /** Default positioning for the object. */
538
+ LXW_OBJECT_POSITION_DEFAULT,
539
+
540
+ /** Move and size with the worksheet object with the cells. */
541
+ LXW_OBJECT_MOVE_AND_SIZE,
542
+
543
+ /** Move but don't size with the worksheet object with the cells. */
544
+ LXW_OBJECT_MOVE_DONT_SIZE,
545
+
546
+ /** Don't move or size the worksheet object with the cells. */
547
+ LXW_OBJECT_DONT_MOVE_DONT_SIZE,
548
+
549
+ /** Same as #LXW_OBJECT_MOVE_AND_SIZE except libxlsxwriter applies hidden
550
+ * cells after the object is inserted. */
551
+ LXW_OBJECT_MOVE_AND_SIZE_AFTER
552
+ };
553
+
554
+ /** Options for ignoring worksheet errors/warnings. See worksheet_ignore_errors(). */
555
+ enum lxw_ignore_errors {
556
+
557
+ /** Turn off errors/warnings for numbers stores as text. */
558
+ LXW_IGNORE_NUMBER_STORED_AS_TEXT = 1,
559
+
560
+ /** Turn off errors/warnings for formula errors (such as divide by
561
+ * zero). */
562
+ LXW_IGNORE_EVAL_ERROR,
563
+
564
+ /** Turn off errors/warnings for formulas that differ from surrounding
565
+ * formulas. */
566
+ LXW_IGNORE_FORMULA_DIFFERS,
567
+
568
+ /** Turn off errors/warnings for formulas that omit cells in a range. */
569
+ LXW_IGNORE_FORMULA_RANGE,
570
+
571
+ /** Turn off errors/warnings for unlocked cells that contain formulas. */
572
+ LXW_IGNORE_FORMULA_UNLOCKED,
573
+
574
+ /** Turn off errors/warnings for formulas that refer to empty cells. */
575
+ LXW_IGNORE_EMPTY_CELL_REFERENCE,
576
+
577
+ /** Turn off errors/warnings for cells in a table that do not comply with
578
+ * applicable data validation rules. */
579
+ LXW_IGNORE_LIST_DATA_VALIDATION,
580
+
581
+ /** Turn off errors/warnings for cell formulas that differ from the column
582
+ * formula. */
583
+ LXW_IGNORE_CALCULATED_COLUMN,
584
+
585
+ /** Turn off errors/warnings for formulas that contain a two digit text
586
+ * representation of a year. */
587
+ LXW_IGNORE_TWO_DIGIT_TEXT_YEAR,
588
+
589
+ LXW_IGNORE_LAST_OPTION
590
+ };
591
+
205
592
  enum cell_types {
206
593
  NUMBER_CELL = 1,
207
594
  STRING_CELL,
@@ -211,6 +598,7 @@ enum cell_types {
211
598
  ARRAY_FORMULA_CELL,
212
599
  BLANK_CELL,
213
600
  BOOLEAN_CELL,
601
+ COMMENT,
214
602
  HYPERLINK_URL,
215
603
  HYPERLINK_INTERNAL,
216
604
  HYPERLINK_EXTERNAL
@@ -223,8 +611,20 @@ enum pane_types {
223
611
  FREEZE_SPLIT_PANES
224
612
  };
225
613
 
614
+ enum lxw_image_position {
615
+ HEADER_LEFT = 0,
616
+ HEADER_CENTER,
617
+ HEADER_RIGHT,
618
+ FOOTER_LEFT,
619
+ FOOTER_CENTER,
620
+ FOOTER_RIGHT
621
+ };
622
+
226
623
  /* Define the tree.h RB structs for the red-black head types. */
227
624
  RB_HEAD(lxw_table_cells, lxw_cell);
625
+ RB_HEAD(lxw_drawing_rel_ids, lxw_drawing_rel_id);
626
+ RB_HEAD(lxw_vml_drawing_rel_ids, lxw_drawing_rel_id);
627
+ RB_HEAD(lxw_cond_format_hash, lxw_cond_format_hash_element);
228
628
 
229
629
  /* Define a RB_TREE struct manually to add extra members. */
230
630
  struct lxw_table_rows {
@@ -257,11 +657,46 @@ struct lxw_table_rows {
257
657
  /* Add unused struct to allow adding a semicolon */ \
258
658
  struct lxw_rb_generate_cell{int unused;}
259
659
 
660
+ #define LXW_RB_GENERATE_DRAWING_REL_IDS(name, type, field, cmp) \
661
+ RB_GENERATE_INSERT_COLOR(name, type, field, static) \
662
+ RB_GENERATE_REMOVE_COLOR(name, type, field, static) \
663
+ RB_GENERATE_INSERT(name, type, field, cmp, static) \
664
+ RB_GENERATE_REMOVE(name, type, field, static) \
665
+ RB_GENERATE_FIND(name, type, field, cmp, static) \
666
+ RB_GENERATE_NEXT(name, type, field, static) \
667
+ RB_GENERATE_MINMAX(name, type, field, static) \
668
+ /* Add unused struct to allow adding a semicolon */ \
669
+ struct lxw_rb_generate_drawing_rel_ids{int unused;}
670
+
671
+ #define LXW_RB_GENERATE_VML_DRAWING_REL_IDS(name, type, field, cmp) \
672
+ RB_GENERATE_INSERT_COLOR(name, type, field, static) \
673
+ RB_GENERATE_REMOVE_COLOR(name, type, field, static) \
674
+ RB_GENERATE_INSERT(name, type, field, cmp, static) \
675
+ RB_GENERATE_REMOVE(name, type, field, static) \
676
+ RB_GENERATE_FIND(name, type, field, cmp, static) \
677
+ RB_GENERATE_NEXT(name, type, field, static) \
678
+ RB_GENERATE_MINMAX(name, type, field, static) \
679
+ /* Add unused struct to allow adding a semicolon */ \
680
+ struct lxw_rb_generate_vml_drawing_rel_ids{int unused;}
681
+
682
+ #define LXW_RB_GENERATE_COND_FORMAT_HASH(name, type, field, cmp) \
683
+ RB_GENERATE_INSERT_COLOR(name, type, field, static) \
684
+ RB_GENERATE_REMOVE_COLOR(name, type, field, static) \
685
+ RB_GENERATE_INSERT(name, type, field, cmp, static) \
686
+ RB_GENERATE_REMOVE(name, type, field, static) \
687
+ RB_GENERATE_FIND(name, type, field, cmp, static) \
688
+ RB_GENERATE_NEXT(name, type, field, static) \
689
+ RB_GENERATE_MINMAX(name, type, field, static) \
690
+ /* Add unused struct to allow adding a semicolon */ \
691
+ struct lxw_rb_generate_cond_format_hash{int unused;}
692
+
260
693
  STAILQ_HEAD(lxw_merged_ranges, lxw_merged_range);
261
694
  STAILQ_HEAD(lxw_selections, lxw_selection);
262
- STAILQ_HEAD(lxw_data_validations, lxw_data_validation);
263
- STAILQ_HEAD(lxw_image_data, lxw_image_options);
264
- STAILQ_HEAD(lxw_chart_data, lxw_image_options);
695
+ STAILQ_HEAD(lxw_data_validations, lxw_data_val_obj);
696
+ STAILQ_HEAD(lxw_cond_format_list, lxw_cond_format_obj);
697
+ STAILQ_HEAD(lxw_image_props, lxw_object_properties);
698
+ STAILQ_HEAD(lxw_chart_props, lxw_object_properties);
699
+ STAILQ_HEAD(lxw_comment_objs, lxw_vml_obj);
265
700
 
266
701
  /**
267
702
  * @brief Options for rows and columns.
@@ -279,9 +714,13 @@ STAILQ_HEAD(lxw_chart_data, lxw_image_options);
279
714
  *
280
715
  */
281
716
  typedef struct lxw_row_col_options {
282
- /** Hide the row/column */
717
+ /** Hide the row/column. @ref ww_outlines_grouping.*/
283
718
  uint8_t hidden;
719
+
720
+ /** Outline level. See @ref ww_outlines_grouping.*/
284
721
  uint8_t level;
722
+
723
+ /** Set the outline row as collapsed. See @ref ww_outlines_grouping.*/
285
724
  uint8_t collapsed;
286
725
  } lxw_row_col_options;
287
726
 
@@ -405,8 +844,6 @@ typedef struct lxw_data_validation {
405
844
  */
406
845
  uint8_t dropdown;
407
846
 
408
- uint8_t is_between;
409
-
410
847
  /**
411
848
  * This parameter is used to set the limiting value to which the criteria
412
849
  * is applied using a whole or decimal number.
@@ -519,14 +956,307 @@ typedef struct lxw_data_validation {
519
956
  */
520
957
  char *error_message;
521
958
 
959
+ } lxw_data_validation;
960
+
961
+ /* A copy of lxw_data_validation which is used internally and which contains
962
+ * some additional fields.
963
+ */
964
+ typedef struct lxw_data_val_obj {
965
+ uint8_t validate;
966
+ uint8_t criteria;
967
+ uint8_t ignore_blank;
968
+ uint8_t show_input;
969
+ uint8_t show_error;
970
+ uint8_t error_type;
971
+ uint8_t dropdown;
972
+ double value_number;
973
+ char *value_formula;
974
+ char **value_list;
975
+ double minimum_number;
976
+ char *minimum_formula;
977
+ lxw_datetime minimum_datetime;
978
+ double maximum_number;
979
+ char *maximum_formula;
980
+ lxw_datetime maximum_datetime;
981
+ char *input_title;
982
+ char *input_message;
983
+ char *error_title;
984
+ char *error_message;
522
985
  char sqref[LXW_MAX_CELL_RANGE_LENGTH];
523
986
 
524
- STAILQ_ENTRY (lxw_data_validation) list_pointers;
987
+ STAILQ_ENTRY (lxw_data_val_obj) list_pointers;
988
+ } lxw_data_val_obj;
525
989
 
526
- } lxw_data_validation;
990
+ /**
991
+ * @brief Worksheet conditional formatting options.
992
+ *
993
+ * The fields/options in the the lxw_conditional_format are used to define a
994
+ * worksheet conditional format. It is used in conjunction with
995
+ * `worksheet_conditional_format()`.
996
+ *
997
+ */
998
+ typedef struct lxw_conditional_format {
999
+
1000
+ /** The type of conditional format such as #LXW_CONDITIONAL_TYPE_CELL or
1001
+ * #LXW_CONDITIONAL_DATA_BAR. Should be a #lxw_conditional_format_types
1002
+ * value.*/
1003
+ uint8_t type;
1004
+
1005
+ /** The criteria parameter is used to set the criteria by which the cell
1006
+ * data will be evaluated. For example in the expression `a > 5 the
1007
+ * criteria is `>` or, in libxlsxwriter terms,
1008
+ * #LXW_CONDITIONAL_CRITERIA_GREATER_THAN. The criteria that are
1009
+ * applicable depend on the conditional format type. The criteria
1010
+ * options are defined in #lxw_conditional_criteria. */
1011
+ uint8_t criteria;
1012
+
1013
+ /** The number value to which the condition refers. For example in the
1014
+ * expression `a > 5`, the value is 5.*/
1015
+ double value;
1016
+
1017
+ /** The string value to which the condition refers, such as `"=A1"`. If a
1018
+ * value_string exists in the struct then the number value is
1019
+ * ignored. Note, if the condition refers to a text string then it must
1020
+ * be double quoted like this `"foo"`. */
1021
+ char *value_string;
1022
+
1023
+ /** The format field is used to specify the #lxw_format format that will
1024
+ * be applied to the cell when the conditional formatting criterion is
1025
+ * met. The #lxw_format is created using the `workbook_add_format()`
1026
+ * method in the same way as cell formats.
1027
+ *
1028
+ * @note In Excel, a conditional format is superimposed over the existing
1029
+ * cell format and not all cell format properties can be
1030
+ * modified. Properties that @b cannot be modified, in Excel, by a
1031
+ * conditional format are: font name, font size, superscript and
1032
+ * subscript, diagonal borders, all alignment properties and all
1033
+ * protection properties. */
1034
+ lxw_format *format;
1035
+
1036
+ /** The minimum value used for Cell, Color Scale and Data Bar conditional
1037
+ * formats. For Cell types this is usually used with a "Between" style criteria. */
1038
+ double min_value;
1039
+
1040
+ /** The minimum string value used for Cell, Color Scale and Data Bar conditional
1041
+ * formats. Usually used to set ranges like `=A1`. */
1042
+ char *min_value_string;
1043
+
1044
+ /** The rule used for the minimum condition in Color Scale and Data Bar
1045
+ * conditional formats. The rule types are defined in
1046
+ * #lxw_conditional_format_rule_types. */
1047
+ uint8_t min_rule_type;
1048
+
1049
+ /** The color used for the minimum Color Scale conditional format.
1050
+ * See @ref working_with_colors. */
1051
+ lxw_color_t min_color;
1052
+
1053
+ /** The middle value used for Color Scale and Data Bar conditional
1054
+ * formats. */
1055
+ double mid_value;
1056
+
1057
+ /** The middle string value used for Color Scale and Data Bar conditional
1058
+ * formats. Usually used to set ranges like `=A1`. */
1059
+ char *mid_value_string;
1060
+
1061
+ /** The rule used for the middle condition in Color Scale and Data Bar
1062
+ * conditional formats. The rule types are defined in
1063
+ * #lxw_conditional_format_rule_types. */
1064
+ uint8_t mid_rule_type;
1065
+
1066
+ /** The color used for the middle Color Scale conditional format.
1067
+ * See @ref working_with_colors. */
1068
+ lxw_color_t mid_color;
1069
+
1070
+ /** The maximum value used for Cell, Color Scale and Data Bar conditional
1071
+ * formats. For Cell types this is usually used with a "Between" style
1072
+ * criteria. */
1073
+ double max_value;
1074
+
1075
+ /** The maximum string value used for Cell, Color Scale and Data Bar conditional
1076
+ * formats. Usually used to set ranges like `=A1`. */
1077
+ char *max_value_string;
1078
+
1079
+ /** The rule used for the maximum condition in Color Scale and Data Bar
1080
+ * conditional formats. The rule types are defined in
1081
+ * #lxw_conditional_format_rule_types. */
1082
+ uint8_t max_rule_type;
1083
+
1084
+ /** The color used for the maximum Color Scale conditional format.
1085
+ * See @ref working_with_colors. */
1086
+ lxw_color_t max_color;
1087
+
1088
+ /** The bar_color field sets the fill color for data bars. See @ref
1089
+ * working_with_colors. */
1090
+ lxw_color_t bar_color;
1091
+
1092
+ /** The bar_only field sets The bar_only field displays a bar data but
1093
+ * not the data in the cells. */
1094
+ uint8_t bar_only;
1095
+
1096
+ /** In Excel 2010 additional data bar properties were added such as solid
1097
+ * (non-gradient) bars and control over how negative values are
1098
+ * displayed. These properties can shown below.
1099
+ *
1100
+ * The data_bar_2010 field sets Excel 2010 style data bars even when
1101
+ * Excel 2010 specific properties aren't used. */
1102
+ uint8_t data_bar_2010;
1103
+
1104
+ /** The bar_solid field turns on a solid (non-gradient) fill for data
1105
+ * bars. Set to LXW_TRUE to turn on. Excel 2010 only. */
1106
+ uint8_t bar_solid;
1107
+
1108
+ /** The bar_negative_color field sets the color fill for the negative
1109
+ * portion of a data bar. See @ref working_with_colors. Excel 2010 only. */
1110
+ lxw_color_t bar_negative_color;
1111
+
1112
+ /** The bar_border_color field sets the color for the border line of a
1113
+ * data bar. See @ref working_with_colors. Excel 2010 only. */
1114
+ lxw_color_t bar_border_color;
1115
+
1116
+ /** The bar_negative_border_color field sets the color for the border of
1117
+ * the negative portion of a data bar. See @ref
1118
+ * working_with_colors. Excel 2010 only. */
1119
+ lxw_color_t bar_negative_border_color;
1120
+
1121
+ /** The bar_negative_color_same field sets the fill color for the negative
1122
+ * portion of a data bar to be the same as the fill color for the
1123
+ * positive portion of the data bar. Set to LXW_TRUE to turn on. Excel
1124
+ * 2010 only. */
1125
+ uint8_t bar_negative_color_same;
1126
+
1127
+ /** The bar_negative_border_color_same field sets the border color for the
1128
+ * negative portion of a data bar to be the same as the border color for
1129
+ * the positive portion of the data bar. Set to LXW_TRUE to turn
1130
+ * on. Excel 2010 only. */
1131
+ uint8_t bar_negative_border_color_same;
1132
+
1133
+ /** The bar_no_border field turns off the border for data bars. Set to
1134
+ * LXW_TRUE to enable. Excel 2010 only. */
1135
+ uint8_t bar_no_border;
1136
+
1137
+ /** The bar_direction field sets the direction for data bars. This
1138
+ * property can be either left for left-to-right or right for
1139
+ * right-to-left. If the property isn't set then Excel will adjust the
1140
+ * position automatically based on the context. Should be a
1141
+ * #lxw_conditional_format_bar_direction value. Excel 2010 only. */
1142
+ uint8_t bar_direction;
1143
+
1144
+ /** The bar_axis_position field sets the position within the cells for the
1145
+ * axis that is shown in data bars when there are negative values to
1146
+ * display. The property can be either middle or none. If the property
1147
+ * isn't set then Excel will position the axis based on the range of
1148
+ * positive and negative values. Should be a
1149
+ * lxw_conditional_bar_axis_position value. Excel 2010 only. */
1150
+ uint8_t bar_axis_position;
1151
+
1152
+ /** The bar_axis_color field sets the color for the axis that is shown
1153
+ * in data bars when there are negative values to display. See @ref
1154
+ * working_with_colors. Excel 2010 only. */
1155
+ lxw_color_t bar_axis_color;
1156
+
1157
+ /** The Icons Sets style is specified by the icon_style parameter. Should
1158
+ * be a #lxw_conditional_icon_types. */
1159
+ uint8_t icon_style;
1160
+
1161
+ /** The order of Icon Sets icons can be reversed by setting reverse_icons
1162
+ * to LXW_TRUE. */
1163
+ uint8_t reverse_icons;
1164
+
1165
+ /** The icons can be displayed without the cell value by settings the
1166
+ * icons_only parameter to LXW_TRUE. */
1167
+ uint8_t icons_only;
1168
+
1169
+ /** The multi_range field is used to extend a conditional format over
1170
+ * non-contiguous ranges.
1171
+ *
1172
+ * It is possible to apply the conditional format to different cell
1173
+ * ranges in a worksheet using multiple calls to
1174
+ * `worksheet_conditional_format()`. However, as a minor optimization it
1175
+ * is also possible in Excel to apply the same conditional format to
1176
+ * different non-contiguous cell ranges.
1177
+ *
1178
+ * This is replicated in `worksheet_conditional_format()` using the
1179
+ * multi_range option. The range must contain the primary range for the
1180
+ * conditional format and any others separated by spaces. For example
1181
+ * `"A1 C1:C5 E2 G1:G100"`.
1182
+ */
1183
+ char *multi_range;
1184
+
1185
+ /** The stop_if_true parameter can be used to set the "stop if true"
1186
+ * feature of a conditional formatting rule when more than one rule is
1187
+ * applied to a cell or a range of cells. When this parameter is set then
1188
+ * subsequent rules are not evaluated if the current rule is true. Set to
1189
+ * LXW_TRUE to turn on. */
1190
+ uint8_t stop_if_true;
1191
+
1192
+ } lxw_conditional_format;
1193
+
1194
+ /* Internal */
1195
+ typedef struct lxw_cond_format_obj {
1196
+ uint8_t type;
1197
+ uint8_t criteria;
1198
+
1199
+ double min_value;
1200
+ char *min_value_string;
1201
+ uint8_t min_rule_type;
1202
+ lxw_color_t min_color;
1203
+
1204
+ double mid_value;
1205
+ char *mid_value_string;
1206
+ uint8_t mid_value_type;
1207
+ uint8_t mid_rule_type;
1208
+ lxw_color_t mid_color;
1209
+
1210
+ double max_value;
1211
+ char *max_value_string;
1212
+ uint8_t max_value_type;
1213
+ uint8_t max_rule_type;
1214
+ lxw_color_t max_color;
1215
+
1216
+ uint8_t data_bar_2010;
1217
+ uint8_t auto_min;
1218
+ uint8_t auto_max;
1219
+ uint8_t bar_only;
1220
+ uint8_t bar_solid;
1221
+ uint8_t bar_negative_color_same;
1222
+ uint8_t bar_negative_border_color_same;
1223
+ uint8_t bar_no_border;
1224
+ uint8_t bar_direction;
1225
+ uint8_t bar_axis_position;
1226
+ lxw_color_t bar_color;
1227
+ lxw_color_t bar_negative_color;
1228
+ lxw_color_t bar_border_color;
1229
+ lxw_color_t bar_negative_border_color;
1230
+ lxw_color_t bar_axis_color;
1231
+
1232
+ uint8_t icon_style;
1233
+ uint8_t reverse_icons;
1234
+ uint8_t icons_only;
1235
+
1236
+ uint8_t stop_if_true;
1237
+ uint8_t has_max;
1238
+ char *type_string;
1239
+ char *guid;
1240
+
1241
+ int32_t dxf_index;
1242
+ uint32_t dxf_priority;
1243
+
1244
+ char first_cell[LXW_MAX_CELL_NAME_LENGTH];
1245
+ char sqref[LXW_MAX_ATTRIBUTE_LENGTH];
1246
+
1247
+ STAILQ_ENTRY (lxw_cond_format_obj) list_pointers;
1248
+ } lxw_cond_format_obj;
1249
+
1250
+ typedef struct lxw_cond_format_hash_element {
1251
+ char sqref[LXW_MAX_ATTRIBUTE_LENGTH];
1252
+
1253
+ struct lxw_cond_format_list *cond_formats;
1254
+
1255
+ RB_ENTRY (lxw_cond_format_hash_element) tree_pointers;
1256
+ } lxw_cond_format_hash_element;
527
1257
 
528
1258
  /**
529
- * @brief Options for inserted images
1259
+ * @brief Options for inserted images.
530
1260
  *
531
1261
  * Options for modifying images inserted via `worksheet_insert_image_opt()`.
532
1262
  *
@@ -545,15 +1275,64 @@ typedef struct lxw_image_options {
545
1275
  /** Y scale of the image as a decimal. */
546
1276
  double y_scale;
547
1277
 
1278
+ /** Object position - use one of the values of #lxw_object_position.
1279
+ * See @ref working_with_object_positioning.*/
1280
+ uint8_t object_position;
1281
+
1282
+ /** Optional description of the image. Defaults to the image filename
1283
+ * as in Excel. Set to "" to ignore the description field. */
1284
+ char *description;
1285
+
1286
+ /** Add an optional hyperlink to the image. Follows the same URL rules
1287
+ * and types as `worksheet_write_url()`. */
1288
+ char *url;
1289
+
1290
+ /** Add an optional mouseover tip for a hyperlink to the image. */
1291
+ char *tip;
1292
+
1293
+ } lxw_image_options;
1294
+
1295
+ /**
1296
+ * @brief Options for inserted charts.
1297
+ *
1298
+ * Options for modifying charts inserted via `worksheet_insert_chart_opt()`.
1299
+ *
1300
+ */
1301
+ typedef struct lxw_chart_options {
1302
+
1303
+ /** Offset from the left of the cell in pixels. */
1304
+ int32_t x_offset;
1305
+
1306
+ /** Offset from the top of the cell in pixels. */
1307
+ int32_t y_offset;
1308
+
1309
+ /** X scale of the chart as a decimal. */
1310
+ double x_scale;
1311
+
1312
+ /** Y scale of the chart as a decimal. */
1313
+ double y_scale;
1314
+
1315
+ /** Object position - use one of the values of #lxw_object_position.
1316
+ * See @ref working_with_object_positioning.*/
1317
+ uint8_t object_position;
1318
+
1319
+ } lxw_chart_options;
1320
+
1321
+ /* Internal struct to represent lxw_image_options and lxw_chart_options
1322
+ * values as well as internal metadata.
1323
+ */
1324
+ typedef struct lxw_object_properties {
1325
+ int32_t x_offset;
1326
+ int32_t y_offset;
1327
+ double x_scale;
1328
+ double y_scale;
548
1329
  lxw_row_t row;
549
1330
  lxw_col_t col;
550
1331
  char *filename;
551
1332
  char *description;
552
1333
  char *url;
553
1334
  char *tip;
554
- uint8_t anchor;
555
-
556
- /* Internal metadata. */
1335
+ uint8_t object_position;
557
1336
  FILE *stream;
558
1337
  uint8_t image_type;
559
1338
  uint8_t is_image_buffer;
@@ -565,21 +1344,153 @@ typedef struct lxw_image_options {
565
1344
  double x_dpi;
566
1345
  double y_dpi;
567
1346
  lxw_chart *chart;
1347
+ uint8_t is_duplicate;
1348
+ char *md5;
1349
+ char *image_position;
568
1350
 
569
- STAILQ_ENTRY (lxw_image_options) list_pointers;
1351
+ STAILQ_ENTRY (lxw_object_properties) list_pointers;
1352
+ } lxw_object_properties;
570
1353
 
571
- } lxw_image_options;
1354
+ /**
1355
+ * @brief Options for inserted comments.
1356
+ *
1357
+ * Options for modifying comments inserted via `worksheet_write_comment_opt()`.
1358
+ *
1359
+ */
1360
+ typedef struct lxw_comment_options {
1361
+
1362
+ /** This option is used to make a cell comment visible when the worksheet
1363
+ * is opened. The default behavior in Excel is that comments are
1364
+ * initially hidden. However, it is also possible in Excel to make
1365
+ * individual comments or all comments visible. You can make all
1366
+ * comments in the worksheet visible using the
1367
+ * `worksheet_show_comments()` function. Defaults to
1368
+ * LXW_COMMENT_DISPLAY_DEFAULT. See also @ref ww_comments_visible. */
1369
+ uint8_t visible;
1370
+
1371
+ /** This option is used to indicate the author of the cell comment. Excel
1372
+ * displays the author in the status bar at the bottom of the
1373
+ * worksheet. The default author for all cell comments in a worksheet can
1374
+ * be set using the `worksheet_set_comments_author()` function. Set to
1375
+ * NULL if not required. See also @ref ww_comments_author. */
1376
+ char *author;
1377
+
1378
+ /** This option is used to set the width of the cell comment box
1379
+ * explicitly in pixels. The default width is 128 pixels. See also @ref
1380
+ * ww_comments_width. */
1381
+ uint16_t width;
1382
+
1383
+ /** This option is used to set the height of the cell comment box
1384
+ * explicitly in pixels. The default height is 74 pixels. See also @ref
1385
+ * ww_comments_height. */
1386
+ uint16_t height;
1387
+
1388
+ /** X scale of the comment as a decimal. See also
1389
+ * @ref ww_comments_x_scale. */
1390
+ double x_scale;
1391
+
1392
+ /** Y scale of the comment as a decimal. See also
1393
+ * @ref ww_comments_y_scale. */
1394
+ double y_scale;
1395
+
1396
+ /** This option is used to set the background color of cell comment
1397
+ * box. The color should be an RGB integer value, see @ref
1398
+ * working_with_colors. See also @ref ww_comments_color. */
1399
+ lxw_color_t color;
1400
+
1401
+ /** This option is used to set the font for the comment. The default font
1402
+ * is 'Tahoma'. See also @ref ww_comments_font_name. */
1403
+ char *font_name;
1404
+
1405
+ /** This option is used to set the font size for the comment. The default
1406
+ * is 8. See also @ref ww_comments_font_size. */
1407
+ double font_size;
1408
+
1409
+ /** This option is used to set the font family number for the comment.
1410
+ * Not required very often. Set to 0. */
1411
+ uint8_t font_family;
1412
+
1413
+ /** This option is used to set the row in which the comment will
1414
+ * appear. By default Excel displays comments one cell to the right and
1415
+ * one cell above the cell to which the comment relates. The `start_row`
1416
+ * and `start_col` options should both be set to 0 if not used. See also
1417
+ * @ref ww_comments_start_row. */
1418
+ lxw_row_t start_row;
1419
+
1420
+ /** This option is used to set the column in which the comment will
1421
+ * appear. See the `start_row` option for more information and see also
1422
+ * @ref ww_comments_start_col. */
1423
+ lxw_col_t start_col;
1424
+
1425
+ /** Offset from the left of the cell in pixels. See also
1426
+ * @ref ww_comments_x_offset. */
1427
+ int32_t x_offset;
1428
+
1429
+ /** Offset from the top of the cell in pixels. See also
1430
+ * @ref ww_comments_y_offset. */
1431
+ int32_t y_offset;
1432
+
1433
+ } lxw_comment_options;
1434
+
1435
+ /* Internal structure for VML object options. */
1436
+ typedef struct lxw_vml_obj {
1437
+
1438
+ lxw_row_t row;
1439
+ lxw_col_t col;
1440
+ lxw_row_t start_row;
1441
+ lxw_col_t start_col;
1442
+ int32_t x_offset;
1443
+ int32_t y_offset;
1444
+ uint32_t col_absolute;
1445
+ uint32_t row_absolute;
1446
+ uint32_t width;
1447
+ uint32_t height;
1448
+ double x_dpi;
1449
+ double y_dpi;
1450
+ lxw_color_t color;
1451
+ uint8_t font_family;
1452
+ uint8_t visible;
1453
+ uint32_t author_id;
1454
+ uint32_t rel_index;
1455
+ double font_size;
1456
+ struct lxw_drawing_coords from;
1457
+ struct lxw_drawing_coords to;
1458
+ char *author;
1459
+ char *font_name;
1460
+ char *text;
1461
+ char *image_position;
1462
+ char *name;
1463
+ STAILQ_ENTRY (lxw_vml_obj) list_pointers;
1464
+
1465
+ } lxw_vml_obj;
572
1466
 
573
1467
  /**
574
1468
  * @brief Header and footer options.
575
1469
  *
576
- * Optional parameters used in the worksheet_set_header_opt() and
1470
+ * Optional parameters used in the `worksheet_set_header_opt()` and
577
1471
  * worksheet_set_footer_opt() functions.
578
1472
  *
579
1473
  */
580
1474
  typedef struct lxw_header_footer_options {
581
- /** Header or footer margin in inches. Excel default is 0.3. */
1475
+ /** Header or footer margin in inches. Excel default is 0.3. Must by
1476
+ * larger than 0.0. See `worksheet_set_header_opt()`. */
582
1477
  double margin;
1478
+
1479
+ /** The left header image filename, with path if required. This should
1480
+ * have a corresponding `&G/&[Picture]` placeholder in the `&L` section of
1481
+ * the header/footer string. See `worksheet_set_header_opt()`. */
1482
+ char *image_left;
1483
+
1484
+ /** The center header image filename, with path if required. This should
1485
+ * have a corresponding `&G/&[Picture]` placeholder in the `&C` section of
1486
+ * the header/footer string. See `worksheet_set_header_opt()`. */
1487
+ char *image_center;
1488
+
1489
+ /** The right header image filename, with path if required. This should
1490
+ * have a corresponding `&G/&[Picture]` placeholder in the `&R` section of
1491
+ * the header/footer string. See `worksheet_set_header_opt()`. */
1492
+ char *image_right;
1493
+
583
1494
  } lxw_header_footer_options;
584
1495
 
585
1496
  /**
@@ -637,10 +1548,31 @@ typedef struct lxw_protection {
637
1548
  /** Turn off chartsheet objects. */
638
1549
  uint8_t no_objects;
639
1550
 
1551
+ } lxw_protection;
1552
+
1553
+ /* Internal struct to copy lxw_protection options and internal metadata. */
1554
+ typedef struct lxw_protection_obj {
1555
+ uint8_t no_select_locked_cells;
1556
+ uint8_t no_select_unlocked_cells;
1557
+ uint8_t format_cells;
1558
+ uint8_t format_columns;
1559
+ uint8_t format_rows;
1560
+ uint8_t insert_columns;
1561
+ uint8_t insert_rows;
1562
+ uint8_t insert_hyperlinks;
1563
+ uint8_t delete_columns;
1564
+ uint8_t delete_rows;
1565
+ uint8_t sort;
1566
+ uint8_t autofilter;
1567
+ uint8_t pivot_tables;
1568
+ uint8_t scenarios;
1569
+ uint8_t objects;
1570
+ uint8_t no_content;
1571
+ uint8_t no_objects;
640
1572
  uint8_t no_sheet;
641
1573
  uint8_t is_configured;
642
1574
  char hash[5];
643
- } lxw_protection;
1575
+ } lxw_protection_obj;
644
1576
 
645
1577
  /**
646
1578
  * @brief Struct to represent a rich string format/string pair.
@@ -674,12 +1606,18 @@ typedef struct lxw_worksheet {
674
1606
  FILE *optimize_tmpfile;
675
1607
  struct lxw_table_rows *table;
676
1608
  struct lxw_table_rows *hyperlinks;
1609
+ struct lxw_table_rows *comments;
677
1610
  struct lxw_cell **array;
678
1611
  struct lxw_merged_ranges *merged_ranges;
679
1612
  struct lxw_selections *selections;
680
1613
  struct lxw_data_validations *data_validations;
681
- struct lxw_image_data *image_data;
682
- struct lxw_chart_data *chart_data;
1614
+ struct lxw_cond_format_hash *conditional_formats;
1615
+ struct lxw_image_props *image_props;
1616
+ struct lxw_chart_props *chart_data;
1617
+ struct lxw_drawing_rel_ids *drawing_rel_ids;
1618
+ struct lxw_vml_drawing_rel_ids *vml_drawing_rel_ids;
1619
+ struct lxw_comment_objs *comment_objs;
1620
+ struct lxw_comment_objs *header_image_objs;
683
1621
 
684
1622
  lxw_row_t dim_rowmin;
685
1623
  lxw_row_t dim_rowmax;
@@ -773,21 +1711,62 @@ typedef struct lxw_worksheet {
773
1711
  struct lxw_autofilter autofilter;
774
1712
 
775
1713
  uint16_t merged_range_count;
1714
+ uint16_t max_url_length;
776
1715
 
777
1716
  lxw_row_t *hbreaks;
778
1717
  lxw_col_t *vbreaks;
779
1718
  uint16_t hbreaks_count;
780
1719
  uint16_t vbreaks_count;
781
1720
 
1721
+ uint32_t drawing_rel_id;
1722
+ uint32_t vml_drawing_rel_id;
782
1723
  struct lxw_rel_tuples *external_hyperlinks;
783
1724
  struct lxw_rel_tuples *external_drawing_links;
784
1725
  struct lxw_rel_tuples *drawing_links;
1726
+ struct lxw_rel_tuples *vml_drawing_links;
785
1727
 
786
1728
  struct lxw_panes panes;
787
1729
 
788
- struct lxw_protection protection;
1730
+ struct lxw_protection_obj protection;
789
1731
 
790
1732
  lxw_drawing *drawing;
1733
+ lxw_format *default_url_format;
1734
+
1735
+ uint8_t has_vml;
1736
+ uint8_t has_comments;
1737
+ uint8_t has_header_vml;
1738
+ lxw_rel_tuple *external_vml_comment_link;
1739
+ lxw_rel_tuple *external_comment_link;
1740
+ lxw_rel_tuple *external_vml_header_link;
1741
+ char *comment_author;
1742
+ char *vml_data_id_str;
1743
+ char *vml_header_id_str;
1744
+ uint32_t vml_shape_id;
1745
+ uint32_t vml_header_id;
1746
+ uint32_t dxf_priority;
1747
+ uint8_t comment_display_default;
1748
+ uint32_t data_bar_2010_index;
1749
+
1750
+ uint8_t has_ignore_errors;
1751
+ char *ignore_number_stored_as_text;
1752
+ char *ignore_eval_error;
1753
+ char *ignore_formula_differs;
1754
+ char *ignore_formula_range;
1755
+ char *ignore_formula_unlocked;
1756
+ char *ignore_empty_cell_reference;
1757
+ char *ignore_list_data_validation;
1758
+ char *ignore_calculated_column;
1759
+ char *ignore_two_digit_text_year;
1760
+
1761
+ uint16_t excel_version;
1762
+
1763
+ lxw_object_properties **header_footer_objs[LXW_HEADER_FOOTER_OBJS_MAX];
1764
+ lxw_object_properties *header_left_object_props;
1765
+ lxw_object_properties *header_center_object_props;
1766
+ lxw_object_properties *header_right_object_props;
1767
+ lxw_object_properties *footer_left_object_props;
1768
+ lxw_object_properties *footer_center_object_props;
1769
+ lxw_object_properties *footer_right_object_props;
791
1770
 
792
1771
  STAILQ_ENTRY (lxw_worksheet) list_pointers;
793
1772
 
@@ -806,6 +1785,8 @@ typedef struct lxw_worksheet_init_data {
806
1785
  char *name;
807
1786
  char *quoted_name;
808
1787
  char *tmpdir;
1788
+ lxw_format *default_url_format;
1789
+ uint16_t max_url_length;
809
1790
 
810
1791
  } lxw_worksheet_init_data;
811
1792
 
@@ -820,6 +1801,7 @@ typedef struct lxw_row {
820
1801
  uint8_t row_changed;
821
1802
  uint8_t data_changed;
822
1803
  uint8_t height_changed;
1804
+
823
1805
  struct lxw_table_cells *cells;
824
1806
 
825
1807
  /* tree management pointers for tree.h. */
@@ -832,6 +1814,7 @@ typedef struct lxw_cell {
832
1814
  lxw_col_t col_num;
833
1815
  enum cell_types type;
834
1816
  lxw_format *format;
1817
+ lxw_vml_obj *comment;
835
1818
 
836
1819
  union {
837
1820
  double number;
@@ -848,6 +1831,16 @@ typedef struct lxw_cell {
848
1831
  RB_ENTRY (lxw_cell) tree_pointers;
849
1832
  } lxw_cell;
850
1833
 
1834
+ /* Struct to represent a drawing Target/ID pair. */
1835
+ typedef struct lxw_drawing_rel_id {
1836
+ uint32_t id;
1837
+ char *target;
1838
+
1839
+ RB_ENTRY (lxw_drawing_rel_id) tree_pointers;
1840
+ } lxw_drawing_rel_id;
1841
+
1842
+
1843
+
851
1844
  /* *INDENT-OFF* */
852
1845
  #ifdef __cplusplus
853
1846
  extern "C" {
@@ -857,7 +1850,7 @@ extern "C" {
857
1850
  /**
858
1851
  * @brief Write a number to a worksheet cell.
859
1852
  *
860
- * @param worksheet pointer to a lxw_worksheet instance to be updated.
1853
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
861
1854
  * @param row The zero indexed row number.
862
1855
  * @param col The zero indexed column number.
863
1856
  * @param number The number to write to the cell.
@@ -904,7 +1897,7 @@ lxw_error worksheet_write_number(lxw_worksheet *worksheet,
904
1897
  /**
905
1898
  * @brief Write a string to a worksheet cell.
906
1899
  *
907
- * @param worksheet pointer to a lxw_worksheet instance to be updated.
1900
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
908
1901
  * @param row The zero indexed row number.
909
1902
  * @param col The zero indexed column number.
910
1903
  * @param string String to write to cell.
@@ -952,7 +1945,7 @@ lxw_error worksheet_write_string(lxw_worksheet *worksheet,
952
1945
  /**
953
1946
  * @brief Write a formula to a worksheet cell.
954
1947
  *
955
- * @param worksheet pointer to a lxw_worksheet instance to be updated.
1948
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
956
1949
  * @param row The zero indexed row number.
957
1950
  * @param col The zero indexed column number.
958
1951
  * @param formula Formula string to write to cell.
@@ -1005,7 +1998,7 @@ lxw_error worksheet_write_formula(lxw_worksheet *worksheet,
1005
1998
  /**
1006
1999
  * @brief Write an array formula to a worksheet cell.
1007
2000
  *
1008
- * @param worksheet pointer to a lxw_worksheet instance to be updated.
2001
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
1009
2002
  * @param first_row The first row of the range. (All zero indexed.)
1010
2003
  * @param first_col The first column of the range.
1011
2004
  * @param last_row The last row of the range.
@@ -1064,7 +2057,7 @@ lxw_error worksheet_write_array_formula_num(lxw_worksheet *worksheet,
1064
2057
  /**
1065
2058
  * @brief Write a date or time to a worksheet cell.
1066
2059
  *
1067
- * @param worksheet pointer to a lxw_worksheet instance to be updated.
2060
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
1068
2061
  * @param row The zero indexed row number.
1069
2062
  * @param col The zero indexed column number.
1070
2063
  * @param datetime The datetime to write to the cell.
@@ -1093,14 +2086,9 @@ lxw_error worksheet_write_datetime(lxw_worksheet *worksheet,
1093
2086
  lxw_col_t col, lxw_datetime *datetime,
1094
2087
  lxw_format *format);
1095
2088
 
1096
- lxw_error worksheet_write_url_opt(lxw_worksheet *worksheet,
1097
- lxw_row_t row_num,
1098
- lxw_col_t col_num, const char *url,
1099
- lxw_format *format, const char *string,
1100
- const char *tooltip);
1101
2089
  /**
1102
2090
  *
1103
- * @param worksheet pointer to a lxw_worksheet instance to be updated.
2091
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
1104
2092
  * @param row The zero indexed row number.
1105
2093
  * @param col The zero indexed column number.
1106
2094
  * @param url The url to write to the cell.
@@ -1113,21 +2101,22 @@ lxw_error worksheet_write_url_opt(lxw_worksheet *worksheet,
1113
2101
  * worksheet cell specified by `row` and `column`.
1114
2102
  *
1115
2103
  * @code
1116
- * worksheet_write_url(worksheet, 0, 0, "http://libxlsxwriter.github.io", url_format);
2104
+ * worksheet_write_url(worksheet, 0, 0, "http://libxlsxwriter.github.io", NULL);
1117
2105
  * @endcode
1118
2106
  *
1119
2107
  * @image html hyperlinks_short.png
1120
2108
  *
1121
2109
  * The `format` parameter is used to apply formatting to the cell. This
1122
- * parameter can be `NULL` to indicate no formatting or it can be a @ref
1123
- * format.h "Format" object. The typical worksheet format for a hyperlink is a
1124
- * blue underline:
2110
+ * parameter can be `NULL`, in which case the default Excel blue underlined
2111
+ * hyperlink style will be used. If required a user defined @ref format.h
2112
+ * "Format" object can be used:
2113
+ * underline:
1125
2114
  *
1126
2115
  * @code
1127
2116
  * lxw_format *url_format = workbook_add_format(workbook);
1128
2117
  *
1129
2118
  * format_set_underline (url_format, LXW_UNDERLINE_SINGLE);
1130
- * format_set_font_color(url_format, LXW_COLOR_BLUE);
2119
+ * format_set_font_color(url_format, LXW_COLOR_RED);
1131
2120
  *
1132
2121
  * @endcode
1133
2122
  *
@@ -1135,10 +2124,10 @@ lxw_error worksheet_write_url_opt(lxw_worksheet *worksheet,
1135
2124
  * and `mailto:` :
1136
2125
  *
1137
2126
  * @code
1138
- * worksheet_write_url(worksheet, 0, 0, "ftp://www.python.org/", url_format);
1139
- * worksheet_write_url(worksheet, 1, 0, "http://www.python.org/", url_format);
1140
- * worksheet_write_url(worksheet, 2, 0, "https://www.python.org/", url_format);
1141
- * worksheet_write_url(worksheet, 3, 0, "mailto:jmcnamara@cpan.org", url_format);
2127
+ * worksheet_write_url(worksheet, 0, 0, "ftp://www.python.org/", NULL);
2128
+ * worksheet_write_url(worksheet, 1, 0, "http://www.python.org/", NULL);
2129
+ * worksheet_write_url(worksheet, 2, 0, "https://www.python.org/", NULL);
2130
+ * worksheet_write_url(worksheet, 3, 0, "mailto:jmcnamara@cpan.org", NULL);
1142
2131
  *
1143
2132
  * @endcode
1144
2133
  *
@@ -1147,13 +2136,18 @@ lxw_error worksheet_write_url_opt(lxw_worksheet *worksheet,
1147
2136
  * link. However, it is possible to overwrite it with any other
1148
2137
  * `libxlsxwriter` type using the appropriate `worksheet_write_*()`
1149
2138
  * function. The most common case is to overwrite the displayed link text with
1150
- * another string:
2139
+ * another string. To do this we must also match the default URL format using
2140
+ * `workbook_get_default_url_format()`:
1151
2141
  *
1152
2142
  * @code
1153
- * // Write a hyperlink but overwrite the displayed string.
1154
- * worksheet_write_url (worksheet, 2, 0, "http://libxlsxwriter.github.io", url_format);
1155
- * worksheet_write_string(worksheet, 2, 0, "Read the documentation.", url_format);
2143
+ * // Write a hyperlink with the default blue underline format.
2144
+ * worksheet_write_url(worksheet, 2, 0, "http://libxlsxwriter.github.io", NULL);
2145
+ *
2146
+ * // Get the default url format.
2147
+ * lxw_format *url_format = workbook_get_default_url_format(workbook);
1156
2148
  *
2149
+ * // Overwrite the hyperlink with a user defined string and default format.
2150
+ * worksheet_write_string(worksheet, 2, 0, "Read the documentation.", url_format);
1157
2151
  * @endcode
1158
2152
  *
1159
2153
  * @image html hyperlinks_short2.png
@@ -1163,15 +2157,15 @@ lxw_error worksheet_write_url_opt(lxw_worksheet *worksheet,
1163
2157
  * worksheet references:
1164
2158
  *
1165
2159
  * @code
1166
- * worksheet_write_url(worksheet, 0, 0, "internal:Sheet2!A1", url_format);
1167
- * worksheet_write_url(worksheet, 1, 0, "internal:Sheet2!B2", url_format);
1168
- * worksheet_write_url(worksheet, 2, 0, "internal:Sheet2!A1:B2", url_format);
1169
- * worksheet_write_url(worksheet, 3, 0, "internal:'Sales Data'!A1", url_format);
1170
- * worksheet_write_url(worksheet, 4, 0, "external:c:\\temp\\foo.xlsx", url_format);
1171
- * worksheet_write_url(worksheet, 5, 0, "external:c:\\foo.xlsx#Sheet2!A1", url_format);
1172
- * worksheet_write_url(worksheet, 6, 0, "external:..\\foo.xlsx", url_format);
1173
- * worksheet_write_url(worksheet, 7, 0, "external:..\\foo.xlsx#Sheet2!A1", url_format);
1174
- * worksheet_write_url(worksheet, 8, 0, "external:\\\\NET\\share\\foo.xlsx", url_format);
2160
+ * worksheet_write_url(worksheet, 0, 0, "internal:Sheet2!A1", NULL);
2161
+ * worksheet_write_url(worksheet, 1, 0, "internal:Sheet2!B2", NULL);
2162
+ * worksheet_write_url(worksheet, 2, 0, "internal:Sheet2!A1:B2", NULL);
2163
+ * worksheet_write_url(worksheet, 3, 0, "internal:'Sales Data'!A1", NULL);
2164
+ * worksheet_write_url(worksheet, 4, 0, "external:c:\\temp\\foo.xlsx", NULL);
2165
+ * worksheet_write_url(worksheet, 5, 0, "external:c:\\foo.xlsx#Sheet2!A1", NULL);
2166
+ * worksheet_write_url(worksheet, 6, 0, "external:..\\foo.xlsx", NULL);
2167
+ * worksheet_write_url(worksheet, 7, 0, "external:..\\foo.xlsx#Sheet2!A1", NULL);
2168
+ * worksheet_write_url(worksheet, 8, 0, "external:\\\\NET\\share\\foo.xlsx", NULL);
1175
2169
  *
1176
2170
  * @endcode
1177
2171
  *
@@ -1183,7 +2177,7 @@ lxw_error worksheet_write_url_opt(lxw_worksheet *worksheet,
1183
2177
  * `#` character:
1184
2178
  *
1185
2179
  * @code
1186
- * worksheet_write_url(worksheet, 0, 0, "external:c:\\foo.xlsx#Sheet2!A1", url_format);
2180
+ * worksheet_write_url(worksheet, 0, 0, "external:c:\\foo.xlsx#Sheet2!A1", NULL);
1187
2181
  * @endcode
1188
2182
  *
1189
2183
  * You can also link to a named range in the target worksheet: For example say
@@ -1191,7 +2185,7 @@ lxw_error worksheet_write_url_opt(lxw_worksheet *worksheet,
1191
2185
  * you could link to it as follows:
1192
2186
  *
1193
2187
  * @code
1194
- * worksheet_write_url(worksheet, 0, 0, "external:c:\\temp\\foo.xlsx#my_name", url_format);
2188
+ * worksheet_write_url(worksheet, 0, 0, "external:c:\\temp\\foo.xlsx#my_name", NULL);
1195
2189
  *
1196
2190
  * @endcode
1197
2191
  *
@@ -1199,14 +2193,14 @@ lxw_error worksheet_write_url_opt(lxw_worksheet *worksheet,
1199
2193
  * characters are single quoted as follows:
1200
2194
  *
1201
2195
  * @code
1202
- * worksheet_write_url(worksheet, 0, 0, "internal:'Sales Data'!A1", url_format);
2196
+ * worksheet_write_url(worksheet, 0, 0, "internal:'Sales Data'!A1", NULL);
1203
2197
  * @endcode
1204
2198
  *
1205
2199
  * Links to network files are also supported. Network files normally begin
1206
2200
  * with two back slashes as follows `\\NETWORK\etc`. In order to represent
1207
2201
  * this in a C string literal the backslashes should be escaped:
1208
2202
  * @code
1209
- * worksheet_write_url(worksheet, 0, 0, "external:\\\\NET\\share\\foo.xlsx", url_format);
2203
+ * worksheet_write_url(worksheet, 0, 0, "external:\\\\NET\\share\\foo.xlsx", NULL);
1210
2204
  * @endcode
1211
2205
  *
1212
2206
  *
@@ -1214,8 +2208,8 @@ lxw_error worksheet_write_url_opt(lxw_worksheet *worksheet,
1214
2208
  * translated internally to backslashes:
1215
2209
  *
1216
2210
  * @code
1217
- * worksheet_write_url(worksheet, 0, 0, "external:c:/temp/foo.xlsx", url_format);
1218
- * worksheet_write_url(worksheet, 1, 0, "external://NET/share/foo.xlsx", url_format);
2211
+ * worksheet_write_url(worksheet, 0, 0, "external:c:/temp/foo.xlsx", NULL);
2212
+ * worksheet_write_url(worksheet, 1, 0, "external://NET/share/foo.xlsx", NULL);
1219
2213
  *
1220
2214
  * @endcode
1221
2215
  *
@@ -1223,20 +2217,33 @@ lxw_error worksheet_write_url_opt(lxw_worksheet *worksheet,
1223
2217
  * **Note:**
1224
2218
  *
1225
2219
  * libxlsxwriter will escape the following characters in URLs as required
1226
- * by Excel: `\s " < > \ [ ] ^ { }` unless the URL already contains `%%xx`
1227
- * style escapes. In which case it is assumed that the URL was escaped
1228
- * correctly by the user and will by passed directly to Excel.
2220
+ * by Excel: `\s " < > \ [ ] ^ { }`. Existing URL `%%xx` style escapes in
2221
+ * the string are ignored to allow for user-escaped strings.
2222
+ *
2223
+ * **Note:**
1229
2224
  *
2225
+ * The maximum allowable URL length in recent versions of Excel is 2079
2226
+ * characters. In older versions of Excel (and libxlsxwriter <= 0.8.8) the
2227
+ * limit was 255 characters.
1230
2228
  */
1231
2229
  lxw_error worksheet_write_url(lxw_worksheet *worksheet,
1232
2230
  lxw_row_t row,
1233
2231
  lxw_col_t col, const char *url,
1234
2232
  lxw_format *format);
1235
2233
 
2234
+ /* Don't document for now since the string option can be achieved by a
2235
+ * subsequent cell worksheet_write() as shown in the docs, and the
2236
+ * tooltip option isn't very useful. */
2237
+ lxw_error worksheet_write_url_opt(lxw_worksheet *worksheet,
2238
+ lxw_row_t row_num,
2239
+ lxw_col_t col_num, const char *url,
2240
+ lxw_format *format, const char *string,
2241
+ const char *tooltip);
2242
+
1236
2243
  /**
1237
2244
  * @brief Write a formatted boolean worksheet cell.
1238
2245
  *
1239
- * @param worksheet pointer to a lxw_worksheet instance to be updated.
2246
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
1240
2247
  * @param row The zero indexed row number.
1241
2248
  * @param col The zero indexed column number.
1242
2249
  * @param value The boolean value to write to the cell.
@@ -1258,7 +2265,7 @@ lxw_error worksheet_write_boolean(lxw_worksheet *worksheet,
1258
2265
  /**
1259
2266
  * @brief Write a formatted blank worksheet cell.
1260
2267
  *
1261
- * @param worksheet pointer to a lxw_worksheet instance to be updated.
2268
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
1262
2269
  * @param row The zero indexed row number.
1263
2270
  * @param col The zero indexed column number.
1264
2271
  * @param format A pointer to a Format instance or NULL.
@@ -1287,20 +2294,21 @@ lxw_error worksheet_write_blank(lxw_worksheet *worksheet,
1287
2294
  lxw_format *format);
1288
2295
 
1289
2296
  /**
1290
- * @brief Write a formula to a worksheet cell with a user defined result.
2297
+ * @brief Write a formula to a worksheet cell with a user defined numeric
2298
+ * result.
1291
2299
  *
1292
- * @param worksheet pointer to a lxw_worksheet instance to be updated.
2300
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
1293
2301
  * @param row The zero indexed row number.
1294
2302
  * @param col The zero indexed column number.
1295
2303
  * @param formula Formula string to write to cell.
1296
2304
  * @param format A pointer to a Format instance or NULL.
1297
- * @param result A user defined result for a formula.
2305
+ * @param result A user defined numeric result for the formula.
1298
2306
  *
1299
2307
  * @return A #lxw_error code.
1300
2308
  *
1301
2309
  * The `%worksheet_write_formula_num()` function writes a formula or Excel
1302
2310
  * function to the cell specified by `row` and `column` with a user defined
1303
- * result:
2311
+ * numeric result:
1304
2312
  *
1305
2313
  * @code
1306
2314
  * // Required as a workaround only.
@@ -1335,10 +2343,55 @@ lxw_error worksheet_write_formula_num(lxw_worksheet *worksheet,
1335
2343
  const char *formula,
1336
2344
  lxw_format *format, double result);
1337
2345
 
2346
+ /**
2347
+ * @brief Write a formula to a worksheet cell with a user defined string
2348
+ * result.
2349
+ *
2350
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
2351
+ * @param row The zero indexed row number.
2352
+ * @param col The zero indexed column number.
2353
+ * @param formula Formula string to write to cell.
2354
+ * @param format A pointer to a Format instance or NULL.
2355
+ * @param result A user defined string result for the formula.
2356
+ *
2357
+ * @return A #lxw_error code.
2358
+ *
2359
+ * The `%worksheet_write_formula_str()` function writes a formula or Excel
2360
+ * function to the cell specified by `row` and `column` with a user defined
2361
+ * string result:
2362
+ *
2363
+ * @code
2364
+ * // The example formula is A & B -> AB.
2365
+ * worksheet_write_formula_str(worksheet, 0, 0, "=\"A\" & \"B\"", NULL, "AB");
2366
+ * @endcode
2367
+ *
2368
+ * The `%worksheet_write_formula_str()` function is similar to the
2369
+ * `%worksheet_write_formula_num()` function except it writes a string result
2370
+ * instead or a numeric result. See `worksheet_write_formula_num()` for more
2371
+ * details on why/when these functions are required.
2372
+ *
2373
+ * One place where the `%worksheet_write_formula_str()` function may be required
2374
+ * is to specify an empty result which will force a recalculation of the formula
2375
+ * when loaded in LibreOffice.
2376
+ *
2377
+ * @code
2378
+ * worksheet_write_formula_str(worksheet, 0, 0, "=Sheet1!$A$1", NULL, "");
2379
+ * @endcode
2380
+ *
2381
+ * See the FAQ @ref faq_formula_zero.
2382
+ *
2383
+ * See also @ref working_with_formulas.
2384
+ */
2385
+ lxw_error worksheet_write_formula_str(lxw_worksheet *worksheet,
2386
+ lxw_row_t row,
2387
+ lxw_col_t col,
2388
+ const char *formula,
2389
+ lxw_format *format, const char *result);
2390
+
1338
2391
  /**
1339
2392
  * @brief Write a "Rich" multi-format string to a worksheet cell.
1340
2393
  *
1341
- * @param worksheet pointer to a lxw_worksheet instance to be updated.
2394
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
1342
2395
  * @param row The zero indexed row number.
1343
2396
  * @param col The zero indexed column number.
1344
2397
  * @param rich_string An array of format/string lxw_rich_string_tuple fragments.
@@ -1410,6 +2463,88 @@ lxw_error worksheet_write_rich_string(lxw_worksheet *worksheet,
1410
2463
  lxw_rich_string_tuple *rich_string[],
1411
2464
  lxw_format *format);
1412
2465
 
2466
+ /**
2467
+ * @brief Write a comment to a worksheet cell.
2468
+ *
2469
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
2470
+ * @param row The zero indexed row number.
2471
+ * @param col The zero indexed column number.
2472
+ * @param string The comment string to be written.
2473
+ *
2474
+ * @return A #lxw_error code.
2475
+ *
2476
+ * The `%worksheet_write_comment()` function is used to add a comment to a
2477
+ * cell. A comment is indicated in Excel by a small red triangle in the upper
2478
+ * right-hand corner of the cell. Moving the cursor over the red triangle will
2479
+ * reveal the comment.
2480
+ *
2481
+ * The following example shows how to add a comment to a cell:
2482
+ *
2483
+ * @code
2484
+ * worksheet_write_comment(worksheet, 0, 0, "This is a comment");
2485
+ * @endcode
2486
+ *
2487
+ * @image html comments1.png
2488
+ *
2489
+ * See also @ref working_with_comments
2490
+ *
2491
+ */
2492
+ lxw_error worksheet_write_comment(lxw_worksheet *worksheet,
2493
+ lxw_row_t row, lxw_col_t col,
2494
+ const char *string);
2495
+
2496
+ /**
2497
+ * @brief Write a comment to a worksheet cell with options.
2498
+ *
2499
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
2500
+ * @param row The zero indexed row number.
2501
+ * @param col The zero indexed column number.
2502
+ * @param string The comment string to be written.
2503
+ * @param options #lxw_comment_options to control position and format
2504
+ * of the comment.
2505
+ *
2506
+ * @return A #lxw_error code.
2507
+ *
2508
+ * The `%worksheet_write_comment_opt()` function is used to add a comment to a
2509
+ * cell with option that control the position, format and metadata of the
2510
+ * comment. A comment is indicated in Excel by a small red triangle in the
2511
+ * upper right-hand corner of the cell. Moving the cursor over the red
2512
+ * triangle will reveal the comment.
2513
+ *
2514
+ * The following example shows how to add a comment to a cell with options:
2515
+ *
2516
+ * @code
2517
+ * lxw_comment_options options = {.visible = LXW_COMMENT_DISPLAY_VISIBLE};
2518
+ *
2519
+ * worksheet_write_comment_opt(worksheet, CELL("C6"), "Hello.", &options);
2520
+ * @endcode
2521
+ *
2522
+ * The following options are available in #lxw_comment_options:
2523
+ *
2524
+ * - `author`
2525
+ * - `visible`
2526
+ * - `width`
2527
+ * - `height`
2528
+ * - `x_scale`
2529
+ * - `y_scale`
2530
+ * - `color`
2531
+ * - `font_name`
2532
+ * - `font_size`
2533
+ * - `start_row`
2534
+ * - `start_col`
2535
+ * - `x_offset`
2536
+ * - `y_offset`
2537
+ *
2538
+ * @image html comments2.png
2539
+ *
2540
+ * Comment options are explained in detail in the @ref ww_comments_properties
2541
+ * section of the docs.
2542
+ */
2543
+ lxw_error worksheet_write_comment_opt(lxw_worksheet *worksheet,
2544
+ lxw_row_t row, lxw_col_t col,
2545
+ const char *string,
2546
+ lxw_comment_options *options);
2547
+
1413
2548
  /**
1414
2549
  * @brief Set the properties for a row of cells.
1415
2550
  *
@@ -1706,7 +2841,7 @@ lxw_error worksheet_set_column_opt(lxw_worksheet *worksheet,
1706
2841
  * default height changed due to a font that is larger than the default font
1707
2842
  * size or that has text wrapping turned on. To avoid this you should
1708
2843
  * explicitly set the height of the row using `worksheet_set_row()` if it
1709
- * crosses an inserted image.
2844
+ * crosses an inserted image. See @ref working_with_object_positioning.
1710
2845
  *
1711
2846
  * BMP images are only supported for backward compatibility. In general it is
1712
2847
  * best to avoid BMP images since they aren't compressed. If used, BMP images
@@ -1732,15 +2867,37 @@ lxw_error worksheet_insert_image(lxw_worksheet *worksheet,
1732
2867
  * #lxw_image_options struct to scale and position the image:
1733
2868
  *
1734
2869
  * @code
1735
- * lxw_image_options options = {.x_offset = 30, .y_offset = 10,
2870
+ * lxw_image_options options = {.x_offset = 30, .y_offset = 10,
1736
2871
  * .x_scale = 0.5, .y_scale = 0.5};
1737
2872
  *
1738
- * worksheet_insert_image_opt(worksheet, 2, 1, "logo.png", &options);
2873
+ * worksheet_insert_image_opt(worksheet, 2, 1, "logo.png", &options);
1739
2874
  *
1740
2875
  * @endcode
1741
2876
  *
1742
2877
  * @image html insert_image_opt.png
1743
2878
  *
2879
+ * The `url` field of lxw_image_options can be use to used to add a hyperlink
2880
+ * to an image:
2881
+ *
2882
+ * @code
2883
+ * lxw_image_options options = {.url = "https://github.com/jmcnamara"};
2884
+ *
2885
+ * worksheet_insert_image_opt(worksheet, 3, 1, "logo.png", &options);
2886
+ * @endcode
2887
+ *
2888
+ * The supported URL formats are the same as those supported by the
2889
+ * `worksheet_write_url()` method and the same rules/limits apply.
2890
+ *
2891
+ * The `tip` field of lxw_image_options can be use to used to add a mouseover
2892
+ * tip to the hyperlink:
2893
+ *
2894
+ * @code
2895
+ * lxw_image_options options = {.url = "https://github.com/jmcnamara",
2896
+ .tip = "GitHub"};
2897
+ *
2898
+ * worksheet_insert_image_opt(worksheet, 4, 1, "logo.png", &options);
2899
+ * @endcode
2900
+ *
1744
2901
  * @note See the notes about row scaling and BMP images in
1745
2902
  * `worksheet_insert_image()` above.
1746
2903
  */
@@ -1871,10 +3028,10 @@ lxw_error worksheet_insert_chart(lxw_worksheet *worksheet,
1871
3028
  *
1872
3029
  * The `%worksheet_insert_chart_opt()` function is like
1873
3030
  * `worksheet_insert_chart()` function except that it takes an optional
1874
- * #lxw_image_options struct to scale and position the image of the chart:
3031
+ * #lxw_chart_options struct to scale and position the chart:
1875
3032
  *
1876
3033
  * @code
1877
- * lxw_image_options options = {.x_offset = 30, .y_offset = 10,
3034
+ * lxw_chart_options options = {.x_offset = 30, .y_offset = 10,
1878
3035
  * .x_scale = 0.5, .y_scale = 0.75};
1879
3036
  *
1880
3037
  * worksheet_insert_chart_opt(worksheet, 0, 2, chart, &options);
@@ -1883,14 +3040,11 @@ lxw_error worksheet_insert_chart(lxw_worksheet *worksheet,
1883
3040
  *
1884
3041
  * @image html chart_line_opt.png
1885
3042
  *
1886
- * The #lxw_image_options struct is the same struct used in
1887
- * `worksheet_insert_image_opt()` to position and scale images.
1888
- *
1889
3043
  */
1890
3044
  lxw_error worksheet_insert_chart_opt(lxw_worksheet *worksheet,
1891
3045
  lxw_row_t row, lxw_col_t col,
1892
3046
  lxw_chart *chart,
1893
- lxw_image_options *user_options);
3047
+ lxw_chart_options *user_options);
1894
3048
 
1895
3049
  /**
1896
3050
  * @brief Merge a range of cells.
@@ -1949,7 +3103,7 @@ lxw_error worksheet_insert_chart_opt(lxw_worksheet *worksheet,
1949
3103
  * worksheet_write_number(worksheet, 1, 1, 123, format);
1950
3104
  * @endcode
1951
3105
  *
1952
- * @note Merged ranges generally dont work in libxlsxwriter when the Workbook
3106
+ * @note Merged ranges generally don't work in libxlsxwriter when the Workbook
1953
3107
  * #lxw_workbook_options `constant_memory` mode is enabled.
1954
3108
  */
1955
3109
  lxw_error worksheet_merge_range(lxw_worksheet *worksheet, lxw_row_t first_row,
@@ -2033,7 +3187,7 @@ lxw_error worksheet_data_validation_cell(lxw_worksheet *worksheet,
2033
3187
  lxw_data_validation *validation);
2034
3188
 
2035
3189
  /**
2036
- * @brief Add a data validation to a range cell.
3190
+ * @brief Add a data validation to a range.
2037
3191
  *
2038
3192
  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
2039
3193
  * @param first_row The first row of the range. (All zero indexed.)
@@ -2074,6 +3228,85 @@ lxw_error worksheet_data_validation_range(lxw_worksheet *worksheet,
2074
3228
  lxw_col_t last_col,
2075
3229
  lxw_data_validation *validation);
2076
3230
 
3231
+ /**
3232
+ * @brief Add a conditional format to a worksheet cell.
3233
+ *
3234
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
3235
+ * @param row The zero indexed row number.
3236
+ * @param col The zero indexed column number.
3237
+ * @param conditional_format A #lxw_conditional_format object to control the
3238
+ * conditional format.
3239
+ *
3240
+ * @return A #lxw_error code.
3241
+ *
3242
+ * The `%worksheet_conditional_format_cell()` function is used to set a
3243
+ * conditional format for a cell in a worksheet:
3244
+ *
3245
+ * @code
3246
+ * conditional_format->type = LXW_CONDITIONAL_TYPE_CELL;
3247
+ * conditional_format->criteria = LXW_CONDITIONAL_CRITERIA_GREATER_THAN_OR_EQUAL_TO;
3248
+ * conditional_format->value = 50;
3249
+ * conditional_format->format = format1;
3250
+ * worksheet_conditional_format_cell(worksheet, CELL("A1"), conditional_format);
3251
+ * @endcode
3252
+ *
3253
+ * The conditional format parameters is specified in #lxw_conditional_format.
3254
+ *
3255
+ * See @ref working_with_conditional_formatting for full details.
3256
+ */
3257
+ lxw_error worksheet_conditional_format_cell(lxw_worksheet *worksheet,
3258
+ lxw_row_t row,
3259
+ lxw_col_t col,
3260
+ lxw_conditional_format
3261
+ *conditional_format);
3262
+
3263
+ /**
3264
+ * @brief Add a conditional format to a worksheet range.
3265
+ *
3266
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
3267
+ * @param first_row The first row of the range. (All zero indexed.)
3268
+ * @param first_col The first column of the range.
3269
+ * @param last_row The last row of the range.
3270
+ * @param last_col The last col of the range.
3271
+ * @param conditional_format A #lxw_conditional_format object to control the
3272
+ * conditional format.
3273
+ *
3274
+ * @return A #lxw_error code.
3275
+ *
3276
+ * The `%worksheet_conditional_format_cell()` function is used to set a
3277
+ * conditional format for a range of cells in a worksheet:
3278
+ *
3279
+ * @code
3280
+ * conditional_format->type = LXW_CONDITIONAL_TYPE_CELL;
3281
+ * conditional_format->criteria = LXW_CONDITIONAL_CRITERIA_GREATER_THAN_OR_EQUAL_TO;
3282
+ * conditional_format->value = 50;
3283
+ * conditional_format->format = format1;
3284
+ * worksheet_conditional_format_range(worksheet1, RANGE("B3:K12"), conditional_format);
3285
+ *
3286
+ * conditional_format->type = LXW_CONDITIONAL_TYPE_CELL;
3287
+ * conditional_format->criteria = LXW_CONDITIONAL_CRITERIA_LESS_THAN;
3288
+ * conditional_format->value = 50;
3289
+ * conditional_format->format = format2;
3290
+ * worksheet_conditional_format_range(worksheet1, RANGE("B3:K12"), conditional_format);
3291
+ * @endcode
3292
+ *
3293
+ * Output:
3294
+ *
3295
+ * @image html conditional_format1.png
3296
+ *
3297
+ *
3298
+ * The conditional format parameters is specified in #lxw_conditional_format.
3299
+ *
3300
+ * See @ref working_with_conditional_formatting for full details.
3301
+ */
3302
+ lxw_error worksheet_conditional_format_range(lxw_worksheet *worksheet,
3303
+ lxw_row_t first_row,
3304
+ lxw_col_t first_col,
3305
+ lxw_row_t last_row,
3306
+ lxw_col_t last_col,
3307
+ lxw_conditional_format
3308
+ *conditional_format);
3309
+
2077
3310
  /**
2078
3311
  * @brief Make a worksheet the active, i.e., visible worksheet.
2079
3312
  *
@@ -2251,7 +3484,7 @@ void worksheet_split_panes_opt(lxw_worksheet *worksheet,
2251
3484
  /**
2252
3485
  * @brief Set the selected cell or cells in a worksheet:
2253
3486
  *
2254
- * @param worksheet Pointer to a lxw_worksheet instance to be updated.
3487
+ * @param worksheet A pointer to a lxw_worksheet instance to be updated.
2255
3488
  * @param first_row The first row of the range. (All zero indexed.)
2256
3489
  * @param first_col The first column of the range.
2257
3490
  * @param last_row The last row of the range.
@@ -2446,7 +3679,11 @@ void worksheet_set_margins(lxw_worksheet *worksheet, double left,
2446
3679
  * | `&S` | | Strikethrough |
2447
3680
  * | `&X` | | Superscript |
2448
3681
  * | `&Y` | | Subscript |
3682
+ * | `&[Picture]` | Images | Image placeholder |
3683
+ * | `&G` | | Same as `&[Picture]` |
3684
+ * | `&&` | Miscellaneous | Literal ampersand & |
2449
3685
  *
3686
+ * Note: inserting images requires the `worksheet_set_header_opt()` function.
2450
3687
  *
2451
3688
  * Text in headers and footers can be justified (aligned) to the left, center
2452
3689
  * and right by prefixing the text with the control characters `&L`, `&C` and
@@ -2570,17 +3807,14 @@ void worksheet_set_margins(lxw_worksheet *worksheet, double left,
2570
3807
  * @code
2571
3808
  *
2572
3809
  * $ unzip myfile.xlsm -d myfile
2573
- * $ xmllint --format `find myfile -name "*.xml" | xargs` | egrep "Header|Footer"
3810
+ * $ xmllint --format `find myfile -name "*.xml" | xargs` | egrep "Header|Footer" | sed 's/&amp;/\&/g'
2574
3811
  *
2575
3812
  * <headerFooter scaleWithDoc="0">
2576
- * <oddHeader>&amp;L&amp;P</oddHeader>
3813
+ * <oddHeader>&L&P</oddHeader>
2577
3814
  * </headerFooter>
2578
3815
  *
2579
3816
  * @endcode
2580
3817
  *
2581
- * Note that in this case you need to unescape the Html. In the above example
2582
- * the header string would be `&L&P`.
2583
- *
2584
3818
  * To include a single literal ampersand `&` in a header or footer you should
2585
3819
  * use a double ampersand `&&`:
2586
3820
  *
@@ -2588,8 +3822,8 @@ void worksheet_set_margins(lxw_worksheet *worksheet, double left,
2588
3822
  * worksheet_set_header(worksheet, "&CCuriouser && Curiouser - Attorneys at Law");
2589
3823
  * @endcode
2590
3824
  *
2591
- * Note, the header or footer string must be less than 255 characters. Strings
2592
- * longer than this will not be written.
3825
+ * Note, Excel requires that the header or footer string must be less than 255
3826
+ * characters. Strings longer than this will not be written.
2593
3827
  *
2594
3828
  */
2595
3829
  lxw_error worksheet_set_header(lxw_worksheet *worksheet, const char *string);
@@ -2616,19 +3850,43 @@ lxw_error worksheet_set_footer(lxw_worksheet *worksheet, const char *string);
2616
3850
  *
2617
3851
  * @return A #lxw_error code.
2618
3852
  *
2619
- * The syntax of this function is the same as worksheet_set_header() with an
3853
+ * The syntax of this function is the same as `worksheet_set_header()` with an
2620
3854
  * additional parameter to specify options for the header.
2621
3855
  *
2622
- * Currently, the only available option is the header margin:
3856
+ * The #lxw_header_footer_options options are:
3857
+ *
3858
+ * - `margin`: Header or footer margin in inches. The value must by larger
3859
+ * than 0.0. The Excel default is 0.3.
3860
+ *
3861
+ * - `image_left`: The left header image filename, with path if required. This
3862
+ * should have a corresponding `&G/&[Picture]` placeholder in the `&L`
3863
+ * section of the header/footer string.
3864
+ *
3865
+ * - `image_center`: The center header image filename, with path if
3866
+ * required. This should have a corresponding `&G/&[Picture]` placeholder in
3867
+ * the `&C` section of the header/footer string.
3868
+ *
3869
+ * - `image_right`: The right header image filename, with path if
3870
+ * required. This should have a corresponding `&G/&[Picture]` placeholder in
3871
+ * the `&R` section of the header/footer string.
2623
3872
  *
2624
3873
  * @code
3874
+ * lxw_header_footer_options header_options = { .margin = 0.2 };
2625
3875
  *
2626
- * lxw_header_footer_options header_options = { 0.2 };
3876
+ * worksheet_set_header_opt(worksheet, "Some text", &header_options);
3877
+ * @endcode
3878
+ *
3879
+ * Images can be inserted in the header by specifying the `&[Picture]`
3880
+ * placeholder and a filename/path to the image:
2627
3881
  *
2628
- * worksheet_set_header_opt(worksheet, "Some text", &header_options);
3882
+ * @code
3883
+ * lxw_header_footer_options header_options = {.image_left = "logo.png"};
2629
3884
  *
3885
+ * worksheet_set_header_opt(worksheet, "&L&[Picture]", &header_options);
2630
3886
  * @endcode
2631
3887
  *
3888
+ * @image html headers_footers.png
3889
+ *
2632
3890
  */
2633
3891
  lxw_error worksheet_set_header_opt(lxw_worksheet *worksheet,
2634
3892
  const char *string,
@@ -2643,7 +3901,7 @@ lxw_error worksheet_set_header_opt(lxw_worksheet *worksheet,
2643
3901
  *
2644
3902
  * @return A #lxw_error code.
2645
3903
  *
2646
- * The syntax of this function is the same as worksheet_set_header_opt().
3904
+ * The syntax of this function is the same as `worksheet_set_header_opt()`.
2647
3905
  *
2648
3906
  */
2649
3907
  lxw_error worksheet_set_footer_opt(lxw_worksheet *worksheet,
@@ -3241,6 +4499,8 @@ void worksheet_set_default_row(lxw_worksheet *worksheet, double height,
3241
4499
  * @param worksheet Pointer to a lxw_worksheet instance.
3242
4500
  * @param name Name of the worksheet used by VBA.
3243
4501
  *
4502
+ * @return A #lxw_error.
4503
+ *
3244
4504
  * The `worksheet_set_vba_name()` function can be used to set the VBA name for
3245
4505
  * the worksheet. This is sometimes required when a vbaProject macro included
3246
4506
  * via `workbook_add_vba_project()` refers to the worksheet by a name other
@@ -3256,10 +4516,147 @@ void worksheet_set_default_row(lxw_worksheet *worksheet, double height,
3256
4516
  * extracted from a foreign language version of Excel.
3257
4517
  *
3258
4518
  * See also @ref working_with_macros
4519
+ */
4520
+ lxw_error worksheet_set_vba_name(lxw_worksheet *worksheet, const char *name);
4521
+
4522
+ /**
4523
+ * @brief Make all comments in the worksheet visible.
4524
+ *
4525
+ * @param worksheet Pointer to a lxw_worksheet instance.
4526
+ *
4527
+ * This `%worksheet_show_comments()` function is used to make all cell
4528
+ * comments visible when a worksheet is opened:
4529
+ *
4530
+ * @code
4531
+ * worksheet_show_comments(worksheet);
4532
+ * @endcode
4533
+ *
4534
+ * Individual comments can be made visible or hidden using the `visible`
4535
+ * option of the #lxw_comment_options struct and the `worksheet_write_comment_opt()`
4536
+ * function (see above and @ref ww_comments_visible).
4537
+ */
4538
+ void worksheet_show_comments(lxw_worksheet *worksheet);
4539
+
4540
+ /**
4541
+ * @brief Set the default author of the cell comments.
4542
+ *
4543
+ * @param worksheet Pointer to a lxw_worksheet instance.
4544
+ * @param author The name of the comment author.
4545
+ *
4546
+ * This `%worksheet_set_comments_author()` function is used to set the
4547
+ * default author of all cell comments:
4548
+ *
4549
+ * @code
4550
+ * worksheet_set_comments_author(worksheet, "Jane Gloriana Villanueva")
4551
+ * @endcode
4552
+ *
4553
+ * Individual authors can be set using the `author` option of the
4554
+ * #lxw_comment_options struct and the `worksheet_write_comment_opt()`
4555
+ * function (see above and @ref ww_comments_author).
4556
+ */
4557
+ void worksheet_set_comments_author(lxw_worksheet *worksheet,
4558
+ const char *author);
4559
+
4560
+ /**
4561
+ * @brief Ignore various Excel errors/warnings in a worksheet for user
4562
+ * defined ranges.
4563
+ *
4564
+ * @param worksheet Pointer to a lxw_worksheet instance.
4565
+ * @param type The type of error/warning to ignore. See #lxw_ignore_errors.
4566
+ * @param range The range(s) for which the error/warning should be ignored.
3259
4567
  *
3260
4568
  * @return A #lxw_error.
4569
+ *
4570
+ *
4571
+ * The `%worksheet_ignore_errors()` function can be used to ignore various
4572
+ * worksheet cell errors/warnings. For example the following code writes a string
4573
+ * that looks like a number:
4574
+ *
4575
+ * @code
4576
+ * worksheet_write_string(worksheet, CELL("D2"), "123", NULL);
4577
+ * @endcode
4578
+ *
4579
+ * This causes Excel to display a small green triangle in the top left hand
4580
+ * corner of the cell to indicate an error/warning:
4581
+ *
4582
+ * @image html ignore_errors1.png
4583
+ *
4584
+ * Sometimes these warnings are useful indicators that there is an issue in
4585
+ * the spreadsheet but sometimes it is preferable to turn them off. Warnings
4586
+ * can be turned off at the Excel level for all workbooks and worksheets by
4587
+ * using the using "Excel options -> Formulas -> Error checking
4588
+ * rules". Alternatively you can turn them off for individual cells in a
4589
+ * worksheet, or ranges of cells, using the `%worksheet_ignore_errors()`
4590
+ * function with different #lxw_ignore_errors options and ranges like this:
4591
+ *
4592
+ * @code
4593
+ * worksheet_ignore_errors(worksheet, LXW_IGNORE_NUMBER_STORED_AS_TEXT, "C3");
4594
+ * worksheet_ignore_errors(worksheet, LXW_IGNORE_EVAL_ERROR, "C6");
4595
+ * @endcode
4596
+ *
4597
+ * The range can be a single cell, a range of cells, or multiple cells and ranges
4598
+ * separated by spaces:
4599
+ *
4600
+ * @code
4601
+ * // Single cell.
4602
+ * worksheet_ignore_errors(worksheet, LXW_IGNORE_NUMBER_STORED_AS_TEXT, "C6");
4603
+ *
4604
+ * // Or a single range:
4605
+ * worksheet_ignore_errors(worksheet, LXW_IGNORE_NUMBER_STORED_AS_TEXT, "C6:G8");
4606
+ *
4607
+ * // Or multiple cells and ranges:
4608
+ * worksheet_ignore_errors(worksheet, LXW_IGNORE_NUMBER_STORED_AS_TEXT, "C6 E6 G1:G20 J2:J6");
4609
+ * @endcode
4610
+ *
4611
+ * @note Calling `%worksheet_ignore_errors()` more than once for the same
4612
+ * #lxw_ignore_errors type will overwrite the previous range.
4613
+ *
4614
+ * You can turn off warnings for an entire column by specifying the range from
4615
+ * the first cell in the column to the last cell in the column:
4616
+ *
4617
+ * @code
4618
+ * worksheet_ignore_errors(worksheet, LXW_IGNORE_NUMBER_STORED_AS_TEXT, "A1:A1048576");
4619
+ * @endcode
4620
+ *
4621
+ * Or for the entire worksheet by specifying the range from the first cell in
4622
+ * the worksheet to the last cell in the worksheet:
4623
+ *
4624
+ * @code
4625
+ * worksheet_ignore_errors(worksheet, LXW_IGNORE_NUMBER_STORED_AS_TEXT, "A1:XFD1048576");
4626
+ * @endcode
4627
+ *
4628
+ * The worksheet errors/warnings that can be ignored are:
4629
+ *
4630
+ * - #LXW_IGNORE_NUMBER_STORED_AS_TEXT: Turn off errors/warnings for numbers
4631
+ * stores as text.
4632
+ *
4633
+ * - #LXW_IGNORE_EVAL_ERROR: Turn off errors/warnings for formula errors (such
4634
+ * as divide by zero).
4635
+ *
4636
+ * - #LXW_IGNORE_FORMULA_DIFFERS: Turn off errors/warnings for formulas that
4637
+ * differ from surrounding formulas.
4638
+ *
4639
+ * - #LXW_IGNORE_FORMULA_RANGE: Turn off errors/warnings for formulas that
4640
+ * omit cells in a range.
4641
+ *
4642
+ * - #LXW_IGNORE_FORMULA_UNLOCKED: Turn off errors/warnings for unlocked cells
4643
+ * that contain formulas.
4644
+ *
4645
+ * - #LXW_IGNORE_EMPTY_CELL_REFERENCE: Turn off errors/warnings for formulas
4646
+ * that refer to empty cells.
4647
+ *
4648
+ * - #LXW_IGNORE_LIST_DATA_VALIDATION: Turn off errors/warnings for cells in a
4649
+ * table that do not comply with applicable data validation rules.
4650
+ *
4651
+ * - #LXW_IGNORE_CALCULATED_COLUMN: Turn off errors/warnings for cell formulas
4652
+ * that differ from the column formula.
4653
+ *
4654
+ * - #LXW_IGNORE_TWO_DIGIT_TEXT_YEAR: Turn off errors/warnings for formulas
4655
+ * that contain a two digit text representation of a year.
4656
+ *
3261
4657
  */
3262
- lxw_error worksheet_set_vba_name(lxw_worksheet *worksheet, const char *name);
4658
+ lxw_error worksheet_ignore_errors(lxw_worksheet *worksheet, uint8_t type,
4659
+ const char *range);
3263
4660
 
3264
4661
  lxw_worksheet *lxw_worksheet_new(lxw_worksheet_init_data *init_data);
3265
4662
  void lxw_worksheet_free(lxw_worksheet *worksheet);
@@ -3268,24 +4665,37 @@ void lxw_worksheet_write_single_row(lxw_worksheet *worksheet);
3268
4665
 
3269
4666
  void lxw_worksheet_prepare_image(lxw_worksheet *worksheet,
3270
4667
  uint32_t image_ref_id, uint32_t drawing_id,
3271
- lxw_image_options *image_data);
4668
+ lxw_object_properties *object_props);
4669
+
4670
+ void lxw_worksheet_prepare_header_image(lxw_worksheet *worksheet,
4671
+ uint32_t image_ref_id,
4672
+ lxw_object_properties *object_props);
3272
4673
 
3273
4674
  void lxw_worksheet_prepare_chart(lxw_worksheet *worksheet,
3274
4675
  uint32_t chart_ref_id, uint32_t drawing_id,
3275
- lxw_image_options *image_data,
4676
+ lxw_object_properties *object_props,
3276
4677
  uint8_t is_chartsheet);
3277
4678
 
3278
- lxw_row *lxw_worksheet_find_row(lxw_worksheet *worksheet, lxw_row_t row_num);
3279
- lxw_cell *lxw_worksheet_find_cell(lxw_row *row, lxw_col_t col_num);
4679
+ uint32_t lxw_worksheet_prepare_vml_objects(lxw_worksheet *worksheet,
4680
+ uint32_t vml_data_id,
4681
+ uint32_t vml_shape_id,
4682
+ uint32_t vml_drawing_id,
4683
+ uint32_t comment_id);
4684
+
4685
+ void lxw_worksheet_prepare_header_vml_objects(lxw_worksheet *self,
4686
+ uint32_t vml_header_id,
4687
+ uint32_t vml_drawing_id);
3280
4688
 
4689
+ lxw_row *lxw_worksheet_find_row(lxw_worksheet *worksheet, lxw_row_t row_num);
4690
+ lxw_cell *lxw_worksheet_find_cell_in_row(lxw_row *row, lxw_col_t col_num);
3281
4691
  /*
3282
- * External functions to call intern XML methods shared with chartsheet.
4692
+ * External functions to call intern XML functions shared with chartsheet.
3283
4693
  */
3284
4694
  void lxw_worksheet_write_sheet_views(lxw_worksheet *worksheet);
3285
4695
  void lxw_worksheet_write_page_margins(lxw_worksheet *worksheet);
3286
4696
  void lxw_worksheet_write_drawings(lxw_worksheet *worksheet);
3287
4697
  void lxw_worksheet_write_sheet_protection(lxw_worksheet *worksheet,
3288
- lxw_protection *protect);
4698
+ lxw_protection_obj *protect);
3289
4699
  void lxw_worksheet_write_sheet_pr(lxw_worksheet *worksheet);
3290
4700
  void lxw_worksheet_write_page_setup(lxw_worksheet *worksheet);
3291
4701
  void lxw_worksheet_write_header_footer(lxw_worksheet *worksheet);
@@ -3320,7 +4730,7 @@ STATIC void _worksheet_write_print_options(lxw_worksheet *worksheet);
3320
4730
  STATIC void _worksheet_write_sheet_pr(lxw_worksheet *worksheet);
3321
4731
  STATIC void _worksheet_write_tab_color(lxw_worksheet *worksheet);
3322
4732
  STATIC void _worksheet_write_sheet_protection(lxw_worksheet *worksheet,
3323
- lxw_protection *protect);
4733
+ lxw_protection_obj *protect);
3324
4734
  STATIC void _worksheet_write_data_validations(lxw_worksheet *self);
3325
4735
  #endif /* TESTING */
3326
4736