diff --git a/.DS_Store b/.DS_Store
new file mode 100644
index 0000000..4567c3b
Binary files /dev/null and b/.DS_Store differ
diff --git a/WorkPad.pro b/WorkPad.pro
index 69393c6..75622f3 100644
--- a/WorkPad.pro
+++ b/WorkPad.pro
@@ -7,7 +7,7 @@ CONFIG += c++17
win32:VERSION = 3.0.0.0 # major.minor.patch.build
else:VERSION = 3.0.0 # major.minor.patch
-DEFINES += APP_VERSION=\"\\\"$${VERSION}-rc1\\\"\"
+DEFINES += APP_VERSION=\"\\\"$${VERSION}-rc2\\\"\"
DEFINES += APP_NAME=\"\\\"WorkPad\\\"\"
# remove possible other optimization flags
@@ -111,4 +111,5 @@ else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
RESOURCES += \
- icons.qrc
+ icons.qrc \
+ static.qrc
diff --git a/resources/style.css b/resources/style.css
new file mode 100644
index 0000000..ce0861d
--- /dev/null
+++ b/resources/style.css
@@ -0,0 +1,1105 @@
+/* light */
+.markdown-body {
+ color-scheme: light;
+ -ms-text-size-adjust: 100%;
+ -webkit-text-size-adjust: 100%;
+ margin: 0;
+ color: #1f2328;
+ background-color: #ffffff;
+ font-family: -apple-system,BlinkMacSystemFont,"Segoe UI","Noto Sans",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";
+ font-size: 16px;
+ line-height: 1.5;
+ word-wrap: break-word;
+}
+
+.markdown-body .octicon {
+ display: inline-block;
+ fill: currentColor;
+ vertical-align: text-bottom;
+}
+
+.markdown-body h1:hover .anchor .octicon-link:before,
+.markdown-body h2:hover .anchor .octicon-link:before,
+.markdown-body h3:hover .anchor .octicon-link:before,
+.markdown-body h4:hover .anchor .octicon-link:before,
+.markdown-body h5:hover .anchor .octicon-link:before,
+.markdown-body h6:hover .anchor .octicon-link:before {
+ width: 16px;
+ height: 16px;
+ content: ' ';
+ display: inline-block;
+ background-color: currentColor;
+ -webkit-mask-image: url("data:image/svg+xml,");
+ mask-image: url("data:image/svg+xml,");
+}
+
+.markdown-body details,
+.markdown-body figcaption,
+.markdown-body figure {
+ display: block;
+}
+
+.markdown-body summary {
+ display: list-item;
+}
+
+.markdown-body [hidden] {
+ display: none !important;
+}
+
+.markdown-body a {
+ background-color: transparent;
+ color: #0969da;
+ text-decoration: none;
+}
+
+.markdown-body abbr[title] {
+ border-bottom: none;
+ -webkit-text-decoration: underline dotted;
+ text-decoration: underline dotted;
+}
+
+.markdown-body b,
+.markdown-body strong {
+ font-weight: 600;
+}
+
+.markdown-body dfn {
+ font-style: italic;
+}
+
+.markdown-body h1 {
+ margin: .67em 0;
+ font-weight: 600;
+ padding-bottom: .3em;
+ font-size: 2em;
+ border-bottom: 1px solid #d1d9e0b3;
+}
+
+.markdown-body mark {
+ background-color: #fff8c5;
+ color: #1f2328;
+}
+
+.markdown-body small {
+ font-size: 90%;
+}
+
+.markdown-body sub,
+.markdown-body sup {
+ font-size: 75%;
+ line-height: 0;
+ position: relative;
+ vertical-align: baseline;
+}
+
+.markdown-body sub {
+ bottom: -0.25em;
+}
+
+.markdown-body sup {
+ top: -0.5em;
+}
+
+.markdown-body img {
+ border-style: none;
+ max-width: 100%;
+ box-sizing: content-box;
+}
+
+.markdown-body code,
+.markdown-body kbd,
+.markdown-body pre,
+.markdown-body samp {
+ font-family: monospace;
+ font-size: 1em;
+}
+
+.markdown-body figure {
+ margin: 1em 2.5rem;
+}
+
+.markdown-body hr {
+ box-sizing: content-box;
+ overflow: hidden;
+ background: transparent;
+ border-bottom: 1px solid #d1d9e0b3;
+ height: .25em;
+ padding: 0;
+ margin: 1.5rem 0;
+ background-color: #d1d9e0;
+ border: 0;
+}
+
+.markdown-body input {
+ font: inherit;
+ margin: 0;
+ overflow: visible;
+ font-family: inherit;
+ font-size: inherit;
+ line-height: inherit;
+}
+
+.markdown-body [type=button],
+.markdown-body [type=reset],
+.markdown-body [type=submit] {
+ -webkit-appearance: button;
+ appearance: button;
+}
+
+.markdown-body [type=checkbox],
+.markdown-body [type=radio] {
+ box-sizing: border-box;
+ padding: 0;
+}
+
+.markdown-body [type=number]::-webkit-inner-spin-button,
+.markdown-body [type=number]::-webkit-outer-spin-button {
+ height: auto;
+}
+
+.markdown-body [type=search]::-webkit-search-cancel-button,
+.markdown-body [type=search]::-webkit-search-decoration {
+ -webkit-appearance: none;
+ appearance: none;
+}
+
+.markdown-body ::-webkit-input-placeholder {
+ color: inherit;
+ opacity: .54;
+}
+
+.markdown-body ::-webkit-file-upload-button {
+ -webkit-appearance: button;
+ appearance: button;
+ font: inherit;
+}
+
+.markdown-body a:hover {
+ text-decoration: underline;
+}
+
+.markdown-body ::placeholder {
+ color: #59636e;
+ opacity: 1;
+}
+
+.markdown-body hr::before {
+ display: table;
+ content: "";
+}
+
+.markdown-body hr::after {
+ display: table;
+ clear: both;
+ content: "";
+}
+
+.markdown-body table {
+ border-spacing: 0;
+ border-collapse: collapse;
+ display: block;
+ width: max-content;
+ max-width: 100%;
+ overflow: auto;
+ font-variant: tabular-nums;
+}
+
+.markdown-body td,
+.markdown-body th {
+ padding: 0;
+}
+
+.markdown-body details summary {
+ cursor: pointer;
+}
+
+.markdown-body a:focus,
+.markdown-body [role=button]:focus,
+.markdown-body input[type=radio]:focus,
+.markdown-body input[type=checkbox]:focus {
+ outline: 2px solid #0969da;
+ outline-offset: -2px;
+ box-shadow: none;
+}
+
+.markdown-body a:focus:not(:focus-visible),
+.markdown-body [role=button]:focus:not(:focus-visible),
+.markdown-body input[type=radio]:focus:not(:focus-visible),
+.markdown-body input[type=checkbox]:focus:not(:focus-visible) {
+ outline: solid 1px transparent;
+}
+
+.markdown-body a:focus-visible,
+.markdown-body [role=button]:focus-visible,
+.markdown-body input[type=radio]:focus-visible,
+.markdown-body input[type=checkbox]:focus-visible {
+ outline: 2px solid #0969da;
+ outline-offset: -2px;
+ box-shadow: none;
+}
+
+.markdown-body a:not([class]):focus,
+.markdown-body a:not([class]):focus-visible,
+.markdown-body input[type=radio]:focus,
+.markdown-body input[type=radio]:focus-visible,
+.markdown-body input[type=checkbox]:focus,
+.markdown-body input[type=checkbox]:focus-visible {
+ outline-offset: 0;
+}
+
+.markdown-body kbd {
+ display: inline-block;
+ padding: 0.25rem;
+ font: 11px ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace;
+ line-height: 10px;
+ color: #1f2328;
+ vertical-align: middle;
+ background-color: #f6f8fa;
+ border: solid 1px #d1d9e0b3;
+ border-bottom-color: #d1d9e0b3;
+ border-radius: 6px;
+ box-shadow: inset 0 -1px 0 #d1d9e0b3;
+}
+
+.markdown-body h1,
+.markdown-body h2,
+.markdown-body h3,
+.markdown-body h4,
+.markdown-body h5,
+.markdown-body h6 {
+ margin-top: 1.5rem;
+ margin-bottom: 1rem;
+ font-weight: 600;
+ line-height: 1.25;
+}
+
+.markdown-body h2 {
+ font-weight: 600;
+ padding-bottom: .3em;
+ font-size: 1.5em;
+ border-bottom: 1px solid #d1d9e0b3;
+}
+
+.markdown-body h3 {
+ font-weight: 600;
+ font-size: 1.25em;
+}
+
+.markdown-body h4 {
+ font-weight: 600;
+ font-size: 1em;
+}
+
+.markdown-body h5 {
+ font-weight: 600;
+ font-size: .875em;
+}
+
+.markdown-body h6 {
+ font-weight: 600;
+ font-size: .85em;
+ color: #59636e;
+}
+
+.markdown-body p {
+ margin-top: 0;
+ margin-bottom: 10px;
+}
+
+.markdown-body blockquote {
+ margin: 0;
+ padding: 0 1em;
+ color: #59636e;
+ border-left: .25em solid #d1d9e0;
+}
+
+.markdown-body ul,
+.markdown-body ol {
+ margin-top: 0;
+ margin-bottom: 0;
+ padding-left: 2em;
+}
+
+.markdown-body ol ol,
+.markdown-body ul ol {
+ list-style-type: lower-roman;
+}
+
+.markdown-body ul ul ol,
+.markdown-body ul ol ol,
+.markdown-body ol ul ol,
+.markdown-body ol ol ol {
+ list-style-type: lower-alpha;
+}
+
+.markdown-body dd {
+ margin-left: 0;
+}
+
+.markdown-body tt,
+.markdown-body code,
+.markdown-body samp {
+ font-family: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace;
+ font-size: 12px;
+}
+
+.markdown-body pre {
+ margin-top: 0;
+ margin-bottom: 0;
+ font-family: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace;
+ font-size: 12px;
+ word-wrap: normal;
+}
+
+.markdown-body .octicon {
+ display: inline-block;
+ overflow: visible !important;
+ vertical-align: text-bottom;
+ fill: currentColor;
+}
+
+.markdown-body input::-webkit-outer-spin-button,
+.markdown-body input::-webkit-inner-spin-button {
+ margin: 0;
+ appearance: none;
+}
+
+.markdown-body .mr-2 {
+ margin-right: 0.5rem !important;
+}
+
+.markdown-body::before {
+ display: table;
+ content: "";
+}
+
+.markdown-body::after {
+ display: table;
+ clear: both;
+ content: "";
+}
+
+.markdown-body>*:first-child {
+ margin-top: 0 !important;
+}
+
+.markdown-body>*:last-child {
+ margin-bottom: 0 !important;
+}
+
+.markdown-body a:not([href]) {
+ color: inherit;
+ text-decoration: none;
+}
+
+.markdown-body .absent {
+ color: #d1242f;
+}
+
+.markdown-body .anchor {
+ float: left;
+ padding-right: 0.25rem;
+ margin-left: -20px;
+ line-height: 1;
+}
+
+.markdown-body .anchor:focus {
+ outline: none;
+}
+
+.markdown-body p,
+.markdown-body blockquote,
+.markdown-body ul,
+.markdown-body ol,
+.markdown-body dl,
+.markdown-body table,
+.markdown-body pre,
+.markdown-body details {
+ margin-top: 0;
+ margin-bottom: 1rem;
+}
+
+.markdown-body blockquote>:first-child {
+ margin-top: 0;
+}
+
+.markdown-body blockquote>:last-child {
+ margin-bottom: 0;
+}
+
+.markdown-body h1 .octicon-link,
+.markdown-body h2 .octicon-link,
+.markdown-body h3 .octicon-link,
+.markdown-body h4 .octicon-link,
+.markdown-body h5 .octicon-link,
+.markdown-body h6 .octicon-link {
+ color: #1f2328;
+ vertical-align: middle;
+ visibility: hidden;
+}
+
+.markdown-body h1:hover .anchor,
+.markdown-body h2:hover .anchor,
+.markdown-body h3:hover .anchor,
+.markdown-body h4:hover .anchor,
+.markdown-body h5:hover .anchor,
+.markdown-body h6:hover .anchor {
+ text-decoration: none;
+}
+
+.markdown-body h1:hover .anchor .octicon-link,
+.markdown-body h2:hover .anchor .octicon-link,
+.markdown-body h3:hover .anchor .octicon-link,
+.markdown-body h4:hover .anchor .octicon-link,
+.markdown-body h5:hover .anchor .octicon-link,
+.markdown-body h6:hover .anchor .octicon-link {
+ visibility: visible;
+}
+
+.markdown-body h1 tt,
+.markdown-body h1 code,
+.markdown-body h2 tt,
+.markdown-body h2 code,
+.markdown-body h3 tt,
+.markdown-body h3 code,
+.markdown-body h4 tt,
+.markdown-body h4 code,
+.markdown-body h5 tt,
+.markdown-body h5 code,
+.markdown-body h6 tt,
+.markdown-body h6 code {
+ padding: 0 .2em;
+ font-size: inherit;
+}
+
+.markdown-body summary h1,
+.markdown-body summary h2,
+.markdown-body summary h3,
+.markdown-body summary h4,
+.markdown-body summary h5,
+.markdown-body summary h6 {
+ display: inline-block;
+}
+
+.markdown-body summary h1 .anchor,
+.markdown-body summary h2 .anchor,
+.markdown-body summary h3 .anchor,
+.markdown-body summary h4 .anchor,
+.markdown-body summary h5 .anchor,
+.markdown-body summary h6 .anchor {
+ margin-left: -40px;
+}
+
+.markdown-body summary h1,
+.markdown-body summary h2 {
+ padding-bottom: 0;
+ border-bottom: 0;
+}
+
+.markdown-body ul.no-list,
+.markdown-body ol.no-list {
+ padding: 0;
+ list-style-type: none;
+}
+
+.markdown-body ol[type="a s"] {
+ list-style-type: lower-alpha;
+}
+
+.markdown-body ol[type="A s"] {
+ list-style-type: upper-alpha;
+}
+
+.markdown-body ol[type="i s"] {
+ list-style-type: lower-roman;
+}
+
+.markdown-body ol[type="I s"] {
+ list-style-type: upper-roman;
+}
+
+.markdown-body ol[type="1"] {
+ list-style-type: decimal;
+}
+
+.markdown-body div>ol:not([type]) {
+ list-style-type: decimal;
+}
+
+.markdown-body ul ul,
+.markdown-body ul ol,
+.markdown-body ol ol,
+.markdown-body ol ul {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+.markdown-body li>p {
+ margin-top: 1rem;
+}
+
+.markdown-body li+li {
+ margin-top: .25em;
+}
+
+.markdown-body dl {
+ padding: 0;
+}
+
+.markdown-body dl dt {
+ padding: 0;
+ margin-top: 1rem;
+ font-size: 1em;
+ font-style: italic;
+ font-weight: 600;
+}
+
+.markdown-body dl dd {
+ padding: 0 1rem;
+ margin-bottom: 1rem;
+}
+
+.markdown-body table th {
+ font-weight: 600;
+}
+
+.markdown-body table th,
+.markdown-body table td {
+ padding: 6px 13px;
+ border: 1px solid #d1d9e0;
+}
+
+.markdown-body table td>:last-child {
+ margin-bottom: 0;
+}
+
+.markdown-body table tr {
+ background-color: #ffffff;
+ border-top: 1px solid #d1d9e0b3;
+}
+
+.markdown-body table tr:nth-child(2n) {
+ background-color: #f6f8fa;
+}
+
+.markdown-body table img {
+ background-color: transparent;
+}
+
+.markdown-body img[align=right] {
+ padding-left: 20px;
+}
+
+.markdown-body img[align=left] {
+ padding-right: 20px;
+}
+
+.markdown-body .emoji {
+ max-width: none;
+ vertical-align: text-top;
+ background-color: transparent;
+}
+
+.markdown-body span.frame {
+ display: block;
+ overflow: hidden;
+}
+
+.markdown-body span.frame>span {
+ display: block;
+ float: left;
+ width: auto;
+ padding: 7px;
+ margin: 13px 0 0;
+ overflow: hidden;
+ border: 1px solid #d1d9e0;
+}
+
+.markdown-body span.frame span img {
+ display: block;
+ float: left;
+}
+
+.markdown-body span.frame span span {
+ display: block;
+ padding: 5px 0 0;
+ clear: both;
+ color: #1f2328;
+}
+
+.markdown-body span.align-center {
+ display: block;
+ overflow: hidden;
+ clear: both;
+}
+
+.markdown-body span.align-center>span {
+ display: block;
+ margin: 13px auto 0;
+ overflow: hidden;
+ text-align: center;
+}
+
+.markdown-body span.align-center span img {
+ margin: 0 auto;
+ text-align: center;
+}
+
+.markdown-body span.align-right {
+ display: block;
+ overflow: hidden;
+ clear: both;
+}
+
+.markdown-body span.align-right>span {
+ display: block;
+ margin: 13px 0 0;
+ overflow: hidden;
+ text-align: right;
+}
+
+.markdown-body span.align-right span img {
+ margin: 0;
+ text-align: right;
+}
+
+.markdown-body span.float-left {
+ display: block;
+ float: left;
+ margin-right: 13px;
+ overflow: hidden;
+}
+
+.markdown-body span.float-left span {
+ margin: 13px 0 0;
+}
+
+.markdown-body span.float-right {
+ display: block;
+ float: right;
+ margin-left: 13px;
+ overflow: hidden;
+}
+
+.markdown-body span.float-right>span {
+ display: block;
+ margin: 13px auto 0;
+ overflow: hidden;
+ text-align: right;
+}
+
+.markdown-body code,
+.markdown-body tt {
+ padding: .2em .4em;
+ margin: 0;
+ font-size: 85%;
+ white-space: break-spaces;
+ background-color: #818b981f;
+ border-radius: 6px;
+}
+
+.markdown-body code br,
+.markdown-body tt br {
+ display: none;
+}
+
+.markdown-body del code {
+ text-decoration: inherit;
+}
+
+.markdown-body samp {
+ font-size: 85%;
+}
+
+.markdown-body pre code {
+ font-size: 100%;
+}
+
+.markdown-body pre>code {
+ padding: 0;
+ margin: 0;
+ word-break: normal;
+ white-space: pre;
+ background: transparent;
+ border: 0;
+}
+
+.markdown-body .highlight {
+ margin-bottom: 1rem;
+}
+
+.markdown-body .highlight pre {
+ margin-bottom: 0;
+ word-break: normal;
+}
+
+.markdown-body .highlight pre,
+.markdown-body pre {
+ padding: 1rem;
+ overflow: auto;
+ font-size: 85%;
+ line-height: 1.45;
+ color: #1f2328;
+ background-color: #f6f8fa;
+ border-radius: 6px;
+}
+
+.markdown-body pre code,
+.markdown-body pre tt {
+ display: inline;
+ max-width: auto;
+ padding: 0;
+ margin: 0;
+ overflow: visible;
+ line-height: inherit;
+ word-wrap: normal;
+ background-color: transparent;
+ border: 0;
+}
+
+.markdown-body .csv-data td,
+.markdown-body .csv-data th {
+ padding: 5px;
+ overflow: hidden;
+ font-size: 12px;
+ line-height: 1;
+ text-align: left;
+ white-space: nowrap;
+}
+
+.markdown-body .csv-data .blob-num {
+ padding: 10px 0.5rem 9px;
+ text-align: right;
+ background: #ffffff;
+ border: 0;
+}
+
+.markdown-body .csv-data tr {
+ border-top: 0;
+}
+
+.markdown-body .csv-data th {
+ font-weight: 600;
+ background: #f6f8fa;
+ border-top: 0;
+}
+
+.markdown-body [data-footnote-ref]::before {
+ content: "[";
+}
+
+.markdown-body [data-footnote-ref]::after {
+ content: "]";
+}
+
+.markdown-body .footnotes {
+ font-size: 12px;
+ color: #59636e;
+ border-top: 1px solid #d1d9e0;
+}
+
+.markdown-body .footnotes ol {
+ padding-left: 1rem;
+}
+
+.markdown-body .footnotes ol ul {
+ display: inline-block;
+ padding-left: 1rem;
+ margin-top: 1rem;
+}
+
+.markdown-body .footnotes li {
+ position: relative;
+}
+
+.markdown-body .footnotes li:target::before {
+ position: absolute;
+ top: calc(0.5rem*-1);
+ right: calc(0.5rem*-1);
+ bottom: calc(0.5rem*-1);
+ left: calc(1.5rem*-1);
+ pointer-events: none;
+ content: "";
+ border: 2px solid #0969da;
+ border-radius: 6px;
+}
+
+.markdown-body .footnotes li:target {
+ color: #1f2328;
+}
+
+.markdown-body .footnotes .data-footnote-backref g-emoji {
+ font-family: monospace;
+}
+
+.markdown-body body:has(:modal) {
+ padding-right: var(--dialog-scrollgutter) !important;
+}
+
+.markdown-body .pl-c {
+ color: #59636e;
+}
+
+.markdown-body .pl-c1,
+.markdown-body .pl-s .pl-v {
+ color: #0550ae;
+}
+
+.markdown-body .pl-e,
+.markdown-body .pl-en {
+ color: #6639ba;
+}
+
+.markdown-body .pl-smi,
+.markdown-body .pl-s .pl-s1 {
+ color: #1f2328;
+}
+
+.markdown-body .pl-ent {
+ color: #0550ae;
+}
+
+.markdown-body .pl-k {
+ color: #cf222e;
+}
+
+.markdown-body .pl-s,
+.markdown-body .pl-pds,
+.markdown-body .pl-s .pl-pse .pl-s1,
+.markdown-body .pl-sr,
+.markdown-body .pl-sr .pl-cce,
+.markdown-body .pl-sr .pl-sre,
+.markdown-body .pl-sr .pl-sra {
+ color: #0a3069;
+}
+
+.markdown-body .pl-v,
+.markdown-body .pl-smw {
+ color: #953800;
+}
+
+.markdown-body .pl-bu {
+ color: #82071e;
+}
+
+.markdown-body .pl-ii {
+ color: #f6f8fa;
+ background-color: #82071e;
+}
+
+.markdown-body .pl-c2 {
+ color: #f6f8fa;
+ background-color: #cf222e;
+}
+
+.markdown-body .pl-sr .pl-cce {
+ font-weight: bold;
+ color: #116329;
+}
+
+.markdown-body .pl-ml {
+ color: #3b2300;
+}
+
+.markdown-body .pl-mh,
+.markdown-body .pl-mh .pl-en,
+.markdown-body .pl-ms {
+ font-weight: bold;
+ color: #0550ae;
+}
+
+.markdown-body .pl-mi {
+ font-style: italic;
+ color: #1f2328;
+}
+
+.markdown-body .pl-mb {
+ font-weight: bold;
+ color: #1f2328;
+}
+
+.markdown-body .pl-md {
+ color: #82071e;
+ background-color: #ffebe9;
+}
+
+.markdown-body .pl-mi1 {
+ color: #116329;
+ background-color: #dafbe1;
+}
+
+.markdown-body .pl-mc {
+ color: #953800;
+ background-color: #ffd8b5;
+}
+
+.markdown-body .pl-mi2 {
+ color: #d1d9e0;
+ background-color: #0550ae;
+}
+
+.markdown-body .pl-mdr {
+ font-weight: bold;
+ color: #8250df;
+}
+
+.markdown-body .pl-ba {
+ color: #59636e;
+}
+
+.markdown-body .pl-sg {
+ color: #818b98;
+}
+
+.markdown-body .pl-corl {
+ text-decoration: underline;
+ color: #0a3069;
+}
+
+.markdown-body [role=button]:focus:not(:focus-visible),
+.markdown-body [role=tabpanel][tabindex="0"]:focus:not(:focus-visible),
+.markdown-body button:focus:not(:focus-visible),
+.markdown-body summary:focus:not(:focus-visible),
+.markdown-body a:focus:not(:focus-visible) {
+ outline: none;
+ box-shadow: none;
+}
+
+.markdown-body [tabindex="0"]:focus:not(:focus-visible),
+.markdown-body details-dialog:focus:not(:focus-visible) {
+ outline: none;
+}
+
+.markdown-body g-emoji {
+ display: inline-block;
+ min-width: 1ch;
+ font-family: "Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";
+ font-size: 1em;
+ font-style: normal !important;
+ font-weight: 400;
+ line-height: 1;
+ vertical-align: -0.075em;
+}
+
+.markdown-body g-emoji img {
+ width: 1em;
+ height: 1em;
+}
+
+.markdown-body .task-list-item {
+ list-style-type: none;
+}
+
+.markdown-body .task-list-item label {
+ font-weight: 400;
+}
+
+.markdown-body .task-list-item.enabled label {
+ cursor: pointer;
+}
+
+.markdown-body .task-list-item+.task-list-item {
+ margin-top: 0.25rem;
+}
+
+.markdown-body .task-list-item .handle {
+ display: none;
+}
+
+.markdown-body .task-list-item-checkbox {
+ margin: 0 .2em .25em -1.4em;
+ vertical-align: middle;
+}
+
+.markdown-body ul:dir(rtl) .task-list-item-checkbox {
+ margin: 0 -1.6em .25em .2em;
+}
+
+.markdown-body ol:dir(rtl) .task-list-item-checkbox {
+ margin: 0 -1.6em .25em .2em;
+}
+
+.markdown-body .contains-task-list:hover .task-list-item-convert-container,
+.markdown-body .contains-task-list:focus-within .task-list-item-convert-container {
+ display: block;
+ width: auto;
+ height: 24px;
+ overflow: visible;
+ clip: auto;
+}
+
+.markdown-body ::-webkit-calendar-picker-indicator {
+ filter: invert(50%);
+}
+
+.markdown-body .markdown-alert {
+ padding: 0.5rem 1rem;
+ margin-bottom: 1rem;
+ color: inherit;
+ border-left: .25em solid #d1d9e0;
+}
+
+.markdown-body .markdown-alert>:first-child {
+ margin-top: 0;
+}
+
+.markdown-body .markdown-alert>:last-child {
+ margin-bottom: 0;
+}
+
+.markdown-body .markdown-alert .markdown-alert-title {
+ display: flex;
+ font-weight: 500;
+ align-items: center;
+ line-height: 1;
+}
+
+.markdown-body .markdown-alert.markdown-alert-note {
+ border-left-color: #0969da;
+}
+
+.markdown-body .markdown-alert.markdown-alert-note .markdown-alert-title {
+ color: #0969da;
+}
+
+.markdown-body .markdown-alert.markdown-alert-important {
+ border-left-color: #8250df;
+}
+
+.markdown-body .markdown-alert.markdown-alert-important .markdown-alert-title {
+ color: #8250df;
+}
+
+.markdown-body .markdown-alert.markdown-alert-warning {
+ border-left-color: #9a6700;
+}
+
+.markdown-body .markdown-alert.markdown-alert-warning .markdown-alert-title {
+ color: #9a6700;
+}
+
+.markdown-body .markdown-alert.markdown-alert-tip {
+ border-left-color: #1a7f37;
+}
+
+.markdown-body .markdown-alert.markdown-alert-tip .markdown-alert-title {
+ color: #1a7f37;
+}
+
+.markdown-body .markdown-alert.markdown-alert-caution {
+ border-left-color: #cf222e;
+}
+
+.markdown-body .markdown-alert.markdown-alert-caution .markdown-alert-title {
+ color: #d1242f;
+}
+
+.markdown-body>*:first-child>.heading-element:first-child {
+ margin-top: 0 !important;
+}
+
+.markdown-body .highlight pre:has(+.zeroclipboard-container) {
+ min-height: 52px;
+}
+
diff --git a/src/frames/exportdialog.cpp b/src/frames/exportdialog.cpp
index f2ba33b..8dd8fbf 100644
--- a/src/frames/exportdialog.cpp
+++ b/src/frames/exportdialog.cpp
@@ -19,5 +19,9 @@ int ExportDialog::getResult()
{
return MARKDOWN;
}
+ else if (ui->pdfRadio->isChecked())
+ {
+ return PDF;
+ }
return PLAIN;
}
diff --git a/src/frames/exportdialog.h b/src/frames/exportdialog.h
index 2fb2536..124bf94 100644
--- a/src/frames/exportdialog.h
+++ b/src/frames/exportdialog.h
@@ -5,6 +5,7 @@
#define MARKDOWN 1
#define PLAIN 2
+#define PDF 3
namespace Ui {
class ExportDialog;
diff --git a/src/frames/exportdialog.ui b/src/frames/exportdialog.ui
index a6e9516..ef1aa82 100644
--- a/src/frames/exportdialog.ui
+++ b/src/frames/exportdialog.ui
@@ -35,10 +35,10 @@
- Qt::Horizontal
+ Qt::Orientation::Horizontal
- QDialogButtonBox::Cancel|QDialogButtonBox::Ok
+ QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok
@@ -61,7 +61,7 @@
30
- 60
+ 40
92
23
@@ -70,6 +70,19 @@
Text file
+
+
+
+ 30
+ 60
+ 92
+ 23
+
+
+
+ PDF file
+
+
diff --git a/src/frames/mainwindow.cpp b/src/frames/mainwindow.cpp
index b130f89..cfb2265 100644
--- a/src/frames/mainwindow.cpp
+++ b/src/frames/mainwindow.cpp
@@ -7,14 +7,22 @@
#include "renamedialog.h"
#include "exportdialog.h"
+#include
+
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
timer = new QTimer(this);
- updateViewThread = nullptr;
parser = std::make_shared();
+
+ // open stylesheet resource
+ QFile f(":/css/resources/style.css");
+ f.open(QFile::OpenModeFlag::ReadOnly);
+ style = f.readAll();
+ f.close();
+
connect(ui->actionAdd_folder, &QAction::triggered, this, &MainWindow::createFolder);
connect(ui->actionAdd, &QAction::triggered, this, &MainWindow::createNote);
connect(ui->actionSave, &QAction::triggered, this, &MainWindow::save);
@@ -32,10 +40,39 @@ MainWindow::MainWindow(QWidget *parent)
this->cfgmng = new ConfigManager();
updateListView();
connect(timer, &QTimer::timeout, this, &MainWindow::save);
+
+ // start render thread
+ threaddone = new bool(false);
+ queue = new QVector;
+ queueMutex = new QMutex();
+ updateViewThread = new std::thread([this](){
+ while (!*threaddone) {
+ queueMutex->lock();
+ if (queue->count() == 0) {
+ queueMutex->unlock();
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ continue;
+ }
+ QString content = (*queue)[0];
+ queue->pop_front();
+ queueMutex->unlock();
+ std::stringstream markdownInput(content.toStdString());
+ QString htmlOutput = "";
+ htmlOutput += QString::fromStdString(parser->Parse(markdownInput));
+ htmlOutput += "";
+ emit updateViewers(htmlOutput);
+ }
+ });
}
MainWindow::~MainWindow()
{
+ *threaddone = true;
+ updateViewThread->join();
+ delete queue;
+ delete queueMutex;
+ delete threaddone;
+ delete updateViewThread;
delete timer;
delete savemng;
delete ui;
@@ -309,6 +346,10 @@ void MainWindow::exportNote()
{
filter = "Markdown file (*.md)";
}
+ else if (fileType == PDF)
+ {
+ filter = "PDF file (*.pdf)";
+ }
QString fileName = QFileDialog::getSaveFileName(this, tr("Export note"), "", filter);
if (!fileName.isEmpty())
{
@@ -320,13 +361,27 @@ void MainWindow::exportNote()
{
fileName += ".txt";
}
- QFile *f = new QFile(fileName);
- if (f->open(QIODevice::WriteOnly))
+ else if (fileType == PDF && !fileName.endsWith(".pdf", Qt::CaseInsensitive))
{
- f->write(n->getContent().toUtf8());
- f->close();
+ fileName += ".pdf";
}
- delete f;
+
+ if (fileType == PDF)
+ {
+ ui->webEngineViewer->printToPdf(fileName);
+ }
+ else
+ {
+ QFile *f = new QFile(fileName);
+ if (f->open(QIODevice::WriteOnly))
+ {
+
+ f->write(n->getContent().toUtf8());
+ f->close();
+ }
+ delete f;
+ }
+
}
}
}
@@ -413,19 +468,12 @@ void MainWindow::updateListView()
void MainWindow::updateHTMLView()
{
- if (threadLock.tryLock()) {
- updateViewThread = new std::thread([this](){
- QString content = ui->plainTextEdit->toPlainText();
- std::stringstream markdownInput(content.toStdString());
- QString htmlOutput = QString::fromStdString(parser->Parse(markdownInput));
- emit updateViewers(htmlOutput);
- threadLock.unlock();
- });
- } else {
- QTimer::singleShot(200, [this]() {
- updateHTMLView();
- });
+ queueMutex->lock();
+ if (queue->count() > 4) {
+ queue->pop_front();
}
+ queue->append(ui->plainTextEdit->toPlainText());
+ queueMutex->unlock();
}
void MainWindow::clearAndDisableFields()
diff --git a/src/frames/mainwindow.h b/src/frames/mainwindow.h
index 4eb3d90..c3fd05d 100644
--- a/src/frames/mainwindow.h
+++ b/src/frames/mainwindow.h
@@ -61,9 +61,15 @@ private:
SaveManager *savemng;
ConfigManager *cfgmng;
QTimer *timer;
- std::thread *updateViewThread;
std::shared_ptr parser;
- QMutex threadLock;
+
+ QString style;
+
+ //shared between threads
+ QVector* queue;
+ QMutex* queueMutex;
+ bool* threaddone;
+ std::thread *updateViewThread;
void updateListView();
void clearAndDisableFields();
diff --git a/src/frames/mainwindow.ui b/src/frames/mainwindow.ui
index f900f2d..fee8737 100644
--- a/src/frames/mainwindow.ui
+++ b/src/frames/mainwindow.ui
@@ -77,7 +77,7 @@
QTabWidget::TabShape::Rounded
- 0
+ 2
diff --git a/static.qrc b/static.qrc
new file mode 100644
index 0000000..aa40dcb
--- /dev/null
+++ b/static.qrc
@@ -0,0 +1,5 @@
+
+
+ resources/style.css
+
+