Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/xlsxwriter/format.py: 49%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

359 statements  

1############################################################################### 

2# 

3# Format - A class for writing the Excel XLSX Worksheet file. 

4# 

5# SPDX-License-Identifier: BSD-2-Clause 

6# 

7# Copyright (c) 2013-2025, John McNamara, jmcnamara@cpan.org 

8# 

9 

10# Package imports. 

11from typing import Literal, Union 

12from warnings import warn 

13 

14from xlsxwriter import xmlwriter 

15from xlsxwriter.color import Color 

16 

17 

18class Format(xmlwriter.XMLwriter): 

19 """ 

20 A class for writing the Excel XLSX Format file. 

21 

22 

23 """ 

24 

25 ########################################################################### 

26 # 

27 # Public API. 

28 # 

29 ########################################################################### 

30 

31 def __init__(self, properties=None, xf_indices=None, dxf_indices=None) -> None: 

32 """ 

33 Constructor. 

34 

35 """ 

36 if properties is None: 

37 properties = {} 

38 

39 super().__init__() 

40 

41 self.xf_format_indices = xf_indices 

42 self.dxf_format_indices = dxf_indices 

43 self.xf_index = None 

44 self.dxf_index = None 

45 

46 self.num_format = "General" 

47 self.num_format_index = 0 

48 self.font_index = 0 

49 self.has_font = False 

50 self.has_dxf_font = False 

51 

52 self.bold = 0 

53 self.underline = 0 

54 self.italic = 0 

55 self.font_name = "Calibri" 

56 self.theme_font_name = "Calibri" 

57 self.font_size = 11 

58 self.font_color = None 

59 self.font_strikeout = 0 

60 self.font_outline = 0 

61 self.font_shadow = 0 

62 self.font_script = 0 

63 self.font_family = 2 

64 self.font_charset = 0 

65 self.font_scheme = "minor" 

66 self.font_condense = 0 

67 self.font_extend = 0 

68 self.theme = 0 

69 self.hyperlink = False 

70 self.xf_id = 0 

71 

72 self.hidden = 0 

73 self.locked = 1 

74 

75 self.text_h_align = 0 

76 self.text_wrap = 0 

77 self.text_v_align = 0 

78 self.text_justlast = 0 

79 self.rotation = 0 

80 

81 self.fg_color = None 

82 self.bg_color = None 

83 self.pattern = 0 

84 self.has_fill = False 

85 self.has_dxf_fill = False 

86 self.fill_index = 0 

87 self.fill_count = 0 

88 

89 self.border_index = 0 

90 self.has_border = False 

91 self.has_dxf_border = False 

92 self.border_count = 0 

93 

94 self.bottom = 0 

95 self.bottom_color = None 

96 self.diag_border = 0 

97 self.diag_color = None 

98 self.diag_type = 0 

99 self.left = 0 

100 self.left_color = None 

101 self.right = 0 

102 self.right_color = None 

103 self.top = 0 

104 self.top_color = None 

105 

106 self.indent = 0 

107 self.shrink = 0 

108 self.reading_order = 0 

109 self.just_distrib = 0 

110 self.color_indexed = 0 

111 self.font_only = 0 

112 

113 self.quote_prefix = False 

114 self.checkbox = False 

115 

116 # Set the property first. 

117 if properties.get("theme_font_name"): 

118 self.theme_font_name = properties["theme_font_name"] 

119 

120 # Convert properties in the constructor to method calls. 

121 for key, value in properties.items(): 

122 getattr(self, "set_" + key)(value) 

123 

124 self._format_key = None 

125 

126 def __repr__(self) -> str: 

127 """ 

128 Return a string representation of the Format instance. 

129 """ 

130 return ( 

131 f"Format(" 

132 f"font_name={self.font_name!r}, " 

133 f"font_size={self.font_size}, " 

134 f"bold={self.bold}, " 

135 f"italic={self.italic}, " 

136 f"underline={self.underline}, " 

137 f"font_color={self.font_color}, " 

138 f"num_format={self.num_format!r}, " 

139 f"text_h_align={self.text_h_align}, " 

140 f"text_v_align={self.text_v_align}, " 

141 f"fg_color={self.fg_color}, " 

142 f"bg_color={self.bg_color}, " 

143 f"pattern={self.pattern}, " 

144 f"locked={self.locked}, " 

145 f"hidden={self.hidden})" 

146 ) 

147 

148 ########################################################################### 

149 # 

150 # Format properties. 

151 # 

152 ########################################################################### 

