xlsxwriter 0.2.1.pre.2 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (117) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +4 -3
  3. data/ext/xlsxwriter/chart.c +20 -2
  4. data/ext/xlsxwriter/extconf.rb +8 -8
  5. data/ext/xlsxwriter/libxlsxwriter/License.txt +24 -2
  6. data/ext/xlsxwriter/libxlsxwriter/Makefile +46 -12
  7. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/app.h +1 -1
  8. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/chart.h +196 -30
  9. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/chartsheet.h +3 -3
  10. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/comment.h +76 -0
  11. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/common.h +24 -5
  12. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/content_types.h +5 -1
  13. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/core.h +1 -1
  14. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/custom.h +1 -1
  15. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/drawing.h +6 -17
  16. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/format.h +20 -6
  17. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/hash_table.h +1 -1
  18. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/packager.h +3 -1
  19. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/relationships.h +1 -1
  20. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/shared_strings.h +1 -1
  21. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/styles.h +11 -5
  22. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/theme.h +1 -1
  23. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/third_party/md5.h +43 -0
  24. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/utility.h +42 -3
  25. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/vml.h +55 -0
  26. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/workbook.h +83 -18
  27. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/worksheet.h +1519 -109
  28. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/xmlwriter.h +4 -2
  29. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter.h +3 -2
  30. data/ext/xlsxwriter/libxlsxwriter/src/Makefile +25 -7
  31. data/ext/xlsxwriter/libxlsxwriter/src/app.c +1 -1
  32. data/ext/xlsxwriter/libxlsxwriter/src/chart.c +332 -48
  33. data/ext/xlsxwriter/libxlsxwriter/src/chartsheet.c +20 -19
  34. data/ext/xlsxwriter/libxlsxwriter/src/comment.c +443 -0
  35. data/ext/xlsxwriter/libxlsxwriter/src/content_types.c +20 -1
  36. data/ext/xlsxwriter/libxlsxwriter/src/core.c +2 -2
  37. data/ext/xlsxwriter/libxlsxwriter/src/custom.c +1 -1
  38. data/ext/xlsxwriter/libxlsxwriter/src/drawing.c +58 -20
  39. data/ext/xlsxwriter/libxlsxwriter/src/format.c +98 -25
  40. data/ext/xlsxwriter/libxlsxwriter/src/hash_table.c +1 -1
  41. data/ext/xlsxwriter/libxlsxwriter/src/packager.c +269 -12
  42. data/ext/xlsxwriter/libxlsxwriter/src/relationships.c +1 -1
  43. data/ext/xlsxwriter/libxlsxwriter/src/shared_strings.c +2 -4
  44. data/ext/xlsxwriter/libxlsxwriter/src/styles.c +334 -48
  45. data/ext/xlsxwriter/libxlsxwriter/src/theme.c +1 -1
  46. data/ext/xlsxwriter/libxlsxwriter/src/utility.c +71 -8
  47. data/ext/xlsxwriter/libxlsxwriter/src/vml.c +1032 -0
  48. data/ext/xlsxwriter/libxlsxwriter/src/workbook.c +343 -27
  49. data/ext/xlsxwriter/libxlsxwriter/src/worksheet.c +3759 -478
  50. data/ext/xlsxwriter/libxlsxwriter/src/xmlwriter.c +81 -2
  51. data/ext/xlsxwriter/libxlsxwriter/third_party/md5/Makefile +42 -0
  52. data/ext/xlsxwriter/libxlsxwriter/third_party/md5/md5.c +291 -0
  53. data/ext/xlsxwriter/libxlsxwriter/third_party/md5/md5.h +43 -0
  54. data/ext/xlsxwriter/shared_strings.c +65 -0
  55. data/ext/xlsxwriter/shared_strings.h +15 -0
  56. data/ext/xlsxwriter/workbook.c +56 -1
  57. data/ext/xlsxwriter/worksheet.c +31 -2
  58. data/ext/xlsxwriter/worksheet.h +1 -0
  59. data/ext/xlsxwriter/xlsxwriter.c +2 -0
  60. data/lib/xlsxwriter/rich_string.rb +0 -2
  61. data/lib/xlsxwriter/version.rb +1 -1
  62. data/lib/xlsxwriter/worksheet.rb +2 -2
  63. data/test/{run-test.rb → run_test.rb} +3 -3
  64. data/test/support/chart_test.rb +3 -3
  65. data/test/support/with_xlsx_file.rb +4 -2
  66. data/test/support/xlsx_comparable.rb +40 -26
  67. data/test/test_array_formula.rb +42 -0
  68. data/test/test_autofilter.rb +72 -0
  69. data/test/{test-chart-area.rb → test_chart_area.rb} +2 -2
  70. data/test/{test-chart-axis.rb → test_chart_axis.rb} +16 -16
  71. data/test/test_chart_bar.rb +382 -0
  72. data/test/test_chart_blank.rb +27 -0
  73. data/test/{test-chart-column.rb → test_chart_column.rb} +2 -2
  74. data/test/{test-chart-doughnut.rb → test_chart_doughnut.rb} +2 -2
  75. data/test/{test-chart-legend.rb → test_chart_legend.rb} +2 -2
  76. data/test/{test-chart-pie.rb → test_chart_pie.rb} +2 -2
  77. data/test/{test-chart-scatter.rb → test_chart_scatter.rb} +3 -4
  78. data/test/{test-chart-size.rb → test_chart_size.rb} +2 -2
  79. data/test/{test-chart-title.rb → test_chart_title.rb} +3 -3
  80. data/test/{test-chartsheet.rb → test_chartsheet.rb} +2 -2
  81. data/test/{test-data.rb → test_data.rb} +1 -1
  82. data/test/{test-data-validation.rb → test_data_validation.rb} +23 -24
  83. data/test/{test-default-row.rb → test_default_row.rb} +1 -1
  84. data/test/{test-defined-name.rb → test_defined_name.rb} +12 -12
  85. data/test/{test-escapes.rb → test_escapes.rb} +5 -2
  86. data/test/{test-fit-to-pages.rb → test_fit_to_pages.rb} +6 -6
  87. data/test/{test-formatting.rb → test_formatting.rb} +10 -10
  88. data/test/{test-gridlines.rb → test_gridlines.rb} +3 -3
  89. data/test/{test-hyperlink.rb → test_hyperlink.rb} +22 -11
  90. data/test/{test-image.rb → test_image.rb} +6 -4
  91. data/test/{test-macro.rb → test_macro.rb} +1 -1
  92. data/test/{test-merge-range.rb → test_merge_range.rb} +1 -1
  93. data/test/{test-misc.rb → test_misc.rb} +2 -2
  94. data/test/{test-optimize.rb → test_optimize.rb} +2 -4
  95. data/test/{test-outline.rb → test_outline.rb} +14 -14
  96. data/test/{test-page-breaks.rb → test_page_breaks.rb} +2 -2
  97. data/test/{test-page-setup.rb → test_page_setup.rb} +2 -2
  98. data/test/{test-panes.rb → test_panes.rb} +1 -1
  99. data/test/{test-print-area.rb → test_print_area.rb} +3 -3
  100. data/test/{test-print-options.rb → test_print_options.rb} +7 -7
  101. data/test/{test-print-scale.rb → test_print_scale.rb} +2 -2
  102. data/test/{test-properties.rb → test_properties.rb} +2 -2
  103. data/test/{test-protect.rb → test_protect.rb} +3 -3
  104. data/test/{test-repeat.rb → test_repeat.rb} +3 -3
  105. data/test/{test-rich-string.rb → test_rich_string.rb} +5 -9
  106. data/test/{test-row-col-format.rb → test_row_col_format.rb} +1 -1
  107. data/test/{test-ruby-worksheet.rb → test_ruby_worksheet.rb} +2 -2
  108. data/test/{test-set-selection.rb → test_set_selection.rb} +2 -2
  109. data/test/{test-set-start-page.rb → test_set_start_page.rb} +2 -2
  110. data/test/{test-simple.rb → test_simple.rb} +10 -10
  111. data/test/{test-types.rb → test_types.rb} +1 -1
  112. data/test/{xlsx-func-testcase.rb → xlsx_func_testcase.rb} +1 -0
  113. metadata +132 -106
  114. data/test/test-array-formula.rb +0 -35
  115. data/test/test-autofilter.rb +0 -72
  116. data/test/test-chart-bar.rb +0 -74
  117. /data/test/{test-errors.rb → test_errors.rb} +0 -0
