Add a simple EMarkdownEditor widget

Related to https://gitlab.gnome.org/GNOME/evolution/-/issues/449
This commit is contained in:
Milan Crha
2022-01-25 18:31:27 +01:00
parent 4c81b6dfee
commit 4c25b2ebde
27 changed files with 1241 additions and 0 deletions

View File

@ -92,6 +92,24 @@ set(private_icons
hicolor_actions_32x32_view-calendar-month.png hicolor_actions_32x32_view-calendar-month.png
hicolor_actions_32x32_view-calendar-week.png hicolor_actions_32x32_view-calendar-week.png
hicolor_actions_32x32_view-calendar-workweek.png hicolor_actions_32x32_view-calendar-workweek.png
hicolor_actions_scalable_markdown-bold.svg
hicolor_actions_scalable_markdown-bold-dark.svg
hicolor_actions_scalable_markdown-bullets.svg
hicolor_actions_scalable_markdown-bullets-dark.svg
hicolor_actions_scalable_markdown-code.svg
hicolor_actions_scalable_markdown-code-dark.svg
hicolor_actions_scalable_markdown-header.svg
hicolor_actions_scalable_markdown-header-dark.svg
hicolor_actions_scalable_markdown-help.svg
hicolor_actions_scalable_markdown-help-dark.svg
hicolor_actions_scalable_markdown-italic.svg
hicolor_actions_scalable_markdown-italic-dark.svg
hicolor_actions_scalable_markdown-link.svg
hicolor_actions_scalable_markdown-link-dark.svg
hicolor_actions_scalable_markdown-numbers.svg
hicolor_actions_scalable_markdown-numbers-dark.svg
hicolor_actions_scalable_markdown-quote.svg
hicolor_actions_scalable_markdown-quote-dark.svg
hicolor_actions_scalable_view-calendar-day.svg hicolor_actions_scalable_view-calendar-day.svg
hicolor_actions_scalable_view-calendar-list.svg hicolor_actions_scalable_view-calendar-list.svg
hicolor_actions_scalable_view-calendar-month.svg hicolor_actions_scalable_view-calendar-month.svg

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
version="1.1"
id="svg33406"
xml:space="preserve"
width="24"
height="24"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs33410" /><g
id="g33418"
transform="matrix(1.3333333,0,0,1.3333333,-0.4184891,-0.76629467)"
style="fill:#e6e6e6;stroke:#e6e6e6"><path
d="m 3.7098313,15.21086 h 5.5434688 c 3.0378319,0 4.8709559,-1.203315 4.8709559,-3.185358 0,-1.364885 -0.924079,-2.4066304 -2.615885,-2.8913388 1.456277,-0.3522586 2.207967,-1.1591661 2.207967,-2.3925413 0,-1.8345634 -1.690803,-2.8030402 -4.8539172,-2.8030402 H 3.771971 L 3.709831,4.5989496 C 4.258064,4.7605188 4.5868035,4.9361785 4.8062972,5.1268679 V 14.007545 C 4.4775581,14.315654 4.2269945,14.433074 3.7719711,14.520434 Z M 7.452249,8.7377548 V 5.0395077 c 0.3608114,-0.059179 0.7045847,-0.07327 1.174642,-0.07327 1.456276,0 2.286141,0.645338 2.286141,1.804504 0,1.3066452 -0.829865,1.9670129 -2.4585287,1.9670129 z m 1.2377841,5.4304202 c -0.3918814,0 -0.7677269,-0.02912 -1.2377841,-0.05824 V 9.794534 h 0.9711844 c 1.8631896,0 2.8193406,0.763697 2.8193406,2.260092 0,1.453185 -0.798796,2.113552 -2.5527409,2.113552 z"
style="fill:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:#e6e6e6;stroke-width:0.727722;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path33420" /></g></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
version="1.1"
id="svg33406"
xml:space="preserve"
width="24"
height="24"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs33410" /><g
id="g33418"
transform="matrix(1.3333333,0,0,1.3333333,-0.4184891,-0.76629467)"><path
d="m 3.7098313,15.21086 h 5.5434688 c 3.0378319,0 4.8709559,-1.203315 4.8709559,-3.185358 0,-1.364885 -0.924079,-2.4066304 -2.615885,-2.8913388 1.456277,-0.3522586 2.207967,-1.1591661 2.207967,-2.3925413 0,-1.8345634 -1.690803,-2.8030402 -4.8539172,-2.8030402 H 3.771971 L 3.709831,4.5989496 C 4.258064,4.7605188 4.5868035,4.9361785 4.8062972,5.1268679 V 14.007545 C 4.4775581,14.315654 4.2269945,14.433074 3.7719711,14.520434 Z M 7.452249,8.7377548 V 5.0395077 c 0.3608114,-0.059179 0.7045847,-0.07327 1.174642,-0.07327 1.456276,0 2.286141,0.645338 2.286141,1.804504 0,1.3066452 -0.829865,1.9670129 -2.4585287,1.9670129 z m 1.2377841,5.4304202 c -0.3918814,0 -0.7677269,-0.02912 -1.2377841,-0.05824 V 9.794534 h 0.9711844 c 1.8631896,0 2.8193406,0.763697 2.8193406,2.260092 0,1.453185 -0.798796,2.113552 -2.5527409,2.113552 z"
style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:#1a1a1a;stroke-width:0.727722;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path33420" /></g></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
version="1.1"
id="svg33406"
xml:space="preserve"
width="24"
height="24"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs33410" /><path
style="fill:none;fill-rule:evenodd;stroke:#e6e6e6;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 7,6 H 21"
id="path33702" /><path
style="fill:none;fill-rule:evenodd;stroke:#e6e6e6;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 3,6 H 5"
id="path33702-9" /><path
style="fill:none;fill-rule:evenodd;stroke:#e6e6e6;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 3,12 H 5"
id="path33702-9-1" /><path
style="fill:none;fill-rule:evenodd;stroke:#e6e6e6;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 3,18 H 5"
id="path33702-9-7" /><path
style="fill:none;fill-rule:evenodd;stroke:#e6e6e6;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 7,12 H 20.99999"
id="path33704" /><path
style="fill:none;fill-rule:evenodd;stroke:#e6e6e6;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 7,18 H 21"
id="path33706" /></svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
version="1.1"
id="svg33406"
xml:space="preserve"
width="24"
height="24"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs33410" /><path
style="fill:none;fill-rule:evenodd;stroke:#1a1a1a;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 7,6 H 21"
id="path33702" /><path
style="fill:none;fill-rule:evenodd;stroke:#1a1a1a;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 3,6 H 5"
id="path33702-9" /><path
style="fill:none;fill-rule:evenodd;stroke:#1a1a1a;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 3,12 H 5"
id="path33702-9-1" /><path
style="fill:none;fill-rule:evenodd;stroke:#1a1a1a;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 3,18 H 5"
id="path33702-9-7" /><path
style="fill:none;fill-rule:evenodd;stroke:#1a1a1a;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 7,12 H 20.99999"
id="path33704" /><path
style="fill:none;fill-rule:evenodd;stroke:#1a1a1a;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 7,18 H 21"
id="path33706" /></svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
version="1.1"
id="svg51326"
xml:space="preserve"
width="24"
height="24"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs51330" /><g
id="g51332"
transform="scale(1.3333333)"
style="fill:#e6e6e6"><g
id="g51334"
transform="translate(-0.12899983,0.66800028)"
style="fill:#e6e6e6"><path
d="M 6.879,5.004 2.035,7.879 v 0.812 l 4.844,2.985 V 10.582 L 3.035,8.285 6.879,6.004 Z"
style="fill:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path51336" /><path
d="M 7.48,13.395 H 8.371 L 10.934,3.145 H 9.98 Z"
style="fill:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path51338" /><path
d="M 11.551,11.613 16.395,8.738 V 7.91 L 11.551,4.941 v 1.094 l 3.828,2.281 -3.828,2.282 z"
style="fill:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path51340" /></g></g></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
version="1.1"
id="svg51326"
xml:space="preserve"
width="24"
height="24"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs51330" /><g
id="g51332"
transform="scale(1.3333333)"><g
id="g51334"
transform="translate(-0.12899983,0.66800028)"><path
d="M 6.879,5.004 2.035,7.879 v 0.812 l 4.844,2.985 V 10.582 L 3.035,8.285 6.879,6.004 Z"
style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path51336" /><path
d="M 7.48,13.395 H 8.371 L 10.934,3.145 H 9.98 Z"
style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path51338" /><path
d="M 11.551,11.613 16.395,8.738 V 7.91 L 11.551,4.941 v 1.094 l 3.828,2.281 -3.828,2.282 z"
style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path51340" /></g></g></svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
version="1.1"
id="svg4631"
xml:space="preserve"
width="24"
height="24"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs4635" /><g
id="g4637"
transform="scale(1.3333333)"
style="stroke:none"><g
id="g4639"
style="stroke:none"><g
id="g4641"
style="stroke:none"><path
d="m 4.902,3.543 h 1.485 v 4.484 h 5.375 V 3.543 h 1.484 V 14.48 H 11.762 V 9.277 H 6.387 V 14.48 H 4.902 Z"
style="fill:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.75;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4643" /></g></g></g></svg>

After

Width:  |  Height:  |  Size: 881 B

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
version="1.1"
id="svg4631"
xml:space="preserve"
width="24"
height="24"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs4635" /><g
id="g4637"
transform="scale(1.3333333)"><g
id="g4639"
style="stroke:none;fill:#1a1a1a"><g
id="g4641"
style="stroke:none;fill:#1a1a1a"><path
d="m 4.902,3.543 h 1.485 v 4.484 h 5.375 V 3.543 h 1.484 V 14.48 H 11.762 V 9.277 H 6.387 V 14.48 H 4.902 Z"
style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.75;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4643" /></g></g></g></svg>

After

Width:  |  Height:  |  Size: 882 B

View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
version="1.1"
id="svg11209"
xml:space="preserve"
width="24"
height="24"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs11213" /><path
d="m 7.5679998,11.765333 h 3.1453332 v -0.478667 c 0,-1 2.313333,-1.5839996 2.313333,-4.1253328 0,-2.0826667 -1.542666,-3.2493333 -4.2719996,-3.2493333 -1.3333333,0 -2.6866666,0.2906667 -3.8333332,0.812 l 0.7093333,2.3546666 c 0.7493333,-0.3333333 1.5413333,-0.48 2.3333333,-0.48 1.1866666,0 1.8333333,0.3546667 1.8333333,1 0,1.2079999 -2.2293333,1.9999999 -2.2293333,3.6879995 z m 1.5413333,5 c 1.1039999,0 1.8959999,-0.792 1.8959999,-1.916 0,-1.166667 -0.770667,-1.98 -1.8959999,-1.98 -1.1453333,0 -1.9159999,0.813333 -1.9159999,1.98 0,1.124 0.7906666,1.916 1.9159999,1.916 z"
style="fill:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.33333"
id="path11219" /><g
id="g11221"
transform="matrix(1.3333333,1.23672,-1.23672,1.3333333,0,0)"
style="stroke:#e6e6e6"><path
d="M 12.671,-3.092 12.67,0.205"
style="fill:none;stroke:#e6e6e6;stroke-width:0.549878;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path11223" /></g><g
id="g11225"
transform="matrix(1.3333333,1.23672,-1.23672,1.3333333,0,0)"
style="stroke:#e6e6e6"><path
d="m 11.571,-1.444 1.1,-2.2 1.099,2.2"
style="fill:none;stroke:#e6e6e6;stroke-width:0.549878;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path11227" /></g><g
id="g11229"
transform="scale(1.3333333)"
style="stroke:#e6e6e6"><path
d="m 12.75,10.5 h -3 v 3 h 4.5 v -2.25"
style="fill:none;stroke:#e6e6e6;stroke-width:0.75;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path11231" /></g></svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
version="1.1"
id="svg11209"
xml:space="preserve"
width="24"
height="24"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs11213" /><g
id="g11215"
transform="scale(1.3333333)"><g
id="g11217"><path
d="M 5.676,8.824 H 8.035 V 8.465 c 0,-0.75 1.735,-1.188 1.735,-3.094 0,-1.562 -1.157,-2.437 -3.204,-2.437 -1,0 -2.015,0.218 -2.875,0.609 l 0.532,1.766 c 0.562,-0.25 1.156,-0.36 1.75,-0.36 0.89,0 1.375,0.266 1.375,0.75 0,0.906 -1.672,1.5 -1.672,2.766 z m 1.156,3.75 c 0.828,0 1.422,-0.594 1.422,-1.437 0,-0.875 -0.578,-1.485 -1.422,-1.485 -0.859,0 -1.437,0.61 -1.437,1.485 0,0.843 0.593,1.437 1.437,1.437 z"
style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path11219" /><g
id="g11221"
transform="matrix(1,0.92754,-0.92754,1,0,0)"><path
d="M 12.671,-3.092 12.67,0.205"
style="fill:none;stroke:#1a1a1a;stroke-width:0.549878;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path11223" /></g><g
id="g11225"
transform="matrix(1,0.92754,-0.92754,1,0,0)"><path
d="m 11.571,-1.444 1.1,-2.2 1.099,2.2"
style="fill:none;stroke:#1a1a1a;stroke-width:0.549878;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path11227" /></g><g
id="g11229"><path
d="m 12.75,10.5 h -3 v 3 h 4.5 v -2.25"
style="fill:none;stroke:#1a1a1a;stroke-width:0.75;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path11231" /></g></g></g></svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
version="1.1"
id="svg33406"
xml:space="preserve"
width="24"
height="24"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs33410" /><path
d="m 8.0000001,20 h 5.9658889 l 0.09764,-0.894667 C 13.340012,19.021333 12.655299,18.876 12.049447,18.48 L 13.98592,5.5 C 14.611801,5.1253333 15.178848,4.98 15.902365,4.876 L 16.000005,4 h -5.828201 l -0.117665,0.876 c 0.743546,0.104 1.388202,0.2706667 1.936473,0.624 l -1.936473,12.98 c -0.6258802,0.416 -1.2129558,0.541333 -1.9364732,0.625333 z"
style="fill:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.2919"
id="path33416" /></svg>

After

Width:  |  Height:  |  Size: 816 B

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
version="1.1"
id="svg33406"
xml:space="preserve"
width="24"
height="24"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs33410" /><path
d="m 8.0000001,20 h 5.9658889 l 0.09764,-0.894667 C 13.340012,19.021333 12.655299,18.876 12.049447,18.48 L 13.98592,5.5 C 14.611801,5.1253333 15.178848,4.98 15.902365,4.876 L 16.000005,4 h -5.828201 l -0.117665,0.876 c 0.743546,0.104 1.388202,0.2706667 1.936473,0.624 l -1.936473,12.98 c -0.6258802,0.416 -1.2129558,0.541333 -1.9364732,0.625333 z"
style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.2919"
id="path33416" /></svg>

After

Width:  |  Height:  |  Size: 816 B

View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
version="1.1"
id="svg51326"
xml:space="preserve"
width="24"
height="24"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs51330" /><g
id="g51332"
transform="matrix(1.2391158,0.4923106,-0.4923106,1.2391158,5.1915138,-3.3935698)"
style="stroke:#e6e6e6"><g
id="g54244"
transform="rotate(38.936484,7.400522,4.6312859)"
style="stroke:#e6e6e6"><path
style="fill:none;fill-rule:evenodd;stroke:#e6e6e6;stroke-width:0.75px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 8.226042,6.6881392 c -0.250375,-1 -0.250375,-2.5 -3.7e-4,-3.5003801 0.2500051,-1.00038 0.749995,-1.50037 1.2503751,-1.75037 0.50038,-0.25 1.0003699,-0.25 1.5003749,3.8e-4 0.500005,0.25038 0.999995,0.75037 1.24962,1.7503851 0.249625,1.000015 0.249625,2.499985 -3.8e-4,3.4996149 -0.250005,0.99963 -0.749995,1.4996199 -1.237528,1.7496199 -0.487533,0.25 -1.0117169,0.25 -1.5117219,3.7e-4 C 8.976407,8.1881291 8.476417,7.6881391 8.226042,6.6881392 Z"
id="path53269" /><g
id="g53872"
style="stroke:#e6e6e6"><path
style="fill:none;fill-rule:evenodd;stroke:#e6e6e6;stroke-width:0.75px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 9.5279035,9.4814178 c 0.031913,0.432314 0.063768,0.8638272 0.1454647,1.2909192 0.081697,0.427092 0.2183089,0.866695 0.4123258,1.219544 0.194017,0.35285 0.455937,0.636559 0.735758,0.83268 0.279821,0.19612 0.581495,0.309578 0.900979,0.327199 0.319483,0.01762 0.645557,-0.05746 0.932875,-0.233203 0.287317,-0.175739 0.530677,-0.450964 0.727124,-0.786131 0.196448,-0.335166 0.346086,-0.730613 0.436312,-1.189182 0.09023,-0.458568 0.120921,-0.980524 0.125016,-1.4233537 0.0041,-0.4428297 -0.0185,-0.806597 -0.05852,-1.1349214 -0.04003,-0.3283244 -0.09759,-0.6212587 -0.21279,-0.914902 C 13.55725,7.1764236 13.384075,6.8820681 13.210376,6.586821"
id="path53746" /><path
style="fill:none;fill-rule:evenodd;stroke:#e6e6e6;stroke-width:0.75px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 9.7374115,7.5753467 c 0.077527,-0.2420881 0.1552029,-0.4846389 0.2831265,-0.6976481 0.127924,-0.2130092 0.316247,-0.406603 0.524908,-0.5641978 0.208661,-0.1575949 0.442518,-0.2843205 0.610091,-0.3612449 0.167572,-0.076924 0.277147,-0.1063432 0.381942,-0.134479"
id="path53750" /></g></g></g></svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
version="1.1"
id="svg51326"
xml:space="preserve"
width="24"
height="24"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs51330" /><g
id="g51332"
transform="matrix(1.2391158,0.4923106,-0.4923106,1.2391158,5.1915138,-3.3935698)"><g
id="g54244"
transform="rotate(38.936484,7.400522,4.6312859)"><path
style="fill:none;fill-rule:evenodd;stroke:#1a1a1a;stroke-width:0.75px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 8.226042,6.6881392 c -0.250375,-1 -0.250375,-2.5 -3.7e-4,-3.5003801 0.2500051,-1.00038 0.749995,-1.50037 1.2503751,-1.75037 0.50038,-0.25 1.0003699,-0.25 1.5003749,3.8e-4 0.500005,0.25038 0.999995,0.75037 1.24962,1.7503851 0.249625,1.000015 0.249625,2.499985 -3.8e-4,3.4996149 -0.250005,0.99963 -0.749995,1.4996199 -1.237528,1.7496199 -0.487533,0.25 -1.0117169,0.25 -1.5117219,3.7e-4 C 8.976407,8.1881291 8.476417,7.6881391 8.226042,6.6881392 Z"
id="path53269" /><g
id="g53872"><path
style="fill:none;fill-rule:evenodd;stroke:#1a1a1a;stroke-width:0.75px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 9.5279035,9.4814178 c 0.031913,0.432314 0.063768,0.8638272 0.1454647,1.2909192 0.081697,0.427092 0.2183089,0.866695 0.4123258,1.219544 0.194017,0.35285 0.455937,0.636559 0.735758,0.83268 0.279821,0.19612 0.581495,0.309578 0.900979,0.327199 0.319483,0.01762 0.645557,-0.05746 0.932875,-0.233203 0.287317,-0.175739 0.530677,-0.450964 0.727124,-0.786131 0.196448,-0.335166 0.346086,-0.730613 0.436312,-1.189182 0.09023,-0.458568 0.120921,-0.980524 0.125016,-1.4233537 0.0041,-0.4428297 -0.0185,-0.806597 -0.05852,-1.1349214 -0.04003,-0.3283244 -0.09759,-0.6212587 -0.21279,-0.914902 C 13.55725,7.1764236 13.384075,6.8820681 13.210376,6.586821"
id="path53746" /><path
style="fill:none;fill-rule:evenodd;stroke:#1a1a1a;stroke-width:0.75px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 9.7374115,7.5753467 c 0.077527,-0.2420881 0.1552029,-0.4846389 0.2831265,-0.6976481 0.127924,-0.2130092 0.316247,-0.406603 0.524908,-0.5641978 0.208661,-0.1575949 0.442518,-0.2843205 0.610091,-0.3612449 0.167572,-0.076924 0.277147,-0.1063432 0.381942,-0.134479"
id="path53750" /></g></g></g></svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
version="1.1"
id="svg824"
xml:space="preserve"
width="24"
height="24"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs828" /><g
id="g834"
transform="matrix(1.3333333,0,0,1.3333333,-0.56799981,-0.08799955)"
style="stroke:#e6e6e6;stroke-width:1.5;stroke-miterlimit:4;stroke-dasharray:none"><path
d="m 5.676,4.566 h 10.5"
style="fill:none;stroke:#e6e6e6;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path836" /></g><g
id="g838"
transform="matrix(1.3333333,0,0,1.3333333,-0.56799981,-0.08799955)"
style="stroke:#e6e6e6;stroke-width:1.5;stroke-miterlimit:4;stroke-dasharray:none"><path
d="m 5.676,9.066 h 10.5"
style="fill:none;stroke:#e6e6e6;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path840" /></g><g
id="g842"
transform="matrix(1.3333333,0,0,1.3333333,-0.56799981,-0.08799955)"
style="stroke:#e6e6e6;stroke-width:1.5;stroke-miterlimit:4;stroke-dasharray:none"><path
d="m 5.676,13.566 h 10.5"
style="fill:none;stroke:#e6e6e6;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path844" /></g><path
d="M 4.4932328,7.9143159 H 5.1385661 V 4.4356494 H 4.7438995 l -1.3133333,0.6866666 0.2506666,0.4386667 0.812,-0.3546667 z"
style="fill:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.33333"
id="path846" /><path
d="m 3.5726414,13.833474 h 2.3333333 v -0.562666 h -1.396 c 0.896,-0.792 1.2706666,-1.354666 1.2706666,-1.937333 0,-0.625333 -0.4586666,-1.021333 -1.1666666,-1.021333 -0.4373333,0 -0.8333333,0.146666 -1.1453333,0.396 l 0.1866666,0.48 c 0.272,-0.209334 0.5626667,-0.313334 0.8333334,-0.313334 0.3959999,0 0.6253333,0.229334 0.6253333,0.562667 0,0.478667 -0.4786667,1 -1.5413333,1.958666 z"
style="fill:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.33333"
id="path848" /><path
d="m 4.7419027,20.015858 c 0.8533333,0 1.4159999,-0.396 1.4159999,-1 0,-0.437333 -0.2919999,-0.770666 -0.7706666,-0.854666 0.3546667,-0.104 0.5826667,-0.396 0.5826667,-0.790667 0,-0.562667 -0.4573334,-0.917333 -1.1453334,-0.917333 -0.3959999,0 -0.8119999,0.104 -1.1453333,0.292 l 0.1453334,0.478666 c 0.312,-0.125333 0.604,-0.208 0.8546666,-0.208 0.396,0 0.6453333,0.166667 0.6453333,0.437334 0,0.312 -0.312,0.521333 -0.7506666,0.521333 H 4.3245694 v 0.5 h 0.292 c 0.5413333,0 0.8746666,0.208 0.8746666,0.541333 0,0.292 -0.2706667,0.458667 -0.7293333,0.458667 -0.292,0 -0.6666667,-0.084 -0.9786667,-0.209333 l -0.1466666,0.5 c 0.3546666,0.166666 0.7293333,0.250666 1.1053333,0.250666 z"
style="fill:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.33333"
id="path850" /></svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
version="1.1"
id="svg824"
xml:space="preserve"
width="24"
height="24"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs828" /><g
id="g834"
transform="matrix(1.3333333,0,0,1.3333333,-0.56799981,-0.08799955)"
style="stroke:#1a1a1a;stroke-width:1.5;stroke-miterlimit:4;stroke-dasharray:none"><path
d="m 5.676,4.566 h 10.5"
style="fill:none;stroke:#1a1a1a;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path836" /></g><g
id="g838"
transform="matrix(1.3333333,0,0,1.3333333,-0.56799981,-0.08799955)"
style="stroke:#1a1a1a;stroke-width:1.5;stroke-miterlimit:4;stroke-dasharray:none"><path
d="m 5.676,9.066 h 10.5"
style="fill:none;stroke:#1a1a1a;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path840" /></g><g
id="g842"
transform="matrix(1.3333333,0,0,1.3333333,-0.56799981,-0.08799955)"
style="stroke:#1a1a1a;stroke-width:1.5;stroke-miterlimit:4;stroke-dasharray:none"><path
d="m 5.676,13.566 h 10.5"
style="fill:none;stroke:#1a1a1a;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path844" /></g><path
d="M 4.4932328,7.9143159 H 5.1385661 V 4.4356494 H 4.7438995 l -1.3133333,0.6866666 0.2506666,0.4386667 0.812,-0.3546667 z"
style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.33333"
id="path846" /><path
d="m 3.5726414,13.833474 h 2.3333333 v -0.562666 h -1.396 c 0.896,-0.792 1.2706666,-1.354666 1.2706666,-1.937333 0,-0.625333 -0.4586666,-1.021333 -1.1666666,-1.021333 -0.4373333,0 -0.8333333,0.146666 -1.1453333,0.396 l 0.1866666,0.48 c 0.272,-0.209334 0.5626667,-0.313334 0.8333334,-0.313334 0.3959999,0 0.6253333,0.229334 0.6253333,0.562667 0,0.478667 -0.4786667,1 -1.5413333,1.958666 z"
style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.33333"
id="path848" /><path
d="m 4.7419027,20.015858 c 0.8533333,0 1.4159999,-0.396 1.4159999,-1 0,-0.437333 -0.2919999,-0.770666 -0.7706666,-0.854666 0.3546667,-0.104 0.5826667,-0.396 0.5826667,-0.790667 0,-0.562667 -0.4573334,-0.917333 -1.1453334,-0.917333 -0.3959999,0 -0.8119999,0.104 -1.1453333,0.292 l 0.1453334,0.478666 c 0.312,-0.125333 0.604,-0.208 0.8546666,-0.208 0.396,0 0.6453333,0.166667 0.6453333,0.437334 0,0.312 -0.312,0.521333 -0.7506666,0.521333 H 4.3245694 v 0.5 h 0.292 c 0.5413333,0 0.8746666,0.208 0.8746666,0.541333 0,0.292 -0.2706667,0.458667 -0.7293333,0.458667 -0.292,0 -0.6666667,-0.084 -0.9786667,-0.209333 l -0.1466666,0.5 c 0.3546666,0.166666 0.7293333,0.250666 1.1053333,0.250666 z"
style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.33333"
id="path850" /></svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
version="1.1"
id="svg33406"
xml:space="preserve"
width="24"
height="24"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs33410" /><path
style="fill:#1a1a1a;fill-rule:evenodd;stroke:#e6e6e6;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 4,3.0000001 V 20.999999"
id="path33601" /><path
style="fill:none;fill-rule:evenodd;stroke:#e6e6e6;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 7.0000095,6.0000002 15,6"
id="path33702-3" /><path
style="fill:none;fill-rule:evenodd;stroke:#e6e6e6;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 7.0000095,12 H 20.999999"
id="path33704-6" /><path
style="fill:none;fill-rule:evenodd;stroke:#e6e6e6;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 7.0000095,18 H 15"
id="path33706-7" /></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
version="1.1"
id="svg33406"
xml:space="preserve"
width="24"
height="24"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs33410" /><path
style="fill:#1a1a1a;fill-rule:evenodd;stroke:#1a1a1a;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 4,3.0000001 V 20.999999"
id="path33601" /><path
style="fill:none;fill-rule:evenodd;stroke:#1a1a1a;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 7.0000095,6.0000002 15,6"
id="path33702-3" /><path
style="fill:none;fill-rule:evenodd;stroke:#1a1a1a;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 7.0000095,12 H 20.999999"
id="path33704-6" /><path
style="fill:none;fill-rule:evenodd;stroke:#1a1a1a;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 7.0000095,18 H 15"
id="path33706-7" /></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -29,6 +29,10 @@
<title>API Index</title> <title>API Index</title>
<xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include> <xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include>
</index> </index>
<index id="api-index-3-44" role="3.44">
<title>Index of new symbols in 3.44</title>
<xi:include href="xml/api-index-3.44.xml"><xi:fallback /></xi:include>
</index>
<index id="api-index-3-42" role="3.42"> <index id="api-index-3-42" role="3.42">
<title>Index of new symbols in 3.42</title> <title>Index of new symbols in 3.42</title>
<xi:include href="xml/api-index-3.42.xml"><xi:fallback /></xi:include> <xi:include href="xml/api-index-3.42.xml"><xi:fallback /></xi:include>

View File

@ -280,6 +280,7 @@
<xi:include href="xml/e-interval-chooser.xml"/> <xi:include href="xml/e-interval-chooser.xml"/>
<xi:include href="xml/e-mail-identity-combo-box.xml"/> <xi:include href="xml/e-mail-identity-combo-box.xml"/>
<xi:include href="xml/e-map.xml"/> <xi:include href="xml/e-map.xml"/>
<xi:include href="xml/e-markdown-editor.xml"/>
<xi:include href="xml/e-menu-tool-action.xml"/> <xi:include href="xml/e-menu-tool-action.xml"/>
<xi:include href="xml/e-menu-tool-button.xml"/> <xi:include href="xml/e-menu-tool-button.xml"/>
<xi:include href="xml/e-mktemp.xml"/> <xi:include href="xml/e-mktemp.xml"/>
@ -326,6 +327,10 @@
<title>Index</title> <title>Index</title>
<xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include> <xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include>
</index> </index>
<index id="api-index-3-44" role="3.44">
<title>Index of new symbols in 3.44</title>
<xi:include href="xml/api-index-3.44.xml"><xi:fallback /></xi:include>
</index>
<index id="api-index-3-42" role="3.42"> <index id="api-index-3-42" role="3.42">
<title>Index of new symbols in 3.42</title> <title>Index of new symbols in 3.42</title>
<xi:include href="xml/api-index-3.42.xml"><xi:fallback /></xi:include> <xi:include href="xml/api-index-3.42.xml"><xi:fallback /></xi:include>

View File

@ -237,6 +237,7 @@ src/e-util/e-mail-signature-editor.c
src/e-util/e-mail-signature-manager.c src/e-util/e-mail-signature-manager.c
src/e-util/e-mail-signature-script-dialog.c src/e-util/e-mail-signature-script-dialog.c
src/e-util/e-map.c src/e-util/e-map.c
src/e-util/e-markdown-editor.c
src/e-util/e-misc-utils.c src/e-util/e-misc-utils.c
src/e-util/e-name-selector-dialog.c src/e-util/e-name-selector-dialog.c
src/e-util/e-name-selector-entry.c src/e-util/e-name-selector-entry.c

View File

@ -168,6 +168,7 @@ set(SOURCES
e-mail-signature-script-dialog.c e-mail-signature-script-dialog.c
e-mail-signature-tree-view.c e-mail-signature-tree-view.c
e-map.c e-map.c
e-markdown-editor.c
e-marshal.c e-marshal.c
e-menu-tool-action.c e-menu-tool-action.c
e-menu-tool-button.c e-menu-tool-button.c
@ -443,6 +444,7 @@ set(HEADERS
e-mail-signature-script-dialog.h e-mail-signature-script-dialog.h
e-mail-signature-tree-view.h e-mail-signature-tree-view.h
e-map.h e-map.h
e-markdown-editor.h
e-menu-tool-action.h e-menu-tool-action.h
e-menu-tool-button.h e-menu-tool-button.h
e-misc-utils.h e-misc-utils.h
@ -651,6 +653,7 @@ target_include_directories(evolution-util PUBLIC
${GEO_INCLUDE_DIRS} ${GEO_INCLUDE_DIRS}
${GNOME_PLATFORM_INCLUDE_DIRS} ${GNOME_PLATFORM_INCLUDE_DIRS}
${GSPELL_INCLUDE_DIRS} ${GSPELL_INCLUDE_DIRS}
${MARKDOWN_INCLUDE_DIRS}
) )
target_link_libraries(evolution-util target_link_libraries(evolution-util
@ -663,6 +666,7 @@ target_link_libraries(evolution-util
${GSPELL_LDFLAGS} ${GSPELL_LDFLAGS}
${ICONV_LIBS} ${ICONV_LIBS}
${MATH_LDFLAGS} ${MATH_LDFLAGS}
${MARKDOWN_LDFLAGS}
) )
if(HAVE_LDAP) if(HAVE_LDAP)
@ -816,6 +820,7 @@ add_private_programs_simple(
test-dateedit test-dateedit
test-html-editor test-html-editor
test-mail-signatures test-mail-signatures
test-markdown-editor
test-name-selector test-name-selector
test-preferences-window test-preferences-window
test-proxy-preferences test-proxy-preferences

View File

@ -0,0 +1,585 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* SPDX-FileCopyrightText: (C) 2022 Red Hat (www.redhat.com)
* SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "evolution-config.h"
#ifdef HAVE_MARKDOWN
#include <cmark.h>
#endif
#include <glib/gi18n-lib.h>
#include <gtk/gtk.h>
#include <libedataserverui/libedataserverui.h>
#include "e-misc-utils.h"
#include "e-spell-text-view.h"
#include "e-web-view.h"
#include "e-markdown-editor.h"
struct _EMarkdownEditorPrivate {
GtkTextView *text_view;
EWebView *web_view;
GtkToolbar *action_toolbar;
};
G_DEFINE_TYPE_WITH_PRIVATE (EMarkdownEditor, e_markdown_editor, GTK_TYPE_BOX)
static void
e_markdown_editor_get_selection (EMarkdownEditor *self,
GtkTextIter *out_start,
GtkTextIter *out_end,
gchar **out_selected_text)
{
GtkTextBuffer *buffer;
GtkTextIter start, end;
buffer = gtk_text_view_get_buffer (self->priv->text_view);
if (gtk_text_buffer_get_selection_bounds (buffer, &start, &end) && out_selected_text) {
*out_selected_text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
} else if (out_selected_text) {
*out_selected_text = NULL;
}
if (out_start)
*out_start = start;
if (out_end)
*out_end = end;
}
static void
e_markdown_editor_surround_selection (EMarkdownEditor *self,
gboolean whole_lines,
const gchar *prefix,
const gchar *suffix)
{
GtkTextIter start, end;
GtkTextBuffer *buffer;
e_markdown_editor_get_selection (self, &start, &end, NULL);
buffer = gtk_text_view_get_buffer (self->priv->text_view);
gtk_text_buffer_begin_user_action (buffer);
if (whole_lines) {
gint to_line, ii;
to_line = gtk_text_iter_get_line (&end);
for (ii = gtk_text_iter_get_line (&start); ii <= to_line; ii++) {
GtkTextIter iter;
gtk_text_buffer_get_iter_at_line (buffer, &iter, ii);
if (prefix && *prefix)
gtk_text_buffer_insert (buffer, &iter, prefix, -1);
if (suffix && *suffix) {
gtk_text_iter_forward_to_line_end (&iter);
gtk_text_buffer_insert (buffer, &iter, suffix, -1);
}
}
} else {
gint end_offset = gtk_text_iter_get_offset (&end);
if (prefix && *prefix) {
gtk_text_buffer_insert (buffer, &start, prefix, -1);
/* Keep the cursor where it is, move it only when the suffix is used */
end_offset += strlen (prefix);
gtk_text_buffer_get_iter_at_offset (buffer, &end, end_offset);
}
if (suffix && *suffix) {
gtk_text_buffer_insert (buffer, &end, suffix, -1);
/* Place the cursor before the suffix */
gtk_text_buffer_get_iter_at_offset (buffer, &end, end_offset);
gtk_text_buffer_select_range (buffer, &end, &end);
}
}
gtk_text_buffer_end_user_action (buffer);
}
static void
e_markdown_editor_add_bold_text_cb (GtkToolButton *button,
gpointer user_data)
{
EMarkdownEditor *self = user_data;
g_return_if_fail (E_IS_MARKDOWN_EDITOR (self));
e_markdown_editor_surround_selection (self, FALSE, "**", "**");
}
static void
e_markdown_editor_add_italic_text_cb (GtkToolButton *button,
gpointer user_data)
{
EMarkdownEditor *self = user_data;
g_return_if_fail (E_IS_MARKDOWN_EDITOR (self));
e_markdown_editor_surround_selection (self, FALSE, "*", "*");
}
static void
e_markdown_editor_insert_quote_cb (GtkToolButton *button,
gpointer user_data)
{
EMarkdownEditor *self = user_data;
g_return_if_fail (E_IS_MARKDOWN_EDITOR (self));
e_markdown_editor_surround_selection (self, TRUE, "> ", NULL);
}
static void
e_markdown_editor_insert_code_cb (GtkToolButton *button,
gpointer user_data)
{
EMarkdownEditor *self = user_data;
GtkTextIter start, end;
gchar *selection = NULL;
g_return_if_fail (E_IS_MARKDOWN_EDITOR (self));
e_markdown_editor_get_selection (self, &start, &end, &selection);
if (selection && strchr (selection, '\n')) {
GtkTextBuffer *buffer;
GtkTextIter iter;
gint start_line, end_line;
buffer = gtk_text_view_get_buffer (self->priv->text_view);
gtk_text_buffer_begin_user_action (buffer);
start_line = gtk_text_iter_get_line (&start);
end_line = gtk_text_iter_get_line (&end);
gtk_text_buffer_get_iter_at_line (buffer, &iter, start_line);
gtk_text_buffer_insert (buffer, &iter, "```\n", -1);
/* One line added above + 1 for the end line itself */
end_line = end_line + 2;
gtk_text_buffer_get_iter_at_line (buffer, &iter, end_line);
if (gtk_text_iter_is_end (&iter) && gtk_text_iter_get_line_offset (&iter) > 0) {
gtk_text_buffer_insert (buffer, &iter, "\n```\n", -1);
} else {
if (gtk_text_iter_is_end (&iter))
end_line--;
gtk_text_buffer_insert (buffer, &iter, "```\n", -1);
}
/* Place the cursor before the suffix */
gtk_text_buffer_get_iter_at_line (buffer, &iter, end_line);
gtk_text_buffer_select_range (buffer, &iter, &iter);
gtk_text_buffer_end_user_action (buffer);
} else {
e_markdown_editor_surround_selection (self, FALSE, "`", "`");
}
g_free (selection);
}
static void
e_markdown_editor_add_link_cb (GtkToolButton *button,
gpointer user_data)
{
EMarkdownEditor *self = user_data;
GtkTextBuffer *buffer;
GtkTextIter start, end;
gchar *selection = NULL;
gint offset;
g_return_if_fail (E_IS_MARKDOWN_EDITOR (self));
e_markdown_editor_get_selection (self, &start, &end, &selection);
buffer = gtk_text_view_get_buffer (self->priv->text_view);
offset = gtk_text_iter_get_offset (&start);
gtk_text_buffer_begin_user_action (buffer);
if (selection && *selection) {
gint end_offset = gtk_text_iter_get_offset (&end);
if (g_ascii_strncasecmp (selection, "http:", 5) == 0 ||
g_ascii_strncasecmp (selection, "https:", 6) == 0) {
gtk_text_buffer_insert (buffer, &start, "[](", -1);
gtk_text_buffer_get_iter_at_offset (buffer, &end, end_offset + 3);
gtk_text_buffer_insert (buffer, &end, ")", -1);
gtk_text_buffer_get_iter_at_offset (buffer, &start, offset + 1);
end = start;
} else {
gtk_text_buffer_insert (buffer, &start, "[", -1);
gtk_text_buffer_get_iter_at_offset (buffer, &end, end_offset + 1);
gtk_text_buffer_insert (buffer, &end, "](https://)", -1);
gtk_text_buffer_get_iter_at_offset (buffer, &start, end_offset + 1 + 2);
gtk_text_buffer_get_iter_at_offset (buffer, &end, end_offset + 1 + 10);
}
gtk_text_buffer_select_range (buffer, &start, &end);
} else {
gtk_text_buffer_insert (buffer, &start, "[](https://)", -1);
/* skip "[](" */
offset += 3;
gtk_text_buffer_get_iter_at_offset (buffer, &start, offset);
/* after the "https://" text */
gtk_text_buffer_get_iter_at_offset (buffer, &end, offset + 8);
gtk_text_buffer_select_range (buffer, &start, &end);
}
gtk_text_buffer_end_user_action (buffer);
}
static void
e_markdown_editor_add_bullet_list_cb (GtkToolButton *button,
gpointer user_data)
{
EMarkdownEditor *self = user_data;
g_return_if_fail (E_IS_MARKDOWN_EDITOR (self));
e_markdown_editor_surround_selection (self, TRUE, "- ", NULL);
}
static void
e_markdown_editor_add_numbered_list_cb (GtkToolButton *button,
gpointer user_data)
{
EMarkdownEditor *self = user_data;
g_return_if_fail (E_IS_MARKDOWN_EDITOR (self));
e_markdown_editor_surround_selection (self, TRUE, "1. ", NULL);
}
static void
e_markdown_editor_add_header_cb (GtkToolButton *button,
gpointer user_data)
{
EMarkdownEditor *self = user_data;
g_return_if_fail (E_IS_MARKDOWN_EDITOR (self));
e_markdown_editor_surround_selection (self, TRUE, "# ", NULL);
}
static void
e_markdown_editor_markdown_syntax_cb (GtkToolButton *button,
gpointer user_data)
{
EMarkdownEditor *self = user_data;
GtkWidget *toplevel;
g_return_if_fail (E_IS_MARKDOWN_EDITOR (self));
toplevel = gtk_widget_get_toplevel (GTK_WIDGET (self));
e_show_uri (GTK_IS_WINDOW (toplevel) ? GTK_WINDOW (toplevel) : NULL, "https://commonmark.org/help/");
}
#ifdef HAVE_MARKDOWN
static void
e_markdown_editor_switch_page_cb (GtkNotebook *notebook,
GtkWidget *page,
guint page_num,
gpointer user_data)
{
EMarkdownEditor *self = user_data;
gchar *converted;
gchar *html;
g_return_if_fail (E_IS_MARKDOWN_EDITOR (self));
gtk_widget_set_visible (GTK_WIDGET (self->priv->action_toolbar), page_num != 1);
/* Not the Preview page */
if (page_num != 1)
return;
converted = e_markdown_editor_dup_html (self);
html = g_strconcat ("<div class=\"-e-web-view-background-color -e-web-view-text-color\" style=\"border: none; padding: 0px; margin: 0;\">",
converted ? converted : "",
"</div>",
NULL);
e_web_view_load_string (self->priv->web_view, html);
g_free (converted);
g_free (html);
}
#endif /* HAVE_MARKDOWN */
static gboolean
e_markdown_editor_is_dark_theme (EMarkdownEditor *self)
{
GdkRGBA rgba;
gdouble brightness;
e_utils_get_theme_color (GTK_WIDGET (self), "theme_text_color,theme_fg_color", E_UTILS_DEFAULT_THEME_TEXT_COLOR, &rgba);
brightness =
(0.2109 * 255.0 * rgba.red) +
(0.5870 * 255.0 * rgba.green) +
(0.1021 * 255.0 * rgba.blue);
return brightness > 140;
}
static void
e_markdown_editor_constructed (GObject *object)
{
struct _items {
const gchar *label;
const gchar *icon_name;
const gchar *icon_name_dark;
GCallback callback;
} items[] = {
#define ITEM(lbl, icn, cbk) { lbl, icn, icn "-dark", G_CALLBACK (cbk) }
ITEM (N_("Add bold text"), "markdown-bold", e_markdown_editor_add_bold_text_cb),
ITEM (N_("Add italic text"), "markdown-italic", e_markdown_editor_add_italic_text_cb),
ITEM (N_("Insert a quote"), "markdown-quote", e_markdown_editor_insert_quote_cb),
ITEM (N_("Insert code"), "markdown-code", e_markdown_editor_insert_code_cb),
ITEM (N_("Add a link"), "markdown-link", e_markdown_editor_add_link_cb),
ITEM (N_("Add a bullet list"), "markdown-bullets", e_markdown_editor_add_bullet_list_cb),
ITEM (N_("Add a numbered list"), "markdown-numbers", e_markdown_editor_add_numbered_list_cb),
ITEM (N_("Add a header"), "markdown-header", e_markdown_editor_add_header_cb),
ITEM (NULL, "", NULL),
ITEM (N_("Open online common mark documentation"), "markdown-help", G_CALLBACK (e_markdown_editor_markdown_syntax_cb))
#undef ITEM
};
EMarkdownEditor *self = E_MARKDOWN_EDITOR (object);
GtkWidget *widget;
GtkNotebook *notebook;
GtkScrolledWindow *scrolled_window;
gboolean is_dark_theme;
guint ii;
/* Chain up to parent's method. */
G_OBJECT_CLASS (e_markdown_editor_parent_class)->constructed (object);
widget = gtk_notebook_new ();
g_object_set (G_OBJECT (widget),
"halign", GTK_ALIGN_FILL,
"hexpand", TRUE,
"valign", GTK_ALIGN_FILL,
"vexpand", TRUE,
"visible", TRUE,
"show-border", FALSE,
"show-tabs", TRUE,
NULL);
gtk_box_pack_start (GTK_BOX (self), widget, TRUE, TRUE, 0);
notebook = GTK_NOTEBOOK (widget);
widget = gtk_scrolled_window_new (NULL, NULL);
g_object_set (G_OBJECT (widget),
"halign", GTK_ALIGN_FILL,
"hexpand", TRUE,
"valign", GTK_ALIGN_FILL,
"vexpand", TRUE,
"visible", TRUE,
"hscrollbar-policy", GTK_POLICY_AUTOMATIC,
"vscrollbar-policy", GTK_POLICY_AUTOMATIC,
NULL);
gtk_notebook_append_page (notebook, widget, gtk_label_new_with_mnemonic (_("_Write")));
scrolled_window = GTK_SCROLLED_WINDOW (widget);
widget = gtk_text_view_new ();
g_object_set (G_OBJECT (widget),
"halign", GTK_ALIGN_FILL,
"hexpand", TRUE,
"valign", GTK_ALIGN_FILL,
"vexpand", TRUE,
"visible", TRUE,
"margin", 4,
"monospace", TRUE,
"wrap-mode", GTK_WRAP_WORD_CHAR,
NULL);
gtk_container_add (GTK_CONTAINER (scrolled_window), widget);
self->priv->text_view = GTK_TEXT_VIEW (widget);
e_buffer_tagger_connect (self->priv->text_view);
e_spell_text_view_attach (self->priv->text_view);
#ifdef HAVE_MARKDOWN
widget = gtk_scrolled_window_new (NULL, NULL);
g_object_set (G_OBJECT (widget),
"halign", GTK_ALIGN_FILL,
"hexpand", TRUE,
"valign", GTK_ALIGN_FILL,
"vexpand", TRUE,
"visible", TRUE,
"hscrollbar-policy", GTK_POLICY_AUTOMATIC,
"vscrollbar-policy", GTK_POLICY_AUTOMATIC,
NULL);
gtk_notebook_append_page (notebook, widget, gtk_label_new_with_mnemonic (_("_Preview")));
scrolled_window = GTK_SCROLLED_WINDOW (widget);
widget = e_web_view_new ();
g_object_set (G_OBJECT (widget),
"halign", GTK_ALIGN_FILL,
"hexpand", TRUE,
"valign", GTK_ALIGN_FILL,
"vexpand", TRUE,
"visible", TRUE,
"margin", 4,
NULL);
gtk_container_add (GTK_CONTAINER (scrolled_window), widget);
self->priv->web_view = E_WEB_VIEW (widget);
#endif /* HAVE_MARKDOWN */
widget = gtk_toolbar_new ();
gtk_widget_show (widget);
gtk_notebook_set_action_widget (notebook, widget, GTK_PACK_END);
self->priv->action_toolbar = GTK_TOOLBAR (widget);
is_dark_theme = e_markdown_editor_is_dark_theme (self);
for (ii = 0; ii < G_N_ELEMENTS (items); ii++) {
GtkToolItem *item;
if (items[ii].callback) {
GtkWidget *icon;
const gchar *icon_name;
icon_name = is_dark_theme ? items[ii].icon_name_dark : items[ii].icon_name;
icon = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_LARGE_TOOLBAR);
gtk_widget_show (GTK_WIDGET (icon));
item = gtk_tool_button_new (icon, _(items[ii].label));
gtk_tool_item_set_tooltip_text (item, _(items[ii].label));
g_signal_connect_object (item, "clicked", items[ii].callback, self, 0);
} else {
item = gtk_separator_tool_item_new ();
}
gtk_widget_show (GTK_WIDGET (item));
gtk_toolbar_insert (self->priv->action_toolbar, item, -1);
}
#ifdef HAVE_MARKDOWN
g_signal_connect_object (notebook, "switch-page", G_CALLBACK (e_markdown_editor_switch_page_cb), self, 0);
#endif
}
static void
e_markdown_editor_class_init (EMarkdownEditorClass *klass)
{
GObjectClass *object_class;
object_class = G_OBJECT_CLASS (klass);
object_class->constructed = e_markdown_editor_constructed;
}
static void
e_markdown_editor_init (EMarkdownEditor *self)
{
self->priv = e_markdown_editor_get_instance_private (self);
}
/**
* e_markdown_editor_new:
*
* Creates a new #EMarkdownEditor
*
* Returns: (transfer full): a new #EMarkdownEditor
*
* Since: 3.44
*/
GtkWidget *
e_markdown_editor_new (void)
{
return g_object_new (E_TYPE_MARKDOWN_EDITOR, NULL);
}
/**
* e_markdown_editor_dup_text:
* @self: an #EMarkdownEditor
*
* Get the markdown text entered in the @self. To get
* the HTML version of it use e_markdown_editor_dup_html().
* Free the returned string with g_free(), when no longer needed.
*
* Returns: (transfer full): the markdown text
*
* Since: 3.44
**/
gchar *
e_markdown_editor_dup_text (EMarkdownEditor *self)
{
GtkTextBuffer *buffer;
GtkTextIter start, end;
g_return_val_if_fail (E_IS_MARKDOWN_EDITOR (self), NULL);
buffer = gtk_text_view_get_buffer (self->priv->text_view);
gtk_text_buffer_get_bounds (buffer, &start, &end);
return gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
}
/**
* e_markdown_editor_dup_html:
* @self: an #EMarkdownEditor
*
* Get the HTML version of the markdown text entered in the @self.
* To get the markdown text use e_markdown_editor_dup_text().
* Free the returned string with g_free(), when no longer needed.
*
* Note: The function can return %NULL when was not built
* with the markdown support.
*
* Returns: (transfer full) (nullable): the markdown text converted
* into HTML, or %NULL, when was not built with the markdown support
*
* Since: 3.44
**/
gchar *
e_markdown_editor_dup_html (EMarkdownEditor *self)
{
#ifdef HAVE_MARKDOWN
GString *html;
gchar *text, *converted;
#endif
g_return_val_if_fail (E_IS_MARKDOWN_EDITOR (self), NULL);
#ifdef HAVE_MARKDOWN
text = e_markdown_editor_dup_text (self);
converted = cmark_markdown_to_html (text ? text : "", text ? strlen (text) : 0,
CMARK_OPT_VALIDATE_UTF8 | CMARK_OPT_UNSAFE);
html = e_str_replace_string (converted, "<blockquote>", "<blockquote type=\"cite\">");
g_free (converted);
g_free (text);
return g_string_free (html, FALSE);
#else
return NULL;
#endif
}

View File

@ -0,0 +1,57 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* SPDX-FileCopyrightText: (C) 2022 Red Hat (www.redhat.com)
* SPDX-License-Identifier: LGPL-2.1-or-later
*/
#if !defined (__E_UTIL_H_INSIDE__) && !defined (LIBEUTIL_COMPILATION)
#error "Only <e-util/e-util.h> should be included directly."
#endif
#ifndef E_MARKDOWN_EDITOR_H
#define E_MARKDOWN_EDITOR_H
#include <gtk/gtk.h>
/* Standard GObject macros */
#define E_TYPE_MARKDOWN_EDITOR \
(e_markdown_editor_get_type ())
#define E_MARKDOWN_EDITOR(obj) \
(G_TYPE_CHECK_INSTANCE_CAST \
((obj), E_TYPE_MARKDOWN_EDITOR, EMarkdownEditor))
#define E_MARKDOWN_EDITOR_CLASS(cls) \
(G_TYPE_CHECK_CLASS_CAST \
((cls), E_TYPE_MARKDOWN_EDITOR, EMarkdownEditorClass))
#define E_IS_MARKDOWN_EDITOR(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE \
((obj), E_TYPE_MARKDOWN_EDITOR))
#define E_IS_MARKDOWN_EDITOR_CLASS(cls) \
(G_TYPE_CHECK_CLASS_TYPE \
((cls), E_TYPE_MARKDOWN_EDITOR))
#define E_MARKDOWN_EDITOR_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS \
((obj), E_TYPE_MARKDOWN_EDITOR, EMarkdownEditorClass))
G_BEGIN_DECLS
typedef struct _EMarkdownEditor EMarkdownEditor;
typedef struct _EMarkdownEditorClass EMarkdownEditorClass;
typedef struct _EMarkdownEditorPrivate EMarkdownEditorPrivate;
struct _EMarkdownEditor {
GtkBox parent;
EMarkdownEditorPrivate *priv;
};
struct _EMarkdownEditorClass {
GtkBoxClass parent_class;
};
GType e_markdown_editor_get_type (void) G_GNUC_CONST;
GtkWidget * e_markdown_editor_new (void);
gchar * e_markdown_editor_dup_text (EMarkdownEditor *self);
gchar * e_markdown_editor_dup_html (EMarkdownEditor *self);
G_END_DECLS
#endif /* E_MARKDOWN_EDITOR_H */

View File

@ -152,6 +152,7 @@
#include <e-util/e-mail-signature-script-dialog.h> #include <e-util/e-mail-signature-script-dialog.h>
#include <e-util/e-mail-signature-tree-view.h> #include <e-util/e-mail-signature-tree-view.h>
#include <e-util/e-map.h> #include <e-util/e-map.h>
#include <e-util/e-markdown-editor.h>
#include <e-util/e-menu-tool-action.h> #include <e-util/e-menu-tool-action.h>
#include <e-util/e-menu-tool-button.h> #include <e-util/e-menu-tool-button.h>
#include <e-util/e-misc-utils.h> #include <e-util/e-misc-utils.h>

View File

@ -0,0 +1,81 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* SPDX-FileCopyrightText: (C) 2022 Red Hat (www.redhat.com)
* SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "evolution-config.h"
#include <glib/gi18n-lib.h>
#include <e-util/e-util.h>
static gboolean
window_delete_event_cb (GtkWidget *widget,
GdkEvent *event,
gpointer user_data)
{
gtk_main_quit ();
return FALSE;
}
static gint
on_idle_create_widget (gpointer user_data)
{
GtkWidget *window, *editor;
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_default_size (GTK_WINDOW (window), 640, 480);
g_signal_connect (
window, "delete-event",
G_CALLBACK (window_delete_event_cb), NULL);
editor = e_markdown_editor_new ();
g_object_set (G_OBJECT (editor),
"halign", GTK_ALIGN_FILL,
"hexpand", TRUE,
"valign", GTK_ALIGN_FILL,
"vexpand", TRUE,
"visible", TRUE,
NULL);
gtk_container_add (GTK_CONTAINER (window), editor);
gtk_widget_show (window);
return FALSE;
}
gint
main (gint argc,
gchar **argv)
{
GList *modules;
bindtextdomain (GETTEXT_PACKAGE, EVOLUTION_LOCALEDIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
textdomain (GETTEXT_PACKAGE);
gtk_init (&argc, &argv);
e_util_init_main_thread (NULL);
e_passwords_init ();
g_setenv ("EVOLUTION_SOURCE_WEBKITDATADIR", EVOLUTION_SOURCE_WEBKITDATADIR, FALSE);
gtk_icon_theme_append_search_path (gtk_icon_theme_get_default (), EVOLUTION_ICONDIR);
gtk_icon_theme_append_search_path (gtk_icon_theme_get_default (), E_DATA_SERVER_ICONDIR);
modules = e_module_load_all_in_directory (EVOLUTION_MODULEDIR);
g_list_free_full (modules, (GDestroyNotify) g_type_module_unuse);
g_idle_add ((GSourceFunc) on_idle_create_widget, NULL);
gtk_main ();
e_misc_util_free_global_memory ();
return 0;
}