153 

154 def set_font_name(self, font_name) -> None: 

155 """ 

156 Set the Format font_name property such as 'Time New Roman'. The 

157 default Excel font is 'Calibri'. 

158 

159 Args: 

160 font_name: String with the font name. No default. 

161 

162 Returns: 

163 Nothing. 

164 

165 """ 

166 self.font_name = font_name 

167 

168 if font_name != self.theme_font_name: 

169 self.font_scheme = "none" 

170 

171 def set_font_size(self, font_size: int = 11) -> None: 

172 """ 

173 Set the Format font_size property. The default Excel font size is 11. 

174 

175 Args: 

176 font_size: Int with font size. No default. 

177 

178 Returns: 

179 Nothing. 

180 

181 """ 

182 self.font_size = font_size 

183 

184 def set_font_color(self, font_color: Union[str, Color]) -> None: 

185 """ 

186 Set the Format font_color property. The Excel default is black. 

187 

188 Args: 

189 font_color: String with the font color. No default. 

190 

191 Returns: 

192 Nothing. 

193 

194 """ 

195 self.font_color = Color._from_value(font_color) 

196 

197 def set_bold(self, bold: bool = True) -> None: 

198 """ 

199 Set the Format bold property. 

200 

201 Args: 

202 bold: Default is True, turns property on. 

203 

204 Returns: 

205 Nothing. 

206 

207 """ 

208 self.bold = bold 

209 

210 def set_italic(self, italic: bool = True) -> None: 

211 """ 

212 Set the Format italic property. 

213 

214 Args: 

215 italic: Default is True, turns property on. 

216 

217 Returns: 

218 Nothing. 

219 

220 """ 

221 self.italic = italic 

222 

223 def set_underline(self, underline: Literal[1, 2, 33, 34] = 1) -> None: 

224 """ 

225 Set the Format underline property. 

226 

227 Args: 

228 underline: Default is 1, single underline. 

229 

230 Returns: 

231 Nothing. 

232 

233 """ 

234 self.underline = underline 

235 

236 def set_font_strikeout(self, font_strikeout: bool = True) -> None: 

237 """ 

238 Set the Format font_strikeout property. 

239 

240 Args: 

241 font_strikeout: Default is True, turns property on. 

242 

243 Returns: 

244 Nothing. 

245 

246 """ 

247 self.font_strikeout = font_strikeout 

248 

249 def set_font_script(self, font_script: Literal[1, 2] = 1) -> None: 

250 """ 

251 Set the Format font_script property. 

252 

253 Args: 

254 font_script: Default is 1, superscript. 

255 

256 Returns: 

257 Nothing. 

258 

259 """ 

260 self.font_script = font_script 

261 

262 def set_font_outline(self, font_outline: bool = True) -> None: 

263 """ 

264 Set the Format font_outline property. 

265 

266 Args: 

267 font_outline: Default is True, turns property on. 

268 

269 Returns: 

270 Nothing. 

271 

272 """ 

273 self.font_outline = font_outline 

274 

275 def set_font_shadow(self, font_shadow: bool = True) -> None: 

276 """ 

277 Set the Format font_shadow property. 

278 

279 Args: 

280 font_shadow: Default is True, turns property on. 

281 

282 Returns: 

283 Nothing. 

284 

285 """ 

286 self.font_shadow = font_shadow 

287 

288 def set_num_format(self, num_format: str) -> None: 

289 """ 

290 Set the Format num_format property such as '#,##0'. 

291 

292 Args: 

293 num_format: String representing the number format. No default. 

294 

295 Returns: 

296 Nothing. 

297 

298 """ 

299 self.num_format = num_format 

300 

301 def set_locked(self, locked: bool = True) -> None: 

302 """ 

303 Set the Format locked property. 

304 

305 Args: 

306 locked: Default is True, turns property on. 

307 

308 Returns: 

309 Nothing. 

310 

311 """ 

312 self.locked = locked 

313 

314 def set_hidden(self, hidden: bool = True) -> None: 

315 """ 

316 Set the Format hidden property. 

317 

318 Args: 

319 hidden: Default is True, turns property on. 

320 

321 Returns: 

322 Nothing. 

323 

324 """ 

325 self.hidden = hidden 

326 

327 def set_align( 

328 self, 

329 alignment: Literal[ 

330 "left", 

331 "centre", 

332 "center", 

333 "right", 

334 "fill", 

335 "justify", 

336 "center_across", 

337 "centre_across", 

338 "distributed", 

339 "justify_distributed", 

340 "justify_distributed", 

341 "top", 

342 "vcentre", 

343 "vcenter", 

344 "bottom", 

345 "vjustify", 

346 "vdistributed", 

347 ], 

348 ) -> None: 