@@ -0,0 +1,443 @@
1
+ /*****************************************************************************
2
+ * comment - A library for creating Excel XLSX comment files.
3
+ *
4
+ * Used in conjunction with the libxlsxwriter library.
5
+ *
6
+ * Copyright 2014-2020, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
7
+ *
8
+ */
9
+
10
+ #include "xlsxwriter/xmlwriter.h"
11
+ #include "xlsxwriter/comment.h"
12
+ #include "xlsxwriter/utility.h"
13
+
14
+ /*
15
+ * Forward declarations.
16
+ */
17
+
18
+ STATIC int _author_id_cmp(lxw_author_id *tuple1, lxw_author_id *tuple2);
19
+
20
+ #ifndef __clang_analyzer__
21
+ LXW_RB_GENERATE_AUTHOR_IDS(lxw_author_ids, lxw_author_id,
22
+ tree_pointers, _author_id_cmp);
23
+ #endif
24
+
25
+ /*****************************************************************************
26
+ *
27
+ * Private functions.
28
+ *
29
+ ****************************************************************************/
30
+
31
+ /*
32
+ * Comparator for the author ids.
33
+ */
34
+ STATIC int
35
+ _author_id_cmp(lxw_author_id *author_id1, lxw_author_id *author_id2)
36
+ {
37
+ return strcmp(author_id1->author, author_id2->author);
38
+ }
39
+
40
+ /*
41
+ * Check if an author already existing in the author/id table.
42
+ */
43
+ STATIC uint8_t
44
+ _check_author(lxw_comment *self, char *author)
45
+ {
46
+ lxw_author_id tmp_author_id;
47
+ lxw_author_id *existing_author = NULL;
48
+
49
+ if (!author)
50
+ return LXW_TRUE;
51
+
52
+ tmp_author_id.author = author;
53
+ existing_author = RB_FIND(lxw_author_ids,
54
+ self->author_ids, &tmp_author_id);
55
+
56
+ if (existing_author)
57
+ return LXW_TRUE;
58
+ else
59
+ return LXW_FALSE;
60
+ }
61
+
62
+ /*
63
+ * Get the index used for an author name.
64
+ */
65
+ STATIC uint32_t
66
+ _get_author_index(lxw_comment *self, char *author)
67
+ {
68
+ lxw_author_id tmp_author_id;
69
+ lxw_author_id *existing_author = NULL;
70
+ lxw_author_id *new_author_id = NULL;
71
+
72
+ if (!author)
73
+ return 0;
74
+
75
+ tmp_author_id.author = author;
76
+ existing_author = RB_FIND(lxw_author_ids,
77
+ self->author_ids, &tmp_author_id);
78
+
79
+ if (existing_author) {
80
+ return existing_author->id;
81
+ }
82
+ else {
83
+ new_author_id = calloc(1, sizeof(lxw_author_id));
84
+
85
+ if (new_author_id) {
86
+ new_author_id->id = self->author_id;
87
+ new_author_id->author = lxw_strdup(author);
88
+ self->author_id++;
89
+
90
+ RB_INSERT(lxw_author_ids, self->author_ids, new_author_id);
91
+
92
+ return new_author_id->id;
93
+ }
94
+ else {
95
+ return 0;
96
+ }
97
+ }
98
+ }
99
+
100
+ /*
101
+ * Create a new comment object.
102
+ */
103
+ lxw_comment *
104
+ lxw_comment_new(void)
105
+ {
106
+ lxw_comment *comment = calloc(1, sizeof(lxw_comment));
107
+ GOTO_LABEL_ON_MEM_ERROR(comment, mem_error);
108
+
109
+ comment->author_ids = calloc(1, sizeof(struct lxw_author_ids));
110
+ GOTO_LABEL_ON_MEM_ERROR(comment->author_ids, mem_error);
111
+ RB_INIT(comment->author_ids);
112
+
113
+ return comment;
114
+
115
+ mem_error:
116
+ lxw_comment_free(comment);
117
+ return NULL;
118
+ }
119
+
120
+ /*
121
+ * Free a comment object.
122
+ */
123
+ void
124
+ lxw_comment_free(lxw_comment *comment)
125
+ {
126
+ struct lxw_author_id *author_id;
127
+ struct lxw_author_id *next_author_id;
128
+
129
+ if (!comment)
130
+ return;
131
+
132
+ if (comment->author_ids) {
133
+ for (author_id =
134
+ RB_MIN(lxw_author_ids, comment->author_ids);
135
+ author_id; author_id = next_author_id) {
136
+
137
+ next_author_id =
138
+ RB_NEXT(lxw_author_ids, worksheet->author_id, author_id);
139
+ RB_REMOVE(lxw_author_ids, comment->author_ids, author_id);
140
+ free(author_id->author);
141
+ free(author_id);
142
+ }
143
+
144
+ free(comment->author_ids);
145
+ }
146
+
147
+ free(comment);
148
+ }
149
+
150
+ /*****************************************************************************
151
+ *
152
+ * XML functions.
153
+ *
154
+ ****************************************************************************/
155
+
156
+ /*
157
+ * Write the XML declaration.
158
+ */
159
+ STATIC void
160
+ _comment_xml_declaration(lxw_comment *self)
161
+ {
162
+ lxw_xml_declaration(self->file);
163
+ }
164
+
165
+ /*****************************************************************************
166
+ *
167
+ * XML file assembly functions.
168
+ *
169
+ ****************************************************************************/
170
+
171
+ /*
172
+ * Write the <t> element.
173
+ */
174
+ STATIC void
175
+ _comment_write_text_t(lxw_comment *self, lxw_vml_obj *comment_obj)
176
+ {
177
+ lxw_xml_data_element(self->file, "t", comment_obj->text, NULL);
178
+ }
179
+
180
+ /*
181
+ * Write the <family> element.
182
+ */
183
+ STATIC void
184
+ _comment_write_family(lxw_comment *self, lxw_vml_obj *comment_obj)
185
+ {
186
+ struct xml_attribute_list attributes;
187
+ struct xml_attribute *attribute;
188
+
189
+ LXW_INIT_ATTRIBUTES();
190
+ LXW_PUSH_ATTRIBUTES_INT("val", comment_obj->font_family);
191
+
192
+ lxw_xml_empty_tag(self->file, "family", &attributes);
193
+
194
+ LXW_FREE_ATTRIBUTES();
195
+ }
196
+
197
+ /*
198
+ * Write the <rFont> element.
199
+ */
200
+ STATIC void
201
+ _comment_write_r_font(lxw_comment *self, lxw_vml_obj *comment_obj)
202
+ {
203
+ struct xml_attribute_list attributes;
204
+ struct xml_attribute *attribute;
205
+ char font_name[LXW_ATTR_32];
206
+
207
+ if (comment_obj->font_name)
208
+ lxw_snprintf(font_name, LXW_ATTR_32, "%s", comment_obj->font_name);
209
+ else
210
+ lxw_snprintf(font_name, LXW_ATTR_32, "Tahoma");
211
+
212
+ LXW_INIT_ATTRIBUTES();
213
+ LXW_PUSH_ATTRIBUTES_STR("val", font_name);
214
+
215
+ lxw_xml_empty_tag(self->file, "rFont", &attributes);
216
+
217
+ LXW_FREE_ATTRIBUTES();
218
+ }
219
+
220
+ /*
221
+ * Write the <color> element.
222
+ */
223
+ STATIC void
224
+ _comment_write_color(lxw_comment *self)
225
+ {
226
+ struct xml_attribute_list attributes;
227
+ struct xml_attribute *attribute;
228
+ char indexed[] = "81";
229
+
230
+ LXW_INIT_ATTRIBUTES();
231
+ LXW_PUSH_ATTRIBUTES_STR("indexed", indexed);
232
+
233
+ lxw_xml_empty_tag(self->file, "color", &attributes);
234
+
235
+ LXW_FREE_ATTRIBUTES();
236
+ }
237
+
238
+ /*
239
+ * Write the <sz> element.
240
+ */
241
+ STATIC void
242
+ _comment_write_sz(lxw_comment *self, lxw_vml_obj *comment_obj)
243
+ {
244
+ struct xml_attribute_list attributes;
245
+ struct xml_attribute *attribute;
246
+
247
+ LXW_INIT_ATTRIBUTES();
248
+ LXW_PUSH_ATTRIBUTES_DBL("val", comment_obj->font_size);
249
+
250
+ lxw_xml_empty_tag(self->file, "sz", &attributes);
251
+
252
+ LXW_FREE_ATTRIBUTES();
253
+ }
254
+
255
+ /*
256
+ * Write the <rPr> element.
257
+ */
258
+ STATIC void
259
+ _comment_write_r_pr(lxw_comment *self, lxw_vml_obj *comment_obj)
260
+ {
261
+ lxw_xml_start_tag(self->file, "rPr", NULL);
262
+
263
+ /* Write the sz element. */
264
+ _comment_write_sz(self, comment_obj);
265
+
266
+ /* Write the color element. */
267
+ _comment_write_color(self);
268
+
269
+ /* Write the rFont element. */
270
+ _comment_write_r_font(self, comment_obj);
271
+
272
+ /* Write the family element. */
273
+ _comment_write_family(self, comment_obj);
274
+
275
+ lxw_xml_end_tag(self->file, "rPr");
276
+ }
277
+
278
+ /*
279
+ * Write the <r> element.
280
+ */
281
+ STATIC void
282
+ _comment_write_r(lxw_comment *self, lxw_vml_obj *comment_obj)
283
+ {
284
+ lxw_xml_start_tag(self->file, "r", NULL);
285
+
286
+ /* Write the rPr element. */
287
+ _comment_write_r_pr(self, comment_obj);
288
+
289
+ /* Write the t element. */
290
+ _comment_write_text_t(self, comment_obj);
291
+
292
+ lxw_xml_end_tag(self->file, "r");
293
+ }
294
+
295
+ /*
296
+ * Write the <text> element.
297
+ */
298
+ STATIC void
299
+ _comment_write_text(lxw_comment *self, lxw_vml_obj *comment_obj)
300
+ {
301
+ lxw_xml_start_tag(self->file, "text", NULL);
302
+
303
+ /* Write the r element. */
304
+ _comment_write_r(self, comment_obj);
305
+
306
+ lxw_xml_end_tag(self->file, "text");
307
+ }
308
+
309
+ /*
310
+ * Write the <comment> element.
311
+ */
312
+ STATIC void
313
+ _comment_write_comment(lxw_comment *self, lxw_vml_obj *comment_obj)
314
+ {
315
+ struct xml_attribute_list attributes;
316
+ struct xml_attribute *attribute;
317
+ char ref[LXW_MAX_CELL_NAME_LENGTH];
318
+
319
+ lxw_rowcol_to_cell(ref, comment_obj->row, comment_obj->col);
320
+
321
+ LXW_INIT_ATTRIBUTES();
322
+ LXW_PUSH_ATTRIBUTES_STR("ref", ref);
323
+ LXW_PUSH_ATTRIBUTES_INT("authorId", comment_obj->author_id);
324
+
325
+ lxw_xml_start_tag(self->file, "comment", &attributes);
326
+
327
+ /* Write the text element. */
328
+ _comment_write_text(self, comment_obj);
329
+
330
+ lxw_xml_end_tag(self->file, "comment");
331
+
332
+ LXW_FREE_ATTRIBUTES();
333
+ }
334
+
335
+ /*
336
+ * Write the <commentList> element.
337
+ */
338
+ STATIC void
339
+ _comment_write_comment_list(lxw_comment *self)
340
+ {
341
+ lxw_vml_obj *comment_obj;
342
+
343
+ lxw_xml_start_tag(self->file, "commentList", NULL);
344
+
345
+ STAILQ_FOREACH(comment_obj, self->comment_objs, list_pointers) {
346
+ /* Write the comment element. */
347
+ _comment_write_comment(self, comment_obj);
348
+ }
349
+
350
+ lxw_xml_end_tag(self->file, "commentList");
351
+
352
+ }
353
+
354
+ /*
355
+ * Write the <author> element.
356
+ */
357
+ STATIC void
358
+ _comment_write_author(lxw_comment *self, char *author)
359
+ {
360
+ lxw_xml_data_element(self->file, "author", author, NULL);
361
+ }
362
+
363
+ /*
364
+ * Write the <authors> element.
365
+ */
366
+ STATIC void
367
+ _comment_write_authors(lxw_comment *self)
368
+ {
369
+ lxw_vml_obj *comment_obj;
370
+ char *author;
371
+
372
+ lxw_xml_start_tag(self->file, "authors", NULL);
373
+
374
+ /* Set the default author (from worksheet_set_comments_author()). */
375
+ if (self->comment_author) {
376
+ _get_author_index(self, self->comment_author);
377
+ _comment_write_author(self, self->comment_author);
378
+ }
379
+ else {
380
+ _get_author_index(self, "");
381
+ _comment_write_author(self, "");
382
+ }
383
+
384
+ STAILQ_FOREACH(comment_obj, self->comment_objs, list_pointers) {
385
+ author = comment_obj->author;
386
+
387
+ if (author) {
388
+
389
+ if (!_check_author(self, author))
390
+ _comment_write_author(self, author);
391
+
392
+ comment_obj->author_id = _get_author_index(self, author);
393
+ }
394
+ }
395
+
396
+ lxw_xml_end_tag(self->file, "authors");
397
+ }
398
+
399
+ /*
400
+ * Write the <comments> element.
401
+ */
402
+ STATIC void
403
+ _comment_write_comments(lxw_comment *self)
404
+ {
405
+ struct xml_attribute_list attributes;
406
+ struct xml_attribute *attribute;
407
+ char xmlns[] =
408
+ "http://schemas.openxmlformats.org/spreadsheetml/2006/main";
409
+
410
+ LXW_INIT_ATTRIBUTES();
411
+ LXW_PUSH_ATTRIBUTES_STR("xmlns", xmlns);
412
+
413
+ lxw_xml_start_tag(self->file, "comments", &attributes);
414
+
415
+ LXW_FREE_ATTRIBUTES();
416
+ }
417
+
418
+ /*
419
+ * Assemble and write the XML file.
420
+ */
421
+ void
422
+ lxw_comment_assemble_xml_file(lxw_comment *self)
423
+ {
424
+ /* Write the XML declaration. */
425
+ _comment_xml_declaration(self);
426
+
427
+ /* Write the comments element. */
428
+ _comment_write_comments(self);
429
+
430
+ /* Write the authors element. */
431
+ _comment_write_authors(self);
432
+
433
+ /* Write the commentList element. */
434
+ _comment_write_comment_list(self);
435
+
436
+ lxw_xml_end_tag(self->file, "comments");
437
+ }
438
+
439
+ /*****************************************************************************
440
+ *
441
+ * Public functions.
442
+ *
443
+ ****************************************************************************/
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Used in conjunction with the libxlsxwriter library.
5
5
  *