349 """ 

350 Set the Format cell alignment. 

351 

352 Args: 

353 alignment: String representing alignment. No default. 

354 

355 Returns: 

356 Nothing. 

357 """ 

358 alignment = alignment.lower() 

359 

360 # Set horizontal alignment properties. 

361 if alignment == "left": 

362 self.set_text_h_align(1) 

363 if alignment == "centre": 

364 self.set_text_h_align(2) 

365 if alignment == "center": 

366 self.set_text_h_align(2) 

367 if alignment == "right": 

368 self.set_text_h_align(3) 

369 if alignment == "fill": 

370 self.set_text_h_align(4) 

371 if alignment == "justify": 

372 self.set_text_h_align(5) 

373 if alignment == "center_across": 

374 self.set_text_h_align(6) 

375 if alignment == "centre_across": 

376 self.set_text_h_align(6) 

377 if alignment == "distributed": 

378 self.set_text_h_align(7) 

379 if alignment == "justify_distributed": 

380 self.set_text_h_align(7) 

381 

382 if alignment == "justify_distributed": 

383 self.just_distrib = 1 

384 

385 # Set vertical alignment properties. 

386 if alignment == "top": 

387 self.set_text_v_align(1) 

388 if alignment == "vcentre": 

389 self.set_text_v_align(2) 

390 if alignment == "vcenter": 

391 self.set_text_v_align(2) 

392 if alignment == "bottom": 

393 self.set_text_v_align(3) 

394 if alignment == "vjustify": 

395 self.set_text_v_align(4) 

396 if alignment == "vdistributed": 

397 self.set_text_v_align(5) 

398 

399 def set_center_across(self, align_type: None = None) -> None: 

400 # pylint: disable=unused-argument 

401 """ 

402 Set the Format center_across property. 

403 

404 Returns: 

405 Nothing. 

406 

407 """ 

408 self.set_text_h_align(6) 

409 

410 def set_text_wrap(self, text_wrap: bool = True) -> None: 

411 """ 

412 Set the Format text_wrap property. 

413 

414 Args: 

415 text_wrap: Default is True, turns property on. 

416 

417 Returns: 

418 Nothing. 

419 

420 """ 

421 self.text_wrap = text_wrap 

422 

423 def set_rotation(self, rotation: int) -> None: 

424 """ 

425 Set the Format rotation property. 

426 

427 Args: 

428 rotation: Rotation angle. No default. 

429 

430 Returns: 

431 Nothing. 

432 

433 """ 

434 rotation = int(rotation) 

435 

436 # Map user angle to Excel angle. 

437 if rotation == 270: 

438 rotation = 255 

439 elif -90 <= rotation <= 90: 

440 if rotation < 0: 

441 rotation = -rotation + 90 

442 else: 

443 warn("Rotation rotation outside range: -90 <= angle <= 90") 

444 return 

445 

446 self.rotation = rotation 

447 

448 def set_indent(self, indent: int = 1) -> None: 

449 """ 

450 Set the Format indent property. 

451 

452 Args: 

453 indent: Default is 1, first indentation level. 

454 

455 Returns: 

456 Nothing. 

457 

458 """ 

459 self.indent = indent 

460 

461 def set_shrink(self, shrink: bool = True) -> None: 

462 """ 

463 Set the Format shrink property. 

464 

465 Args: 

466 shrink: Default is True, turns property on. 

467 

468 Returns: 

469 Nothing. 

470 

471 """ 

472 self.shrink = shrink 

473 

474 def set_text_justlast(self, text_justlast: bool = True) -> None: 

475 """ 

476 Set the Format text_justlast property. 

477 

478 Args: 

479 text_justlast: Default is True, turns property on. 

480 

481 Returns: 

482 Nothing. 

483 

484 """ 

485 self.text_justlast = text_justlast 

486 

487 def set_pattern(self, pattern: int = 1) -> None: 

488 """ 

489 Set the Format pattern property. 

490 

491 Args: 

492 pattern: Default is 1, solid fill. 

493 

494 Returns: 

495 Nothing. 

496 

497 """ 

498 self.pattern = pattern 

499 

500 def set_bg_color(self, bg_color: Union[str, Color]) -> None: 