6
- * Copyright 2014-2019, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
6
+ * Copyright 2014-2020, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
7
7
  *
8
8
  */
9
9
 
@@ -322,6 +322,25 @@ lxw_ct_add_drawing_name(lxw_content_types *self, const char *name)
322
322
  lxw_ct_add_override(self, name, LXW_APP_DOCUMENT "drawing+xml");
323
323
  }
324
324
 
325
+ /*
326
+ * Add the name of a VML drawing to the ContentTypes overrides.
327
+ */
328
+ void
329
+ lxw_ct_add_vml_name(lxw_content_types *self)
330
+ {
331
+ lxw_ct_add_default(self, "vml", LXW_APP_DOCUMENT "vmlDrawing");
332
+ }
333
+
334
+ /*
335
+ * Add the name of a comment to the ContentTypes overrides.
336
+ */
337
+ void
338
+ lxw_ct_add_comment_name(lxw_content_types *self, const char *name)
339
+ {
340
+ lxw_ct_add_override(self, name,
341
+ LXW_APP_DOCUMENT "spreadsheetml.comments+xml");
342
+ }
343
+
325
344
  /*
326
345
  * Add the sharedStrings link to the ContentTypes overrides.
327
346
  */
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Used in conjunction with the libxlsxwriter library.
5
5
  *