501 """ 

502 Set the Format bg_color property. 

503 

504 Args: 

505 bg_color: Background color. No default. 

506 

507 Returns: 

508 Nothing. 

509 

510 """ 

511 self.bg_color = Color._from_value(bg_color) 

512 

513 def set_fg_color(self, fg_color: Union[str, Color]) -> None: 

514 """ 

515 Set the Format fg_color property. 

516 

517 Args: 

518 fg_color: Foreground color. No default. 

519 

520 Returns: 

521 Nothing. 

522 

523 """ 

524 self.fg_color = Color._from_value(fg_color) 

525 

526 # set_border(style) Set cells borders to the same style 

527 def set_border(self, style: int = 1) -> None: 

528 """ 

529 Set the Format bottom property. 

530 

531 Args: 

532 bottom: Default is 1, border type 1. 

533 

534 Returns: 

535 Nothing. 

536 

537 """ 

538 self.set_bottom(style) 

539 self.set_top(style) 

540 self.set_left(style) 

541 self.set_right(style) 

542 

543 # set_border_color(color) Set cells border to the same color 

544 def set_border_color(self, color: Union[str, Color]) -> None: 

545 """ 

546 Set the Format bottom property. 

547 

548 Args: 

549 color: Color string. No default. 

550 

551 Returns: 

552 Nothing. 

553 

554 """ 

555 self.set_bottom_color(color) 

556 self.set_top_color(color) 

557 self.set_left_color(color) 

558 self.set_right_color(color) 

559 

560 def set_bottom(self, bottom: int = 1) -> None: 

561 """ 

562 Set the Format bottom property. 

563 

564 Args: 

565 bottom: Default is 1, border type 1. 

566 

567 Returns: 

568 Nothing. 

569 

570 """ 

571 self.bottom = bottom 

572 

573 def set_bottom_color(self, bottom_color: Union[str, Color]) -> None: 

574 """ 

575 Set the Format bottom_color property. 

576 

577 Args: 

578 bottom_color: Color string. No default. 

579 

580 Returns: 

581 Nothing. 

582 

583 """ 

584 self.bottom_color = Color._from_value(bottom_color) 

585 

586 def set_diag_type(self, diag_type: Literal[1, 2, 3] = 1) -> None: 

587 """ 

588 Set the Format diag_type property. 

589 

590 Args: 

591 diag_type: Default is 1, border type 1. 

592 

593 Returns: 

594 Nothing. 

595 

596 """ 

597 self.diag_type = diag_type 

598 

599 def set_left(self, left: int = 1) -> None: 

600 """ 

601 Set the Format left property. 

602 

603 Args: 

604 left: Default is 1, border type 1. 

605 

606 Returns: 

607 Nothing. 

608 

609 """ 

610 self.left = left 

611 

612 def set_left_color(self, left_color: Union[str, Color]) -> None: 

613 """ 

614 Set the Format left_color property. 

615 

616 Args: 

617 left_color: Color string. No default. 

618 

619 Returns: 

620 Nothing. 

621 

622 """ 

623 self.left_color = Color._from_value(left_color) 

624 

625 def set_right(self, right: int = 1) -> None: 

626 """ 

627 Set the Format right property. 

628 

629 Args: 

630 right: Default is 1, border type 1. 

631 

632 Returns: 

633 Nothing. 

634 

635 """ 

636 self.right = right 

637 

638 def set_right_color(self, right_color: Union[str, Color]) -> None: 

639 """ 

640 Set the Format right_color property. 

641 

642 Args: 

643 right_color: Color string. No default. 

644 

645 Returns: 

646 Nothing. 

647 

648 """ 

649 self.right_color = Color._from_value(right_color) 

650 

651 def set_top(self, top: int = 1) -> None: 

652 """ 

653 Set the Format top property. 

654 

655 Args: 

656 top: Default is 1, border type 1. 

657 

658 Returns: 

659 Nothing. 

660 

661 """ 

662 self.top = top 

663 

664 def set_top_color(self, top_color: Union[str, Color]) -> None: 

665 """ 

666 Set the Format top_color property. 

667 

668 Args: 

669 top_color: Color string. No default. 

670 

671 Returns: 

672 Nothing. 

673 

674 """ 

675 self.top_color = Color._from_value(top_color) 

676 

677 def set_diag_color(self, diag_color: Union[str, Color]) -> None: 

678 """ 

679 Set the Format diag_color property. 

680 

681 Args: 

682 diag_color: Color string. No default. 

683 

684 Returns: 

685 Nothing. 

686 

687 """ 

688 self.diag_color = Color._from_value(diag_color) 

689 

690 def set_diag_border(self, diag_border: int = 1) -> None: 

691 """ 

692 Set the Format diag_border property. 

693 

694 Args: 

695 diag_border: Default is 1, border type 1. 

696 

697 Returns: 

698 Nothing. 

699 

700 """ 

701 self.diag_border = diag_border 

702 

703 def set_quote_prefix(self, quote_prefix: bool = True) -> None: 

704 """ 

705 Set the Format quote prefix property. 

706 

707 Args: 

708 quote_prefix: Default is True, turns property on. 

709 

710 Returns: 

711 Nothing. 

712 

713 """ 

714 self.quote_prefix = quote_prefix 

715 

716 def set_checkbox(self, checkbox: bool = True) -> None: 

717 """ 

718 Set the Format property to show a checkbox in a cell. 

719 

720 This format property can be used with a cell that contains a boolean 

721 value to display it as a checkbox. This property isn't required very 

722 often and it is generally easier to create a checkbox using the 

723 ``worksheet.insert_checkbox()`` method. 

724 

725 Args: 

726 checkbox: Default is True, turns property on. 

727 

728 Returns: 

729 Nothing. 

730 

731 """ 

732 self.checkbox = checkbox 

733 

734 ########################################################################### 

735 # 

736 # Internal Format properties. These aren't documented since they are 

737 # either only used internally or else are unlikely to be set by the user. 

738 # 

739 ########################################################################### 

740 

741 def set_has_font(self, has_font: bool = True) -> None: 

742 """ 

743 Set the property to indicate the format has a font. 

744 

745 Args: 

746 has_font: Default is True, turns property on. 

747 

748 Returns: 

749 Nothing. 

750 

751 """ 

752 self.has_font = has_font 

753 

754 def set_has_fill(self, has_fill: bool = True) -> None: 

755 """ 

756 Set the property to indicate the format has a fill. 

757 

758 Args: 

759 has_fill: Default is True, turns property on. 

760 

761 Returns: 

762 Nothing. 

763 

764 """ 

765 self.has_fill = has_fill 

766 

767 def set_font_index(self, font_index: int) -> None: 

768 """ 

769 Set the unique font index property. 

770 

771 Args: 

772 font_index: The unique font index. 

773 

774 Returns: 

775 Nothing. 

776 

777 """ 

778 self.font_index = font_index 

779 

780 def set_xf_index(self, xf_index: int) -> None: 

781 """ 

782 Set the unique format index property. 

783 

784 Args: 

785 xf_index: The unique Excel format index. 

786 

787 Returns: 

788 Nothing. 

789 

790 """ 

791 self.xf_index = xf_index 

792 

793 def set_dxf_index(self, dxf_index: int) -> None: 

794 """ 

795 Set the unique conditional format index property. 

796 

797 Args: 

798 dxf_index: The unique Excel conditional format index. 

799 

800 Returns: 

801 Nothing. 

802 

803 """ 

804 self.dxf_index = dxf_index 

805 

806 def set_num_format_index(self, num_format_index: int) -> None: 

807 """ 

808 Set the number format_index property. 

809 

810 Args: 

811 num_format_index: The unique number format index. 

812 

813 Returns: 

814 Nothing. 

815 

816 """ 

817 self.num_format_index = num_format_index 

818 

819 def set_text_h_align(self, text_h_align: int) -> None: 

820 """ 

821 Set the horizontal text alignment property. 

822 

823 Args: 

824 text_h_align: Horizontal text alignment. 

825 

826 Returns: 

827 Nothing. 

828 

829 """ 

830 self.text_h_align = text_h_align 

831 

832 def set_text_v_align(self, text_v_align: int) -> None: 

833 """ 

834 Set the vertical text alignment property. 

835 

836 Args: 

837 text_h_align: Vertical text alignment. 

838 

839 Returns: 

840 Nothing. 

841 

842 """ 

843 self.text_v_align = text_v_align 

844 

845 def set_reading_order(self, direction: int = 0) -> None: 

846 # Set the reading_order property. 

847 """ 

848 Set the reading order property. 

849 

850 Args: 

851 direction: Default is 0, left to right. 

852 

853 Returns: 

854 Nothing. 

855 

856 """ 

857 self.reading_order = direction 

858 