6
- * Copyright 2014-2019, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
6
+ * Copyright 2014-2020, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
7
7
  *
8
8
  */
9
9
 
@@ -50,7 +50,7 @@ lxw_core_free(lxw_core *core)
50
50
  }
51
51
 
52
52
  /*
53
- * Convert a time_t struct to a ISO 8601 style "2010-01-01T00:00:00Z" date.
53
+ * Convert a time_t to a ISO 8601 style "2010-01-01T00:00:00Z" date.
54
54
  */
55
55
  static void
56
56
  _datetime_to_iso8601_date(time_t *timer, char *str, size_t size)
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Used in conjunction with the libxlsxwriter library.
5
5
  *
6
- * Copyright 2014-2019, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
6
+ * Copyright 2014-2020, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
7
7
  *
8
8
  */
9
9
 
@@ -3,13 +3,14 @@
3
3
  *
4
4
  * Used in conjunction with the libxlsxwriter library.
5
5
  *
6
- * Copyright 2014-2019, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
6
+ * Copyright 2014-2020, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
7
7
  *
8
8
  */
9
9
 
10
10
  #include "xlsxwriter/xmlwriter.h"
11
11
  #include "xlsxwriter/common.h"
12
12
  #include "xlsxwriter/drawing.h"
13
+ #include "xlsxwriter/worksheet.h"
13
14
  #include "xlsxwriter/utility.h"