859 def set_valign( 

860 self, 

861 align: Literal[ 

862 "left", 

863 "centre", 

864 "center", 

865 "right", 

866 "fill", 

867 "justify", 

868 "center_across", 

869 "centre_across", 

870 "distributed", 

871 "justify_distributed", 

872 "justify_distributed", 

873 "top", 

874 "vcentre", 

875 "vcenter", 

876 "bottom", 

877 "vjustify", 

878 "vdistributed", 

879 ], 

880 ) -> None: 

881 # Set vertical cell alignment. This is required by the constructor 

882 # properties dict to differentiate between the vertical and horizontal 

883 # properties. 

884 """ 

885 Set vertical cell alignment property. 

886 

887 This is required by the constructor properties dict to differentiate 

888 between the vertical and horizontal properties. 

889 

890 Args: 

891 align: Alignment property. 

892 

893 Returns: 

894 Nothing. 

895 

896 """ 

897 self.set_align(align) 

898 

899 def set_font_family(self, font_family: int) -> None: 

900 """ 

901 Set the font family property. 

902 

903 Args: 

904 font_family: Font family number. 

905 

906 Returns: 

907 Nothing. 

908 

909 """ 

910 self.font_family = font_family 

911 

912 def set_font_charset(self, font_charset: int) -> None: 

913 """ 

914 Set the font character set property. 

915 

916 Args: 

917 font_charset: The font character set number. 

918 

919 Returns: 

920 Nothing. 

921 

922 """ 

923 self.font_charset = font_charset 

924 

925 def set_font_scheme(self, font_scheme: str) -> None: 

926 """ 

927 Set the font scheme property to indicate if the font is tied to the 

928 workbook theme 

929 

930 This method can be used to indicate that a font is part of a theme. The 

931 theme must also contain the appropriate font for this to work. 

932 

933 This method can also be used to indicate that a font is not part of a 

934 theme, for example, if you wished to use a "Calibri" font that is not 

935 connected to the theme and which will not change if the theme is 

936 changed. 

937 

938 

939 The allowed values are: 

940 

941 - "minor": This is used to indicate a theme font that is used for body 

942 text. 

943 - "major": This is used to indicate a theme font that is used for 

944 headings. 

945 - "none": This is used to indicate a font that is not part of the theme. 

946 

947 Args: 

948 font_scheme: The font scheme. 

949 

950 Returns: 

951 Nothing. 

952 

953 """ 

954 self.font_scheme = font_scheme 

955 

956 def set_font_condense(self, font_condense: int) -> None: 

957 """ 

958 Set the font condense property. 

959 

960 Args: 

961 font_condense: The font condense property. 

962 

963 Returns: 

964 Nothing. 

965 

966 """ 

967 self.font_condense = font_condense 

968 

969 def set_font_extend(self, font_extend: int) -> None: 

970 """ 

971 Set the font extend property. 

972 

973 Args: 

974 font_extend: The font extend property. 

975 

976 Returns: 

977 Nothing. 

978 

979 """ 

980 self.font_extend = font_extend 

981 

982 def set_theme(self, theme: int) -> None: 

983 """ 

984 Set the theme property. 

985 

986 Args: 

987 theme: Format theme. 

988 

989 Returns: 

990 Nothing. 

991 

992 """ 

993 self.theme = theme 

994 

995 def set_hyperlink(self, hyperlink: bool = True) -> None: 

996 """ 

997 Set the properties for the hyperlink style. 

998 

999 Args: 

1000 hyperlink: Default is True, turns property on. 

1001 

1002 Returns: 

1003 Nothing. 

1004 

1005 """ 

1006 self.xf_id = 1 

1007 self.set_underline(1) 

1008 self.set_theme(10) 

1009 self.hyperlink = hyperlink 

1010 self.font_scheme = "none" 

1011 

1012 def set_color_indexed(self, color_index: Literal[0, 1]) -> None: 

1013 """ 

1014 Set the color index property. Some fundamental format properties use an 

1015 indexed color instead of a rbg or theme color. 

1016 

1017 Args: 

1018 color_index: Generally 0 or 1. 

1019 

1020 Returns: 

1021 Nothing. 

1022 

1023 """ 

1024 self.color_indexed = color_index 

1025 

1026 def set_font_only(self, font_only: bool = True) -> None: 

1027 """ 

1028 Set property to indicate that the format is used for fonts only. 

1029 

1030 Args: 

1031 font_only: Default is True, turns property on. 

1032 

1033 Returns: 

1034 Nothing. 

1035 

1036 """ 

1037 self.font_only = font_only 

1038 

1039 def set_theme_font_name(self, font_name) -> None: 