14
15
 
15
16
  #define LXW_OBJ_NAME_LENGTH 14 /* "Picture 65536", or "Chart 65536" */
@@ -54,7 +55,6 @@ lxw_free_drawing_object(lxw_drawing_object *drawing_object)
54
55
  return;
55
56
 
56
57
  free(drawing_object->description);
57
- free(drawing_object->url);
58
58
  free(drawing_object->tip);
59
59
 
60
60
  free(drawing_object);
@@ -221,6 +221,32 @@ _drawing_write_to(lxw_drawing *self, lxw_drawing_coords *coords)
221
221
  lxw_xml_end_tag(self->file, "xdr:to");
222
222
  }
223
223
 
224
+ /*
225
+ * Write the <a:hlinkClick> element.
226
+ */
227
+ STATIC void
228
+ _drawing_write_a_hlink_click(lxw_drawing *self, uint32_t rel_index, char *tip)
229
+ {
230
+ struct xml_attribute_list attributes;
231
+ struct xml_attribute *attribute;
232
+ char xmlns_r[] = "http://schemas.openxmlformats.org/"
233
+ "officeDocument/2006/relationships";
234
+ char r_id[LXW_MAX_ATTRIBUTE_LENGTH];
235
+
236
+ lxw_snprintf(r_id, LXW_ATTR_32, "rId%d", rel_index);
237
+
238
+ LXW_INIT_ATTRIBUTES();
239
+ LXW_PUSH_ATTRIBUTES_STR("xmlns:r", xmlns_r);
240
+ LXW_PUSH_ATTRIBUTES_STR("r:id", r_id);
241
+
242
+ if (tip)
243
+ LXW_PUSH_ATTRIBUTES_STR("tooltip", tip);
244
+
245
+ lxw_xml_empty_tag(self->file, "a:hlinkClick", &attributes);
246
+
247
+ LXW_FREE_ATTRIBUTES();
248
+ }
249
+
224
250
  /*
225
251
  * Write the <xdr:cNvPr> element.
226
252
  */
@@ -239,10 +265,24 @@ _drawing_write_c_nv_pr(lxw_drawing *self, char *object_name, uint32_t index,
239
265
  LXW_PUSH_ATTRIBUTES_INT("id", index + 1);
240
266
  LXW_PUSH_ATTRIBUTES_STR("name", name);
241
267
 
242
- if (drawing_object && drawing_object->description)
268
+ if (drawing_object && drawing_object->description
269
+ && strlen(drawing_object->description)) {
243
270
  LXW_PUSH_ATTRIBUTES_STR("descr", drawing_object->description);
271
+ }
272
+
273
+ if (drawing_object && drawing_object->url_rel_index) {
274
+ lxw_xml_start_tag(self->file, "xdr:cNvPr", &attributes);
244
275
 
245
- lxw_xml_empty_tag(self->file, "xdr:cNvPr", &attributes);
276
+ /* Write the a:hlinkClick element. */
277
+ _drawing_write_a_hlink_click(self,
278
+ drawing_object->url_rel_index,
279
+ drawing_object->tip);
280
+
281
+ lxw_xml_end_tag(self->file, "xdr:cNvPr");
282
+ }
283
+ else {
284
+ lxw_xml_empty_tag(self->file, "xdr:cNvPr", &attributes);
285
+ }
246
286
 
247
287
  LXW_FREE_ATTRIBUTES();
248
288
  }