1040 """ 

1041 Set the Format font name use for the theme. 

1042 

1043 Args: 

1044 font_name: String with the font name. No default. 

1045 

1046 Returns: 

1047 Nothing. 

1048 

1049 """ 

1050 self.theme_font_name = font_name 

1051 

1052 # Compatibility methods. These versions of the method names were added in an 

1053 # initial version for compatibility testing with Excel::Writer::XLSX and 

1054 # leaked out into production code. They are deprecated and will be removed 

1055 # in a future after a suitable deprecation period. 

1056 def set_font(self, font_name: str) -> None: 

1057 """Deprecated: Use set_font_name() instead.""" 

1058 self.set_font_name(font_name) 

1059 

1060 def set_size(self, font_size: int) -> None: 

1061 """Deprecated: Use set_font_size() instead.""" 

1062 self.set_font_size(font_size) 

1063 

1064 def set_color(self, font_color: Union[Color, str]) -> None: 

1065 """Deprecated: Use set_font_color() instead.""" 

1066 self.set_font_color(font_color) 

1067 

1068 ########################################################################### 

1069 # 

1070 # Private API. 

1071 # 

1072 ########################################################################### 

1073 

1074 def _get_align_properties(self): 

1075 # pylint: disable=too-many-boolean-expressions 

1076 # Return properties for an Style xf <alignment> sub-element. 

1077 changed = 0 

1078 align = [] 

1079 

1080 # Check if any alignment options in the format have been changed. 

1081 if ( 

1082 self.text_h_align 

1083 or self.text_v_align 

1084 or self.indent 

1085 or self.rotation 

1086 or self.text_wrap 

1087 or self.shrink 

1088 or self.reading_order 

1089 ): 

1090 changed = 1 

1091 else: 

1092 return changed, align 

1093 

1094 # Indent is only allowed for some alignment properties. If it is 

1095 # defined for any other alignment or no alignment has been set then 

1096 # default to left alignment. 

1097 if ( 

1098 self.indent 

1099 and self.text_h_align != 1 

1100 and self.text_h_align != 3 

1101 and self.text_h_align != 7 

1102 and self.text_v_align != 1 

1103 and self.text_v_align != 3 

1104 and self.text_v_align != 5 

1105 ): 

1106 self.text_h_align = 1 

1107 

1108 # Check for properties that are mutually exclusive. 

1109 if self.text_wrap: 

1110 self.shrink = 0 

1111 if self.text_h_align == 4: 

1112 self.shrink = 0 

1113 if self.text_h_align == 5: 

1114 self.shrink = 0 

1115 if self.text_h_align == 7: 

1116 self.shrink = 0 

1117 if self.text_h_align != 7: 

1118 self.just_distrib = 0 

1119 if self.indent: 

1120 self.just_distrib = 0 

1121 

1122 continuous = "centerContinuous" 

1123 

1124 if self.text_h_align == 1: 

1125 align.append(("horizontal", "left")) 

1126 if self.text_h_align == 2: 

1127 align.append(("horizontal", "center")) 

1128 if self.text_h_align == 3: 

1129 align.append(("horizontal", "right")) 

1130 if self.text_h_align == 4: 

1131 align.append(("horizontal", "fill")) 

1132 if self.text_h_align == 5: 

1133 align.append(("horizontal", "justify")) 

1134 if self.text_h_align == 6: 

1135 align.append(("horizontal", continuous)) 

1136 if self.text_h_align == 7: 

1137 align.append(("horizontal", "distributed")) 

1138 

1139 if self.just_distrib: 

1140 align.append(("justifyLastLine", 1)) 

1141 

1142 # Property 'vertical' => 'bottom' is a default. It sets applyAlignment 

1143 # without an alignment sub-element. 

1144 if self.text_v_align == 1: 

1145 align.append(("vertical", "top")) 

1146 if self.text_v_align == 2: 

1147 align.append(("vertical", "center")) 

1148 if self.text_v_align == 4: 

1149 align.append(("vertical", "justify")) 

1150 if self.text_v_align == 5: 

1151 align.append(("vertical", "distributed")) 

1152 

1153 if self.rotation: 

1154 align.append(("textRotation", self.rotation)) 

1155 if self.indent: 

1156 align.append(("indent", self.indent)) 

1157 

1158 if self.text_wrap: 

1159 align.append(("wrapText", 1)) 

1160 if self.shrink: 

1161 align.append(("shrinkToFit", 1)) 

1162 

1163 if self.reading_order == 1: 

1164 align.append(("readingOrder", 1)) 

1165 if self.reading_order == 2: 

1166 align.append(("readingOrder", 2)) 

1167 

1168 return changed, align 

1169 

1170 def _get_protection_properties(self): 

1171 # Return properties for an Excel XML <Protection> element. 

1172 attributes = [] 

1173 

1174 if not self.locked: 

1175 attributes.append(("locked", 0)) 

1176 if self.hidden: 

1177 attributes.append(("hidden", 1)) 

1178 

1179 return attributes 

1180 

1181 def _get_format_key(self): 

1182 # Returns a unique hash key for a format. Used by Workbook. 

1183 if self._format_key is None: 

1184 self._format_key = ":".join( 

1185 str(x) 

1186 for x in ( 

1187 self._get_font_key(), 

1188 self._get_border_key(), 

1189 self._get_fill_key(), 

1190 self._get_alignment_key(), 

1191 self.num_format, 

1192 self.locked, 

1193 self.checkbox, 

1194 self.quote_prefix, 

1195 self.hidden, 

1196 ) 

1197 ) 

1198 

1199 return self._format_key 

1200 

1201 def _get_font_key(self): 

1202 # Returns a unique hash key for a font. Used by Workbook. 

1203 key = ":".join( 

1204 str(x) 

1205 for x in ( 

1206 self.bold, 

1207 self.font_color, 

1208 self.font_charset, 

1209 self.font_family, 

1210 self.font_outline, 

1211 self.font_script, 

1212 self.font_shadow, 

1213 self.font_strikeout, 

1214 self.font_name, 

1215 self.italic, 

1216 self.font_size, 

1217 self.underline, 

1218 self.theme, 

1219 ) 

1220 ) 

1221 

1222 return key 

1223 

1224 def _get_border_key(self): 

1225 # Returns a unique hash key for a border style. Used by Workbook. 

1226 key = ":".join( 

1227 str(x) 

1228 for x in ( 

1229 self.bottom, 

1230 self.bottom_color, 

1231 self.diag_border, 

1232 self.diag_color, 

1233 self.diag_type, 

1234 self.left, 

1235 self.left_color, 

1236 self.right, 

1237 self.right_color, 

1238 self.top, 

1239 self.top_color, 

1240 ) 

1241 ) 

1242 

1243 return key 

1244 

1245 def _get_fill_key(self): 

1246 # Returns a unique hash key for a fill style. Used by Workbook. 

1247 key = ":".join(str(x) for x in (self.pattern, self.bg_color, self.fg_color)) 

1248 

1249 return key 

1250 

1251 def _get_alignment_key(self): 

1252 # Returns a unique hash key for alignment formats. 

1253 

1254 key = ":".join( 

1255 str(x) 

1256 for x in ( 

1257 self.text_h_align, 

1258 self.text_v_align, 

1259 self.indent, 

1260 self.rotation, 

1261 self.text_wrap, 

1262 self.shrink, 

1263 self.reading_order, 

1264 ) 

1265 ) 

1266 

1267 return key 

1268 

1269 def _get_xf_index(self): 

1270 # Returns the XF index number used by Excel to identify a format. 

1271 if self.xf_index is not None: 

1272 # Format already has an index number so return it. 

1273 return self.xf_index 

1274 

1275 # Format doesn't have an index number so assign one. 

1276 key = self._get_format_key() 

1277 

1278 if key in self.xf_format_indices: 

1279 # Format matches existing format with an index. 

1280 return self.xf_format_indices[key] 

1281 

1282 # New format requiring an index. Note. +1 since Excel 

1283 # has an implicit "General" format at index 0. 

1284 index = 1 + len(self.xf_format_indices) 

1285 self.xf_format_indices[key] = index 

1286 self.xf_index = index 

1287 return index 

1288 

1289 def _get_dxf_index(self): 

1290 # Returns the DXF index number used by Excel to identify a format. 

1291 if self.dxf_index is not None: 

1292 # Format already has an index number so return it. 

1293 return self.dxf_index 

1294 

1295 # Format doesn't have an index number so assign one. 

1296 key = self._get_format_key() 

1297 

1298 if key in self.dxf_format_indices: 

1299 # Format matches existing format with an index. 

1300 return self.dxf_format_indices[key] 

1301 

1302 # New format requiring an index. 

1303 index = len(self.dxf_format_indices) 

1304 self.dxf_format_indices[key] = index 

1305 self.dxf_index = index 

1306 return index 

1307 

1308 ########################################################################### 

1309 # 

1310 # XML methods. 

1311 # 

1312 ###########################################################################