@@ -472,7 +512,7 @@ _drawing_write_pic(lxw_drawing *self, uint32_t index,
472
512
  _drawing_write_nv_pic_pr(self, index, drawing_object);
473
513
 
474
514
  /* Write the xdr:blipFill element. */
475
- _drawing_write_blip_fill(self, index);
515
+ _drawing_write_blip_fill(self, drawing_object->rel_index);
476
516
 
477
517
  /* Write the xdr:spPr element. */
478
518
  _drawing_write_sp_pr(self, drawing_object);
@@ -661,7 +701,8 @@ _drawing_write_a_graphic(lxw_drawing *self, uint32_t index)
661
701
  * Write the <xdr:graphicFrame> element.
662
702
  */
663
703
  STATIC void
664
- _drawing_write_graphic_frame(lxw_drawing *self, uint32_t index)
704
+ _drawing_write_graphic_frame(lxw_drawing *self, uint32_t index,
705
+ uint32_t rel_index)
665
706
  {
666
707
  struct xml_attribute_list attributes;
667
708
  struct xml_attribute *attribute;
@@ -678,7 +719,7 @@ _drawing_write_graphic_frame(lxw_drawing *self, uint32_t index)
678
719
  _drawing_write_xfrm(self);
679
720
 
680
721
  /* Write the a:graphic element. */
681
- _drawing_write_a_graphic(self, index);
722
+ _drawing_write_a_graphic(self, rel_index);
682
723
 
683
724
  lxw_xml_end_tag(self->file, "xdr:graphicFrame");
684
725
 
@@ -697,24 +738,21 @@ _drawing_write_two_cell_anchor(lxw_drawing *self, uint32_t index,
697
738
 
698
739
  LXW_INIT_ATTRIBUTES();
699
740
 
700
- if (drawing_object->anchor_type == LXW_ANCHOR_TYPE_IMAGE) {
701
-
702
- if (drawing_object->edit_as == LXW_ANCHOR_EDIT_AS_ABSOLUTE)
703
- LXW_PUSH_ATTRIBUTES_STR("editAs", "absolute");
704
- else if (drawing_object->edit_as != LXW_ANCHOR_EDIT_AS_RELATIVE)
705
- LXW_PUSH_ATTRIBUTES_STR("editAs", "oneCell");
706
- }
741
+ if (drawing_object->anchor == LXW_OBJECT_MOVE_DONT_SIZE)
742
+ LXW_PUSH_ATTRIBUTES_STR("editAs", "oneCell");
743
+ else if (drawing_object->anchor == LXW_OBJECT_DONT_MOVE_DONT_SIZE)
744
+ LXW_PUSH_ATTRIBUTES_STR("editAs", "absolute");
707
745
 
708
746
  lxw_xml_start_tag(self->file, "xdr:twoCellAnchor", &attributes);
709
747
 
710
748
  _drawing_write_from(self, &drawing_object->from);
711
749
  _drawing_write_to(self, &drawing_object->to);
712
750
 
713
- if (drawing_object->anchor_type == LXW_ANCHOR_TYPE_CHART) {
751
+ if (drawing_object->type == LXW_DRAWING_CHART) {
714
752
  /* Write the xdr:graphicFrame element for charts. */
715
- _drawing_write_graphic_frame(self, index);
753
+ _drawing_write_graphic_frame(self, index, drawing_object->rel_index);
716
754
  }
717
- else if (drawing_object->anchor_type == LXW_ANCHOR_TYPE_IMAGE) {
755
+ else if (drawing_object->type == LXW_DRAWING_IMAGE) {
718
756
  /* Write the xdr:pic element. */
719
757
  _drawing_write_pic(self, index, drawing_object);
720
758
  }
@@ -772,7 +810,7 @@ _drawing_write_pos(lxw_drawing *self, int32_t x, int32_t y)
772
810
  * Write the <xdr:absoluteAnchor> element.
773
811
  */
774
812
  STATIC void
775
- _drawing_write_absolute_anchor(lxw_drawing *self)
813
+ _drawing_write_absolute_anchor(lxw_drawing *self, uint32_t frame_index)
776
814
  {
777
815
  lxw_xml_start_tag(self->file, "xdr:absoluteAnchor", NULL);
778
816
 
@@ -791,7 +829,7 @@ _drawing_write_absolute_anchor(lxw_drawing *self)
791
829
  _drawing_write_ext(self, 6162675, 6124575);
792
830
  }
793
831
 
794
- _drawing_write_graphic_frame(self, 1);
832
+ _drawing_write_graphic_frame(self, frame_index, frame_index);
795
833
 
796
834
  /* Write the xdr:clientData element. */
797
835
  _drawing_write_client_data(self);
@@ -830,7 +868,7 @@ lxw_drawing_assemble_xml_file(lxw_drawing *self)
830
868
  }
831
869
  else {
832
870
  /* Write the xdr:absoluteAnchor element. Mainly for chartsheets. */
833
- _drawing_write_absolute_anchor(self);
871
+ _drawing_write_absolute_anchor(self, 1);
834
872
  }
835
873
 
836
874
  lxw_xml_end_tag(self->file, "xdr:wsDr");