From 97b4963fa7b53183999c3e535429a21b1ad33a86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Genov=C3=A9s?= Date: Sun, 14 Apr 2019 14:16:10 +0200 Subject: [PATCH 01/45] Add margin to recents popover --- data/ui/Recents.ui | 1 + 1 file changed, 1 insertion(+) diff --git a/data/ui/Recents.ui b/data/ui/Recents.ui index cfe3ada..4d918da 100644 --- a/data/ui/Recents.ui +++ b/data/ui/Recents.ui @@ -16,6 +16,7 @@ True False start + 6 recent_md_filter 20 False From c629137ed14f942a2c3cff4c4343165ec76fb092 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Genov=C3=A9s?= Date: Sun, 14 Apr 2019 18:20:02 +0200 Subject: [PATCH 02/45] update mockups --- screenshots/mockups_text.svg | 3057 ++++++++++++++++++++++++++-------- 1 file changed, 2333 insertions(+), 724 deletions(-) diff --git a/screenshots/mockups_text.svg b/screenshots/mockups_text.svg index d99093f..ecf8a66 100644 --- a/screenshots/mockups_text.svg +++ b/screenshots/mockups_text.svg @@ -16,7 +16,7 @@ viewBox="0 0 1034.14 578.502" id="svg8720" sodipodi:docname="mockups_text.svg" - inkscape:version="0.92.2 2405546, 2018-03-11" + inkscape:version="0.92.4 5da689c313, 2019-01-14" inkscape:export-filename="/home/manu/Documentos/Programacion/Uberwriter/uberwriter/screenshots/mockups.svg.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90"> @@ -29,21 +29,22 @@ guidetolerance="10" inkscape:pageopacity="0" inkscape:pageshadow="2" - inkscape:window-width="1366" - inkscape:window-height="741" + inkscape:window-width="1920" + inkscape:window-height="1015" id="namedview8722" showgrid="false" - inkscape:zoom="0.70710678" - inkscape:cx="623.96349" - inkscape:cy="469.33901" + inkscape:zoom="0.5" + inkscape:cx="693.82738" + inkscape:cy="260.3702" inkscape:window-x="1280" - inkscape:window-y="525" + inkscape:window-y="28" inkscape:window-maximized="1" - inkscape:current-layer="MainApp" + inkscape:current-layer="g8020-9-6" inkscape:snap-midpoints="true" inkscape:snap-object-midpoints="true" showguides="true" - inkscape:guide-bbox="true" /> + inkscape:guide-bbox="true" + inkscape:snap-page="true" /> @@ -52,7 +53,7 @@ image/svg+xml - + @@ -526,797 +527,2405 @@ id="radialGradient3834" xlink:href="#StandardGradient" inkscape:collect="always" /> + + + + + + - - - - - - - - - + id="MainApp" + class="sprite" + transform="translate(-0.585037,-0.838695)" + style="display:inline"> - + style="fill:#f2f2f2;stroke:#919191;stroke-width:1.17298734;stroke-linecap:square" + id="rect8155" + ry="9.8180552" + rx="11.3513" + height="102.54028" + width="1032.9708" + y="1.4261495" + x="1.1679047" /> - - - - - Words: 37 - Characters: 4576 - - + style="fill:#ededed;stroke:#919191;stroke-width:1.17318892;stroke-linecap:square" + id="rect8157" + height="526.01947" + width="1032.9171" + y="52.73592" + x="1.1679047" /> + + + + + + + + + + + + + + + Words: 37 + Characters: 4576 + + + UberWriter helps your textediting workflow - UberWriter helps your textediting workflow + # - # + It's a simple markdown editor that offers a It's a simple markdown editor that offers a **lot** of features.**lot** of Reasons to install:features.Reasons to install:Because you love markdown as much as I doBecause you like writting in a clutter free environmentBecause you love markdown as much as I doBecause you did not know that you only have always Because you like writting in a clutter free environmentBecause you did not know that you only have always searched for an editor like this - searched for an editor like this + ## ## 1.2.2.3. - - 3. + + UberWriter.md - UberWriter - - - - + font-size="40px" + letter-spacing="0px" + word-spacing="0px" + style="font-size:40px;line-height:25px;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#2e3436;stroke-width:1px" + xml:space="preserve" + id="text8307">UberWriter.md - UberWriter - - - - - + transform="translate(750.32102,2.8991699e-4)" + style="display:inline" + id="g2151-2"> + + transform="matrix(1.1729581,0,0,1.1729581,862.61636,17.659915)" + id="g1841" + style="fill:#3e4444"> + + + + + + + + + + + + + + transform="translate(595.76373,-679.08369)" + id="g8020"> + PopUp Tabs + + + + + + Save As ...ExportCopy HTMLPreferencesOpen TutorialPandoc HelpShortcutsAbout + + + + + transform="matrix(1.1873059,0,0,1.1873059,934.71856,89.206129)" + style="display:inline;fill:#454c4c;fill-opacity:1" + inkscape:label="Cross" + id="layer3"> + + + id="g13479" + transform="matrix(0.66419898,0,0,0.66419898,825.92506,97.285431)" + style="fill:#454c4c"> + + + + + + + + + + + + + + id="g13540" + transform="matrix(1.2284556,0,0,1.2284556,864.07305,91.778824)" + style="fill:#454c4c;fill-opacity:1"> + + + + + + + + + + + + + + + + Open + + + + + + + + + + + + + + + + + + Save + New + + - PopUp Tabs - + inkscape:groupmode="layer" + id="layer2" + inkscape:label="base" + style="display:inline"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + UberWriter.md - UberWriter + ~/Documents/examples/UberWriter.md + (save as) + + + + + + + + + + + + + + + + + + + + + + - - Save As ...ExportCopy HTMLPreferencesOpen TutorialPandoc HelpShortcutsAbout - - - - - - - - + id="tspan18034" + x="84.878777" + y="28.914589" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Cantarell;-inkscape-font-specification:Cantarell">Open + - - - - - - - - + id="g1674" + font-weight="400" + style="color:#000000;font-weight:400;font-family:sans-serif;white-space:normal;fill:#474747" + transform="translate(15.759644,15.640787)"> - - - - - - - - - - - + + + + Save + + - - - - - Open - - - - - - - - - - + id="g12007-1" + transform="translate(928.25074,16.108887)" + style="display:inline;fill:#2e3436"> + style="display:inline;fill:#2e3436" + id="g12009-5" + transform="translate(-140.0002,-645.96875)" + inkscape:label="status" /> + + + - - + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:1.55467153;marker:none;enable-background:new" + id="path12017-6" + d="m 146.50761,646.99554 c -3.02886,0 -5.51073,2.47905 -5.51073,5.50447 0,3.02541 2.48187,5.50446 5.51073,5.50446 3.02885,0 5.51072,-2.47905 5.51072,-5.50446 0,-3.02542 -2.48187,-5.50447 -5.51072,-5.50447 z m 0,2.00893 c 1.94735,0 3.49951,1.55039 3.49951,3.49554 0,1.94514 -1.55216,3.49553 -3.49951,3.49553 -1.94736,0 -3.49952,-1.55039 -3.49952,-3.49553 0,-1.94515 1.55216,-3.49554 3.49952,-3.49554 z" + inkscape:connector-curvature="0" /> + + + + + + + + + + + + + + + + + + + + Save + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Save As + PDF + + HTML + ODT + LaTeX + ... + + PopUp Tabs + + + + + + [Export]Copy HTMLPreferencesTutorialKeyboard ShortcutsAbout UberWriter + + + + + + + + + + + + + + + + + + + + + + + + PopUp Tabs + + Search + + - Save - New Date: Sun, 14 Apr 2019 20:15:46 +0200 Subject: [PATCH 03/45] add path to headerbar subtitle --- uberwriter/window.py | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/uberwriter/window.py b/uberwriter/window.py index ba784c7..2d33c54 100644 --- a/uberwriter/window.py +++ b/uberwriter/window.py @@ -117,6 +117,7 @@ class Window(Gtk.ApplicationWindow): # Setup text editor self.text_editor = TextEditor() + self.text_editor.add_events(Gdk.ModifierType.BUTTON1_MASK) self.text_editor.set_name('UberwriterEditor') self.get_style_context().add_class('uberwriter_window') @@ -474,14 +475,16 @@ class Window(Gtk.ApplicationWindow): # - gradient_offset, ha.props.value)) # global t, amount, initvadjustment target_pos = -1 - if self.focusmode: + if self.focusmode and (self.text_editor.get_events() != 4195088): # print("pos: %i > %i" % (pos, ha.props.page_size * 0.5)) + + print(self.text_editor.get_events() == Gdk.ModifierType.BUTTON1_MASK) if pos != (ha.props.page_size * 0.5): target_pos = pos_y - (ha.props.page_size * 0.5) - elif pos > ha.props.page_size - gradient_offset - 60: - target_pos = pos_y - ha.props.page_size + gradient_offset + 40 - elif pos < gradient_offset: - target_pos = pos_y - gradient_offset + elif pos > ha.props.page_size - gradient_offset - 60: + target_pos = pos_y - ha.props.page_size + gradient_offset + 40 + elif pos < gradient_offset: + target_pos = pos_y - gradient_offset self.smooth_scroll_data = { 'target_pos': target_pos, 'source_pos': ha.props.value, @@ -602,7 +605,7 @@ class Window(Gtk.ApplicationWindow): self.set_filename(filename) self.set_headerbar_title( - os.path.basename(filename) + self.title_end) + os.path.basename(filename) + self.title_end, filename) self.did_change = False filechooser.destroy() @@ -643,7 +646,7 @@ class Window(Gtk.ApplicationWindow): self.set_filename(filename) self.set_headerbar_title( - os.path.basename(filename) + self.title_end) + os.path.basename(filename) + self.title_end, filename) try: self.recent_manager.add_item(filename) @@ -921,7 +924,7 @@ class Window(Gtk.ApplicationWindow): if filename: if filename.startswith('file://'): - filename = filename[7:] + filename = filename[8:] filename = urllib.parse.unquote_plus(filename) try: if not os.path.exists(filename): @@ -933,7 +936,7 @@ class Window(Gtk.ApplicationWindow): self.markup_buffer.markup_buffer(0) self.set_headerbar_title( - os.path.basename(filename) + self.title_end) + os.path.basename(filename) + self.title_end, filename) self.text_editor.undo_stack = [] self.text_editor.redo_stack = [] self.set_filename(filename) @@ -1105,11 +1108,13 @@ class Window(Gtk.ApplicationWindow): # Clean up code for saving application state should be added here. Gtk.main_quit() - def set_headerbar_title(self, title): + def set_headerbar_title(self, title, subtitle=""): """set the desired headerbar title """ self.headerbar.hb.props.title = title self.fs_headerbar.hb.props.title = title + self.headerbar.hb.props.subtitle = subtitle + self.fs_headerbar.hb.props.subtitle = subtitle self.set_title(title) def set_filename(self, filename=None): From 9ae1eaedda069ec50e909be9abdf10cecf204838 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Genov=C3=A9s?= Date: Sun, 14 Apr 2019 21:14:26 +0200 Subject: [PATCH 04/45] show symbolic icon in appmenu --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index 8671284..dbd88c4 100644 --- a/setup.py +++ b/setup.py @@ -78,6 +78,7 @@ setup( (app_prefix + 'bin', ['bin/uberwriter']), (app_prefix + 'share/glib-2.0/schemas', ['data/de.wolfvollprecht.UberWriter.gschema.xml']), (app_prefix + 'share/icons/hicolor/scalable/apps', ['data/media/de.wolfvollprecht.UberWriter.svg']), + (app_prefix + 'share/icons/hicolor/symbolic/apps', ['data/media/de.wolfvollprecht.UberWriter-symbolic.svg']), (app_prefix + 'share/applications', ['de.wolfvollprecht.UberWriter.desktop']), (app_prefix + 'share/uberwriter/data/ui', extra_files_ui), (app_prefix + 'share/uberwriter/data/media', extra_files_media), From 96865fbefc9e5f2348b76a2f9ad15ec5e5d5a7a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Genov=C3=A9s?= Date: Wed, 17 Apr 2019 20:45:17 +0200 Subject: [PATCH 05/45] mockup update --- screenshots/mockups_text.svg | 366 +++++++++++++++++++++++++---------- 1 file changed, 261 insertions(+), 105 deletions(-) diff --git a/screenshots/mockups_text.svg b/screenshots/mockups_text.svg index ecf8a66..6b78ad5 100644 --- a/screenshots/mockups_text.svg +++ b/screenshots/mockups_text.svg @@ -30,14 +30,14 @@ inkscape:pageopacity="0" inkscape:pageshadow="2" inkscape:window-width="1920" - inkscape:window-height="1015" + inkscape:window-height="1016" id="namedview8722" showgrid="false" inkscape:zoom="0.5" inkscape:cx="693.82738" inkscape:cy="260.3702" inkscape:window-x="1280" - inkscape:window-y="28" + inkscape:window-y="27" inkscape:window-maximized="1" inkscape:current-layer="g8020-9-6" inkscape:snap-midpoints="true" @@ -560,7 +560,10 @@ id="MainApp" class="sprite" transform="translate(-0.585037,-0.838695)" - style="display:inline"> + style="display:inline" + inkscape:export-filename="/home/manu/mockup.png" + inkscape:export-xdpi="300.02115" + inkscape:export-ydpi="300.02115"> + ry="9" + inkscape:export-filename="/home/manu/mockup.png" + inkscape:export-xdpi="300.02115" + inkscape:export-ydpi="300.02115" /> + inkscape:export-filename="/home/manu/mockup.png" + inkscape:export-xdpi="300.02115" + inkscape:export-ydpi="300.02115" /> + style="display:inline;fill:#f6f5f4;fill-opacity:1;stroke:#919191;stroke-width:0.9999997;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + inkscape:export-filename="/home/manu/mockup.png" + inkscape:export-xdpi="300.02115" + inkscape:export-ydpi="300.02115" /> + style="display:inline;fill:#888a85" + inkscape:export-filename="/home/manu/mockup.png" + inkscape:export-xdpi="300.02115" + inkscape:export-ydpi="300.02115"> + inkscape:export-filename="/home/manu/mockup.png" + inkscape:export-xdpi="300.02115" + inkscape:export-ydpi="300.02115" /> + inkscape:export-filename="/home/manu/mockup.png" + inkscape:export-xdpi="300.02115" + inkscape:export-ydpi="300.02115" /> + style="display:inline;fill:#2e3436" + inkscape:export-filename="/home/manu/mockup.png" + inkscape:export-xdpi="300.02115" + inkscape:export-ydpi="300.02115"> + transform="translate(-3.7403556,-259.85921)" + inkscape:export-filename="/home/manu/mockup.png" + inkscape:export-xdpi="300.02115" + inkscape:export-ydpi="300.02115"> + inkscape:label="open-menu" + inkscape:export-filename="/home/manu/mockup.png" + inkscape:export-xdpi="300.02115" + inkscape:export-ydpi="300.02115"> + inkscape:export-filename="/home/manu/mockup.png" + inkscape:export-xdpi="300.02115" + inkscape:export-ydpi="300.02115" /> + style="display:inline;fill:#2e3436" + inkscape:export-filename="/home/manu/mockup.png" + inkscape:export-xdpi="300.02115" + inkscape:export-ydpi="300.02115"> + transform="translate(888.25961,15.925787)" + inkscape:export-filename="/home/manu/mockup.png" + inkscape:export-xdpi="300.02115" + inkscape:export-ydpi="300.02115"> + sodipodi:nodetypes="sccccssss" + inkscape:export-filename="/home/manu/mockup.png" + inkscape:export-xdpi="300.02115" + inkscape:export-ydpi="300.02115" /> Open + transform="translate(15.759644,15.640787)" + inkscape:export-filename="/home/manu/mockup.png" + inkscape:export-xdpi="300.02115" + inkscape:export-ydpi="300.02115"> + style="fill:#2e3436" + inkscape:export-filename="/home/manu/mockup.png" + inkscape:export-xdpi="300.02115" + inkscape:export-ydpi="300.02115" /> + sodipodi:nodetypes="sccccssss" + inkscape:export-filename="/home/manu/mockup.png" + inkscape:export-xdpi="300.02115" + inkscape:export-ydpi="300.02115" /> + style="display:inline;fill:#2e3436" + inkscape:export-filename="/home/manu/mockup.png" + inkscape:export-xdpi="300.02115" + inkscape:export-ydpi="300.02115" /> + inkscape:export-filename="/home/manu/mockup.png" + inkscape:export-xdpi="300.02115" + inkscape:export-ydpi="300.02115" /> + style="display:inline;fill:#2e3436" + inkscape:export-filename="/home/manu/mockup.png" + inkscape:export-xdpi="300.02115" + inkscape:export-ydpi="300.02115"> + transform="translate(928.26063,16.139803)" + inkscape:export-filename="/home/manu/mockup.png" + inkscape:export-xdpi="300.02115" + inkscape:export-ydpi="300.02115"> + sodipodi:nodetypes="sccccssss" + inkscape:export-filename="/home/manu/mockup.png" + inkscape:export-xdpi="300.02115" + inkscape:export-ydpi="300.02115" /> + transform="translate(241.06217,313.00195)" + inkscape:export-filename="/home/manu/mockup.png" + inkscape:export-xdpi="300.02115" + inkscape:export-ydpi="300.02115"> + id="g25370" + inkscape:export-filename="/home/manu/mockup.png" + inkscape:export-xdpi="300.02115" + inkscape:export-ydpi="300.02115"> + transform="translate(1167.9186,15.753282)" + inkscape:export-filename="/home/manu/mockup.png" + inkscape:export-xdpi="300.02115" + inkscape:export-ydpi="300.02115"> + style="display:inline;fill:#454c4c" + inkscape:export-filename="/home/manu/mockup.png" + inkscape:export-xdpi="300.02115" + inkscape:export-ydpi="300.02115"> + inkscape:connector-curvature="0" + inkscape:export-filename="/home/manu/mockup.png" + inkscape:export-xdpi="300.02115" + inkscape:export-ydpi="300.02115" /> + inkscape:export-filename="/home/manu/mockup.png" + inkscape:export-xdpi="300.02115" + inkscape:export-ydpi="300.02115" /> + style="display:inline;fill:#2e3436" + inkscape:export-filename="/home/manu/mockup.png" + inkscape:export-xdpi="300.02115" + inkscape:export-ydpi="300.02115"> + inkscape:export-filename="/home/manu/mockup.png" + inkscape:export-xdpi="300.02115" + inkscape:export-ydpi="300.02115" /> + inkscape:label="open-menu" + inkscape:export-filename="/home/manu/mockup.png" + inkscape:export-xdpi="300.02115" + inkscape:export-ydpi="300.02115"> + transform="translate(1278.7098,16.13983)" + inkscape:export-filename="/home/manu/mockup.png" + inkscape:export-xdpi="300.02115" + inkscape:export-ydpi="300.02115"> + id="g25370-7" + inkscape:export-filename="/home/manu/mockup.png" + inkscape:export-xdpi="300.02115" + inkscape:export-ydpi="300.02115"> + transform="translate(1167.9186,68.753284)" + inkscape:export-filename="/home/manu/mockup.png" + inkscape:export-xdpi="300.02115" + inkscape:export-ydpi="300.02115"> + style="display:inline;fill:#454c4c" + inkscape:export-filename="/home/manu/mockup.png" + inkscape:export-xdpi="300.02115" + inkscape:export-ydpi="300.02115"> + inkscape:connector-curvature="0" + inkscape:export-filename="/home/manu/mockup.png" + inkscape:export-xdpi="300.02115" + inkscape:export-ydpi="300.02115" /> + inkscape:export-filename="/home/manu/mockup.png" + inkscape:export-xdpi="300.02115" + inkscape:export-ydpi="300.02115" /> + inkscape:label="open-menu" + inkscape:export-filename="/home/manu/mockup.png" + inkscape:export-xdpi="300.02115" + inkscape:export-ydpi="300.02115"> + transform="translate(1278.7098,69.139832)" + inkscape:export-filename="/home/manu/mockup.png" + inkscape:export-xdpi="300.02115" + inkscape:export-ydpi="300.02115"> + sodipodi:nodetypes="scccssssssss" + inkscape:export-filename="/home/manu/mockup.png" + inkscape:export-xdpi="300.02115" + inkscape:export-ydpi="300.02115" /> + style="fill:none;fill-rule:evenodd;stroke:#a7aba7;stroke-width:0.99999994px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + inkscape:export-filename="/home/manu/mockup.png" + inkscape:export-xdpi="300.02115" + inkscape:export-ydpi="300.02115" /> + id="g8020-9" + inkscape:export-filename="/home/manu/mockup.png" + inkscape:export-xdpi="300.02115" + inkscape:export-ydpi="300.02115"> PopUp Tabs + style="display:inline;fill:#454c4c" + inkscape:export-filename="/home/manu/mockup.png" + inkscape:export-xdpi="300.02115" + inkscape:export-ydpi="300.02115"> + inkscape:connector-curvature="0" + inkscape:export-filename="/home/manu/mockup.png" + inkscape:export-xdpi="300.02115" + inkscape:export-ydpi="300.02115" /> + transform="translate(993.66842,93.37378)" + inkscape:export-filename="/home/manu/mockup.png" + inkscape:export-xdpi="300.02115" + inkscape:export-ydpi="300.02115"> + style="display:inline;fill:#f2f2f2;fill-opacity:1;stroke:#a7aba7;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + inkscape:export-filename="/home/manu/mockup.png" + inkscape:export-xdpi="300.02115" + inkscape:export-ydpi="300.02115" /> + inkscape:connector-curvature="0" + inkscape:export-filename="/home/manu/mockup.png" + inkscape:export-xdpi="300.02115" + inkscape:export-ydpi="300.02115" /> From b55f4dbecd96b215f66b6d2daefd55b28b245b37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Genov=C3=A9s?= Date: Sun, 12 May 2019 21:26:44 +0200 Subject: [PATCH 06/45] Added @goncalossilva to the contributor's list --- data/ui/About.ui | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/data/ui/About.ui b/data/ui/About.ui index c5b788c..c0976ee 100644 --- a/data/ui/About.ui +++ b/data/ui/About.ui @@ -13,9 +13,9 @@ http://uberwriter.github.io/uberwriter Uberwriter website Wolf Vollprecht <w.vollprecht@gmail.com> -Manuel Genovés <manuel.genoves@gmail.com> - -Andrea Somaini (Italian) +Manuel Genovés <manuel.genoves@gmail.com> +Gonçalo Silva <goncalossilva@gmail.com> + Andrea Somaini (Italian) Daniel Artfors (Swedish) shorez (German) TomBoss (French) From 10f98f35b82ad48641977d0be8a2188c7cbf51d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Genov=C3=A9s?= Date: Sun, 10 Nov 2019 19:02:22 +0100 Subject: [PATCH 07/45] fix filename path --- uberwriter/main_window.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uberwriter/main_window.py b/uberwriter/main_window.py index 1587d5f..5ac71f1 100644 --- a/uberwriter/main_window.py +++ b/uberwriter/main_window.py @@ -442,7 +442,7 @@ class MainWindow(StyledWindow): if filename: if filename.startswith('file://'): - filename = filename[8:] + filename = filename[7:] filename = urllib.parse.unquote_plus(filename) self.text_view.clear() try: From 0e2f731ff48a3a558f854eeb06314684dfa8fb6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Genov=C3=A9s?= Date: Mon, 11 Nov 2019 01:27:39 +0100 Subject: [PATCH 08/45] Use a .ui file to define the headerbar This makes all the headerbar code more readable and easier to tweak --- data/uberwriter.gresource.xml | 1 + data/ui/Headerbar.ui | 132 ++++++++++++++++++++++++++++++++++ data/ui/Recents.ui | 5 +- data/ui/Window.ui | 10 +-- uberwriter/headerbars.py | 122 ++++++++++--------------------- 5 files changed, 177 insertions(+), 93 deletions(-) create mode 100644 data/ui/Headerbar.ui diff --git a/data/uberwriter.gresource.xml b/data/uberwriter.gresource.xml index ea9446b..c85d3be 100644 --- a/data/uberwriter.gresource.xml +++ b/data/uberwriter.gresource.xml @@ -9,6 +9,7 @@ ui/Recents.ui ui/Shortcuts.ui ui/Window.ui + ui/Headerbar.ui About.ui diff --git a/data/ui/Headerbar.ui b/data/ui/Headerbar.ui new file mode 100644 index 0000000..61e4843 --- /dev/null +++ b/data/ui/Headerbar.ui @@ -0,0 +1,132 @@ + + + + + + True + False + view-restore-symbolic + + + True + False + system-search-symbolic + + + True + False + True + + + New + True + True + True + app.new + + + + + True + False + + + Open + True + True + True + app.open + + + False + True + 0 + + + + + True + True + True + Open Recent + app.on_open_recent + + + + + + False + True + 1 + + + + + + 1 + + + + + True + True + True + app.fullscreen + exit_fs_icon + + + end + 1 + + + + + True + True + True + + + True + False + Menu + open-menu-symbolic + + + + + end + 2 + + + + + True + True + True + Find + app.search + search_icon + True + + + end + 3 + + + + + Save + True + True + True + app.save + + + end + 4 + + + + diff --git a/data/ui/Recents.ui b/data/ui/Recents.ui index 06bc23a..a7b237c 100644 --- a/data/ui/Recents.ui +++ b/data/ui/Recents.ui @@ -17,7 +17,10 @@ True False start - 6 + 6 + 6 + 6 + 6 recent_md_filter 20 False diff --git a/data/ui/Window.ui b/data/ui/Window.ui index 5d17ee0..16fd925 100644 --- a/data/ui/Window.ui +++ b/data/ui/Window.ui @@ -414,7 +414,6 @@ 1 - True False start @@ -423,14 +422,7 @@ False start - - True - False - start - - - - + diff --git a/uberwriter/headerbars.py b/uberwriter/headerbars.py index a70af47..19991ae 100644 --- a/uberwriter/headerbars.py +++ b/uberwriter/headerbars.py @@ -31,9 +31,17 @@ class MainHeaderbar: #pylint: disable=too-few-public-methods """ def __init__(self, app): - self.hb = Gtk.HeaderBar().new() #pylint: disable=C0103 - self.hb.props.show_close_button = True - self.hb.get_style_context().add_class("titlebar") + + builder = Gtk.Builder() + builder.add_from_resource( + "/de/wolfvollprecht/UberWriter/ui/Headerbar.ui") + + self.hb = builder.get_object("Headerbar") + + self.menu_button = builder.get_object("menu_button") + self.recents_button = builder.get_object("recents_button") + + add_menus(self, app) self.hb_revealer = Gtk.Revealer(name='titlebar-revealer') self.hb_revealer.add(self.hb) @@ -47,9 +55,6 @@ class MainHeaderbar: #pylint: disable=too-few-public-methods self.hb_container.add(self.hb_revealer) self.hb_container.show() - self.btns = main_buttons(app) - pack_main_buttons(self.hb, self.btns) - self.hb.show_all() @@ -81,35 +86,35 @@ class FullscreenHeaderbar: """Sets up and manages the fullscreen headerbar and his events """ - def __init__(self, builder, app): - self.events = builder.get_object("FullscreenEventbox") - self.revealer = builder.get_object( - "FullscreenHbPlaceholder") - self.revealer.show() - self.revealer.set_reveal_child(False) + def __init__(self, fs_builder, app): - self.hb = builder.get_object("FullscreenHeaderbar") #pylint: disable=C0103 - self.hb.get_style_context().add_class("titlebar") - self.hb.show() - self.events.hide() - - self.btns = main_buttons(app) - - fs_btn_exit = Gtk.Button().new_from_icon_name("view-restore-symbolic", - Gtk.IconSize.BUTTON) - fs_btn_exit.set_tooltip_text(_("Exit Fullscreen")) - fs_btn_exit.set_action_name("app.fullscreen") - - pack_main_buttons(self.hb, self.btns, fs_btn_exit) + builder = Gtk.Builder() + builder.add_from_resource( + "/de/wolfvollprecht/UberWriter/ui/Headerbar.ui") + self.hb = builder.get_object("Headerbar") + self.hb.set_show_close_button(False) self.hb.show_all() + self.menu_button = builder.get_object("menu_button") + self.recents_button = builder.get_object("recents_button") + + self.exit_fs_button = builder.get_object("exit_fs_button") + self.exit_fs_button.set_visible(True) + + add_menus(self, app) + + self.events = fs_builder.get_object("FullscreenEventbox") + self.revealer = fs_builder.get_object( + "FullscreenHbPlaceholder") + self.revealer.add(self.hb) + # this is a little tricky # we show hb when the cursor enters an area of 1 px at the top of the window # as the hb is shown the height of the eventbox grows to accomodate it self.events.connect('enter_notify_event', self.show_fs_hb) self.events.connect('leave_notify_event', self.hide_fs_hb) - self.btns.menu.get_popover().connect('closed', self.hide_fs_hb) + self.menu_button.get_popover().connect('closed', self.hide_fs_hb) def show_fs_hb(self, _widget, _data=None): """show headerbar of the fullscreen mode @@ -119,34 +124,24 @@ class FullscreenHeaderbar: def hide_fs_hb(self, _widget, _data=None): """hide headerbar of the fullscreen mode """ - if self.btns.menu.get_active(): + if self.menu_button.get_active(): pass else: self.revealer.set_reveal_child(False) -def main_buttons(app): - """constructor for the headerbar buttons +def add_menus(headerbar, app): - Returns: - [NamedTupple] -- tupple of Gtk.Buttons - """ - - Button = namedtuple("Button", "new open_recent save search menu") - btn = Button(Gtk.Button().new_with_label(_("New")), - Gtk.Box().new(0, 0), - Gtk.Button().new_with_label(_("Save")), - Gtk.Button().new_from_icon_name("system-search-symbolic", - Gtk.IconSize.BUTTON), - Gtk.MenuButton().new()) + # Add menu model to the menu button builder_window_menu = Gtk.Builder() builder_window_menu.add_from_resource( "/de/wolfvollprecht/UberWriter/ui/Menu.ui") model = builder_window_menu.get_object("Menu") - open_button = Gtk.Button().new_with_label(_("Open")) - open_button.set_action_name("app.open") + headerbar.menu_button.set_menu_model(model) + + # Add recents menu to the open recents button recents_builder = Gtk.Builder() recents_builder.add_from_resource( @@ -159,44 +154,5 @@ def main_buttons(app): recents_wd = recents_builder.get_object("recent_md_widget") recents_wd.connect('item-activated', app.on_open_recent) - recents_button = Gtk.MenuButton().new() - recents_button.set_image(Gtk.Image.new_from_icon_name("pan-down-symbolic", - Gtk.IconSize.BUTTON)) - recents_button.set_tooltip_text(_("Open Recent")) - recents_button.set_popover(recents) - - btn.open_recent.get_style_context().add_class("linked") - btn.open_recent.pack_start(open_button, False, False, 0) - btn.open_recent.pack_end(recents_button, False, False, 0) - - btn.search.set_tooltip_text(_("Find")) - btn.menu.set_tooltip_text(_("Menu")) - btn.menu.set_image(Gtk.Image.new_from_icon_name("open-menu-symbolic", - Gtk.IconSize.BUTTON)) - btn.menu.set_use_popover(True) - btn.menu.set_menu_model(model) - btn.new.set_action_name("app.new") - btn.save.set_action_name("app.save") - btn.search.set_action_name("app.search") - - return btn - - -def pack_main_buttons(headerbar, btn, btn_exit=None): - """Pack the given buttons in the given headerbar - - Arguments: - headerbar {Gtk.HeaderBar} -- The headerbar where to put the buttons - btn {Tupple of Gtk.Buttons} -- The buttons to pack - - Keyword Arguments: - btn_exit {Gtk.Button} -- Optional exit fullscreen button (default: {None}) - """ - - headerbar.pack_start(btn.new) - headerbar.pack_start(btn.open_recent) - if btn_exit: - headerbar.pack_end(btn_exit) - headerbar.pack_end(btn.menu) - headerbar.pack_end(btn.search) - headerbar.pack_end(btn.save) + headerbar.recents_button.set_popover(recents) + headerbar.recents_button.set_sensitive(True) From f091e5ac1a466a6fa5d1a09ebf68638bf01c3219 Mon Sep 17 00:00:00 2001 From: Manuel Genoves Date: Thu, 14 Nov 2019 12:45:54 +0100 Subject: [PATCH 09/45] update gitignore --- .gitignore | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/.gitignore b/.gitignore index 9300151..8be02eb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,26 +1,8 @@ -build/lib.linux-x86_64-2.7 *.pyc __pycache__/ build/ -_build/ -debian/uberwriter/DEBIAN -debian/uberwriter/opt -debian/uberwriter/usr -flatpak/* -!flatpak/uberwriter.json -!flatpak/de.wolfvollprecht.UberWriter.* -!flatpak/flatpak_texlive.json -!flatpak/texlive_install.sh -!flatpak/python3-enchant.json -!flatpak/python3-packages.json -*.py~ -data/ui/shortcut_handlers -*.ui~ +*.*~ .vscode/ .idea/ -*.glade~ -dist/uberwriter-2.0b0-py3.7.egg builddir/* -dist/ -uberwriter.egg-info -build-aux/flatpak/.flatpak-builder/* \ No newline at end of file +build-aux/* \ No newline at end of file From b5260e3906b03784e451556d1b7a8ae9987a68ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Genov=C3=A9s?= Date: Sat, 23 Nov 2019 02:08:47 +0100 Subject: [PATCH 10/45] add curved corners for focus mode --- data/media/css/gtk/base.css | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/data/media/css/gtk/base.css b/data/media/css/gtk/base.css index 810bc9c..cc3176f 100644 --- a/data/media/css/gtk/base.css +++ b/data/media/css/gtk/base.css @@ -27,6 +27,19 @@ caret-color: @theme_fg_color; } +.uberwriter-window.focus:not(.tiled):not(.tiled-top):not(.tiled-bottom):not(.tiled-left):not(.tiled-right):not(.maximized):not(.fullscreen) { + border-top-left-radius: 8px; + border-top-right-radius: 8px; +} + +.uberwriter-window.focus:not(.tiled):not(.tiled-top):not(.tiled-bottom):not(.tiled-left):not(.tiled-right):not(.maximized):not(.fullscreen):dir(ltr) scrollbar { + border-top-right-radius: 8px; +} + +.uberwriter-window.focus:not(.tiled):not(.tiled-top):not(.tiled-bottom):not(.tiled-left):not(.tiled-right):not(.maximized):not(.fullscreen):dir(rtl) scrollbar { + border-top-left-radius: 8px; +} + #titlebar-revealer { padding: 0; } From f766c3703d70c1f9218c64ae19e85c803ea5bae8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Genov=C3=A9s?= Date: Sat, 23 Nov 2019 02:09:22 +0100 Subject: [PATCH 11/45] add revealer to the headerbar default class --- data/ui/Headerbar.ui | 191 +++++++++++++++++++++++-------------------- 1 file changed, 101 insertions(+), 90 deletions(-) diff --git a/data/ui/Headerbar.ui b/data/ui/Headerbar.ui index 61e4843..0a2f6aa 100644 --- a/data/ui/Headerbar.ui +++ b/data/ui/Headerbar.ui @@ -12,121 +12,132 @@ False system-search-symbolic - + + titlebar-revealer True False - True + start + slide-up + 750 + True + - - New - True - True - True - app.new - - - - + True False - Open + New True True True - app.open + app.new - - False - True - 0 - - + True - True - True - Open Recent - app.on_open_recent + False - + + Open + True + True + True + app.open + + + False + True + 0 + + + + True + True + True + Open Recent + app.on_open_recent + + + + + + False + True + 1 + + + - False - True 1 - - - - 1 - - - - - True - True - True - app.fullscreen - exit_fs_icon - - - end - 1 - - - - - True - True - True - - True - False - Menu - open-menu-symbolic + + True + True + True + app.fullscreen + exit_fs_icon + + end + 1 + + + + + True + True + True + + + True + False + Menu + open-menu-symbolic + + + + + end + 2 + + + + + True + True + True + Find + app.search + search_icon + True + + + end + 3 + + + + + Save + True + True + True + app.save + + + end + 4 + - - end - 2 - - - - - True - True - True - Find - app.search - search_icon - True - - - end - 3 - - - - - Save - True - True - True - app.save - - - end - 4 - From 8ac8728e3b900928f57cff46800eb4d16e8ae57b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Genov=C3=A9s?= Date: Sat, 23 Nov 2019 02:11:32 +0100 Subject: [PATCH 12/45] implement hack to fade away the headerbar --- data/ui/Window.ui | 9 +- uberwriter/headerbars.py | 174 ++++++++++++++++++++++---------------- uberwriter/main_window.py | 59 ++++++++++++- uberwriter/text_view.py | 19 +++-- 4 files changed, 169 insertions(+), 92 deletions(-) diff --git a/data/ui/Window.ui b/data/ui/Window.ui index 16fd925..466d1b3 100644 --- a/data/ui/Window.ui +++ b/data/ui/Window.ui @@ -417,14 +417,7 @@ False start - - True - False - start - - - - + diff --git a/uberwriter/headerbars.py b/uberwriter/headerbars.py index 19991ae..ba81346 100644 --- a/uberwriter/headerbars.py +++ b/uberwriter/headerbars.py @@ -16,46 +16,121 @@ """Manage all the headerbars related stuff """ -from collections import namedtuple -from gettext import gettext as _ - import gi gi.require_version('Gtk', '3.0') -from gi.repository import Gtk +from gi.repository import Gtk, GLib from uberwriter.helpers import get_descendant -class MainHeaderbar: #pylint: disable=too-few-public-methods +class BaseHeaderbar: + """Base class for all headerbars + """ + def __init__(self, app): + + self.builder = Gtk.Builder() + self.builder.add_from_resource( + "/de/wolfvollprecht/UberWriter/ui/Headerbar.ui") + + self.hb = self.builder.get_object("Headerbar") + self.hb_revealer = self.builder.get_object("titlebar_revealer") + + self.menu_button = self.builder.get_object("menu_button") + self.recents_button = self.builder.get_object("recents_button") + + +class MainHeaderbar(BaseHeaderbar): # pylint: disable=too-few-public-methods """Sets up the main application headerbar """ def __init__(self, app): - builder = Gtk.Builder() - builder.add_from_resource( - "/de/wolfvollprecht/UberWriter/ui/Headerbar.ui") + BaseHeaderbar.__init__(self, app) - self.hb = builder.get_object("Headerbar") - - self.menu_button = builder.get_object("menu_button") - self.recents_button = builder.get_object("recents_button") + self.hb.set_show_close_button(True) add_menus(self, app) - self.hb_revealer = Gtk.Revealer(name='titlebar-revealer') - self.hb_revealer.add(self.hb) - self.hb_revealer.props.transition_duration = 750 - self.hb_revealer.props.transition_type = Gtk.RevealerTransitionType.CROSSFADE - self.hb_revealer.show() + self.hb_revealer.props.transition_duration = 0 + + +class FullscreenHeaderbar(BaseHeaderbar): + """Sets up and manages the fullscreen headerbar and his events + """ + + def __init__(self, fs_builder, app): + + BaseHeaderbar.__init__(self, app) + + self.hb.set_show_close_button(False) + + self.exit_fs_button = self.builder.get_object("exit_fs_button") + self.exit_fs_button.set_visible(True) + + add_menus(self, app) + + self.events = fs_builder.get_object("FullscreenEventbox") + self.events.add(self.hb_revealer) + + # this is a little tricky + # we show hb when the cursor enters an area of 1px at the top + # as the hb is shown the height of the eventbox grows to accomodate it + self.events.connect('enter_notify_event', self.show_fs_hb) + self.events.connect('leave_notify_event', self.hide_fs_hb) + self.menu_button.get_popover().connect('closed', self.hide_fs_hb) + + def show_fs_hb(self, _widget, _data=None): + """show headerbar of the fullscreen mode + """ self.hb_revealer.set_reveal_child(True) - self.hb_container = Gtk.Frame(name='titlebar-container') - self.hb_container.set_shadow_type(Gtk.ShadowType.NONE) - self.hb_container.add(self.hb_revealer) - self.hb_container.show() + def hide_fs_hb(self, _widget, _data=None): + """hide headerbar of the fullscreen mode + """ + if self.menu_button.get_active(): + pass + else: + self.hb_revealer.set_reveal_child(False) - self.hb.show_all() + +class DummyHeaderbar(BaseHeaderbar): + """Sets up and manages the dummy headerbar wich fades away when entering + the free-distracting mode + """ + + def __init__(self, app): + + BaseHeaderbar.__init__(self, app) + + self.hb.set_show_close_button(True) + self.hb_revealer.set_transition_type( + Gtk.RevealerTransitionType.CROSSFADE) + self.hb_revealer.set_reveal_child(False) + + self.menu_button.set_sensitive(True) + self.recents_button.set_sensitive(True) + + def show_dm_hb(self): + """show dummy headerbar: + It appears instantly to inmediatly fade away + """ + self.hb_revealer.set_transition_duration(0) + self.hb_revealer.set_reveal_child(True) + self.hb_revealer.set_transition_duration(600) + self.hb_revealer.set_reveal_child(False) + + def hide_dm_hb(self): + """hide dummy headerbar + It appears slowly to inmediatly dissapear + """ + self.hb_revealer.set_transition_duration(400) + self.hb_revealer.set_reveal_child(True) + GLib.timeout_add(400, self.hide_dm_hb_with_wait) + + def hide_dm_hb_with_wait(self): + self.hb_revealer.set_transition_duration(0) + self.hb_revealer.set_reveal_child(False) + return False class PreviewHeaderbar: @@ -67,10 +142,11 @@ class PreviewHeaderbar: self.hb.props.show_close_button = True self.hb.get_style_context().add_class("titlebar") - self.hb_revealer = Gtk.Revealer(name="titlebar-revealer") + self.hb_revealer = Gtk.Revealer(name="titlebar-revealer-pv") self.hb_revealer.add(self.hb) self.hb_revealer.props.transition_duration = 750 - self.hb_revealer.props.transition_type = Gtk.RevealerTransitionType.CROSSFADE + self.hb_revealer.set_transition_type( + Gtk.RevealerTransitionType.CROSSFADE) self.hb_revealer.show() self.hb_revealer.set_reveal_child(True) @@ -82,55 +158,9 @@ class PreviewHeaderbar: self.hb.show_all() -class FullscreenHeaderbar: - """Sets up and manages the fullscreen headerbar and his events - """ - - def __init__(self, fs_builder, app): - - builder = Gtk.Builder() - builder.add_from_resource( - "/de/wolfvollprecht/UberWriter/ui/Headerbar.ui") - - self.hb = builder.get_object("Headerbar") - self.hb.set_show_close_button(False) - self.hb.show_all() - - self.menu_button = builder.get_object("menu_button") - self.recents_button = builder.get_object("recents_button") - - self.exit_fs_button = builder.get_object("exit_fs_button") - self.exit_fs_button.set_visible(True) - - add_menus(self, app) - - self.events = fs_builder.get_object("FullscreenEventbox") - self.revealer = fs_builder.get_object( - "FullscreenHbPlaceholder") - self.revealer.add(self.hb) - - # this is a little tricky - # we show hb when the cursor enters an area of 1 px at the top of the window - # as the hb is shown the height of the eventbox grows to accomodate it - self.events.connect('enter_notify_event', self.show_fs_hb) - self.events.connect('leave_notify_event', self.hide_fs_hb) - self.menu_button.get_popover().connect('closed', self.hide_fs_hb) - - def show_fs_hb(self, _widget, _data=None): - """show headerbar of the fullscreen mode - """ - self.revealer.set_reveal_child(True) - - def hide_fs_hb(self, _widget, _data=None): - """hide headerbar of the fullscreen mode - """ - if self.menu_button.get_active(): - pass - else: - self.revealer.set_reveal_child(False) - - def add_menus(headerbar, app): + """ Add menu models to hb buttons + """ # Add menu model to the menu button diff --git a/uberwriter/main_window.py b/uberwriter/main_window.py index 5ac71f1..55646f6 100644 --- a/uberwriter/main_window.py +++ b/uberwriter/main_window.py @@ -84,10 +84,21 @@ class MainWindow(StyledWindow): self.settings = Settings.new() # Headerbars + self.last_height = 0 self.headerbar = headerbars.MainHeaderbar(app) - self.set_titlebar(self.headerbar.hb_container) + self.headerbar.hb_revealer.connect( + "size_allocate", self.header_size_allocate) + self.set_titlebar(self.headerbar.hb_revealer) + self.fs_headerbar = headerbars.FullscreenHeaderbar(builder, app) + # The dummy headerbar is a cosmetic hack to be able to + # crossfade the hb on top of the window + self.dm_headerbar = headerbars.DummyHeaderbar(app) + root.add_overlay(self.dm_headerbar.hb_revealer) + root.reorder_overlay(self.dm_headerbar.hb_revealer, 0) + root.set_overlay_pass_through(self.dm_headerbar.hb_revealer, True) + self.title_end = " – UberWriter" self.set_headerbar_title("New File" + self.title_end) @@ -103,6 +114,7 @@ class MainWindow(StyledWindow): # Setup text editor self.text_view = TextView(self.settings.get_int("characters-per-line")) + self.text_view.set_top_margin(80) self.text_view.connect('focus-out-event', self.focus_out) self.text_view.get_buffer().connect('changed', self.on_text_changed) self.text_view.show() @@ -151,6 +163,24 @@ class MainWindow(StyledWindow): ### self.searchreplace = SearchAndReplace(self, self.text_view, builder) + def header_size_allocate(self, widget, allocation): + """ When the main hb starts to shrink its size, add that size + to the textview margin, so it stays in place + """ + + # prevent 1px jumps + if allocation.height == 1 and not widget.get_child_revealed(): + allocation.height = 0 + + height = self.headerbar.hb.get_allocated_height() - allocation.height + if height == self.last_height: + return + + self.last_height = height + + self.text_view.update_vertical_margin(height) + self.text_view.queue_draw() + def on_text_changed(self, *_args): """called when the text changes, sets the self.did_change to true and updates the title and the counters to reflect that @@ -183,7 +213,7 @@ class MainWindow(StyledWindow): """toggle focusmode """ - self.text_view.set_focus_mode(state.get_boolean()) + self.text_view.set_focus_mode(state.get_boolean(), self.headerbar.hb.get_allocated_height()) self.text_view.grab_focus() def set_hemingway_mode(self, state): @@ -519,7 +549,6 @@ class MainWindow(StyledWindow): def open_recent(self, _widget, data=None): """open the given recent document """ - print("open") if data: if self.check_change() == Gtk.ResponseType.CANCEL: @@ -563,8 +592,30 @@ class MainWindow(StyledWindow): self.reveal_top_bottom_bars(True) def reveal_top_bottom_bars(self, reveal): + """handles (in conjunction with header_size_allocate) + the fading in and out of the headerbar + """ + # The logic may seem confusing because similar things are + # handled in headerbars.py, but for convenience (adding classes + # to the main window, and delayed calls) some functions are split + # between here and there + + # TODO: rework this logic? + + def reveal_hb(): + self.headerbar.hb_revealer.set_reveal_child(True) + self.get_style_context().remove_class("focus") + return False + if self.top_bottom_bars_visible != reveal: - self.headerbar.hb_revealer.set_reveal_child(reveal) + if reveal: + self.dm_headerbar.hide_dm_hb() + GLib.timeout_add(400, reveal_hb) + else: + self.headerbar.hb_revealer.set_reveal_child(False) + self.dm_headerbar.show_dm_hb() + self.get_style_context().add_class("focus") + self.stats_revealer.set_reveal_child(reveal) for revealer in self.preview_handler.get_top_bottom_bar_revealers(): revealer.set_reveal_child(reveal) diff --git a/uberwriter/text_view.py b/uberwriter/text_view.py index 1c4e9bc..87cabce 100644 --- a/uberwriter/text_view.py +++ b/uberwriter/text_view.py @@ -54,6 +54,9 @@ class TextView(Gtk.TextView): self.set_pixels_inside_wrap(8) self.get_style_context().add_class('uberwriter-editor') + self.set_margin_left(8) + self.set_margin_right(8) + # Text sizing self.props.halign = Gtk.Align.FILL self.line_chars = line_chars @@ -144,7 +147,6 @@ class TextView(Gtk.TextView): def on_size_allocate(self, *_): self.update_horizontal_margin() - self.update_vertical_margin() self.markup.update_margins_indents() self.queue_draw() @@ -192,14 +194,14 @@ class TextView(Gtk.TextView): self.frozen_scroll_scale = None self.queue_draw() - def set_focus_mode(self, focus_mode): + def set_focus_mode(self, focus_mode, hb_height): """Toggle focus mode. When in focus mode, the cursor sits in the middle of the text view, and the surrounding text is greyed out.""" self.focus_mode = focus_mode - self.update_vertical_margin() + self.update_vertical_margin(hb_size=hb_height) self.markup.apply() self.smooth_scroll_to() self.set_spellcheck(self.spellcheck) @@ -227,13 +229,14 @@ class TextView(Gtk.TextView): self.props.left_margin = horizontal_margin self.props.right_margin = horizontal_margin - def update_vertical_margin(self): + def update_vertical_margin(self, top_margin=0, hb_size=0): if self.focus_mode: - height = self.get_allocation().height - self.props.top_margin = height / 2 - self.props.bottom_margin = height / 2 + height = self.get_allocation().height + top_margin + hb_size + + self.props.top_margin = height / 2 + top_margin + self.props.bottom_margin = height / 2 - top_margin else: - self.props.top_margin = 80 + self.props.top_margin = 80 + top_margin self.props.bottom_margin = 64 def set_hemingway_mode(self, hemingway_mode): From 87e3cc127b19d5a4ffaa766aecad04607737499d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Genov=C3=A9s?= Date: Sat, 23 Nov 2019 02:13:10 +0100 Subject: [PATCH 13/45] add flatpak to gitignore --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 8be02eb..09c9621 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,5 @@ build/ .vscode/ .idea/ builddir/* -build-aux/* \ No newline at end of file +build-aux/* +flatpak/* From ff579b956fe5f313e70b7b7ab2ef9b6cc0315686 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Genov=C3=A9s?= Date: Mon, 25 Nov 2019 13:30:04 +0100 Subject: [PATCH 14/45] update gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 09c9621..8aa3903 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ *.pyc __pycache__/ +_build/* build/ *.*~ .vscode/ From 48e48d95def0ea39c62724d5332f1dd744c88376 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Genov=C3=A9s?= Date: Mon, 9 Dec 2019 02:14:52 +0100 Subject: [PATCH 15/45] add autohide-headerbar toggle on settings --- data/de.wolfvollprecht.UberWriter.gschema.xml | 6 +-- data/ui/Preferences.ui | 46 +++++++++++++++---- uberwriter/preferences_dialog.py | 8 ++++ 3 files changed, 48 insertions(+), 12 deletions(-) diff --git a/data/de.wolfvollprecht.UberWriter.gschema.xml b/data/de.wolfvollprecht.UberWriter.gschema.xml index 664870c..34f9300 100644 --- a/data/de.wolfvollprecht.UberWriter.gschema.xml +++ b/data/de.wolfvollprecht.UberWriter.gschema.xml @@ -62,11 +62,11 @@ Input format to use when previewing and exporting using Pandoc. - + true - Allow Uberwriter to poll cursor motion + Autohide Headerbar - Hide the header and status bars if the cursor is not moving. + Hide the header and status bars when typing. diff --git a/data/ui/Preferences.ui b/data/ui/Preferences.ui index d02cdd7..49bff6a 100644 --- a/data/ui/Preferences.ui +++ b/data/ui/Preferences.ui @@ -99,7 +99,7 @@ 0 - 2 + 3 @@ -110,7 +110,7 @@ 2 - 2 + 3 @@ -123,7 +123,7 @@ 0 - 3 + 4 @@ -134,7 +134,7 @@ 2 - 3 + 4 @@ -147,7 +147,7 @@ 0 - 4 + 5 @@ -158,7 +158,7 @@ 2 - 4 + 5 @@ -171,7 +171,7 @@ 0 - 5 + 6 @@ -184,7 +184,7 @@ 2 - 5 + 6 @@ -196,9 +196,37 @@ 1 - 5 + 6 + + + True + False + Autohide header and statusbars while typing + start + Autohide headerbar + right + + + 0 + 2 + + + + + True + True + end + + + 2 + 2 + + + + + diff --git a/uberwriter/preferences_dialog.py b/uberwriter/preferences_dialog.py index 5158298..dbccf71 100644 --- a/uberwriter/preferences_dialog.py +++ b/uberwriter/preferences_dialog.py @@ -75,6 +75,10 @@ class PreferencesDialog: self.dark_mode_switch.set_active(self.settings.get_value("dark-mode")) self.dark_mode_switch.connect("state-set", self.on_dark_mode) + self.autohide_headerbar_switch = self.builder.get_object("autohide_headerbar_switch") + self.autohide_headerbar_switch.set_active(self.settings.get_value("autohide-headerbar")) + self.autohide_headerbar_switch.connect("state-set", self.on_autohide_headerbar) + self.spellcheck_switch = self.builder.get_object("spellcheck_switch") self.spellcheck_switch.set_active(self.settings.get_value("spellcheck")) self.spellcheck_switch.connect("state-set", self.on_spellcheck) @@ -123,6 +127,10 @@ class PreferencesDialog: self.dark_mode_auto_switch.set_active(GLib.Variant.new_boolean(False)) return False + def on_autohide_headerbar(self, _, state): + self.settings.set_boolean("autohide-headerbar", state) + return False + def on_spellcheck(self, _, state): self.settings.set_boolean("spellcheck", state) return False From 151809ae9bf06c937b25d48d9832a1802d085a76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Genov=C3=A9s?= Date: Mon, 9 Dec 2019 02:15:09 +0100 Subject: [PATCH 16/45] add background color to inline buttons --- data/media/css/gtk/base.css | 1 + 1 file changed, 1 insertion(+) diff --git a/data/media/css/gtk/base.css b/data/media/css/gtk/base.css index cc3176f..01671f3 100644 --- a/data/media/css/gtk/base.css +++ b/data/media/css/gtk/base.css @@ -107,6 +107,7 @@ .inline-button { color: alpha(@theme_fg_color, 0.6); + background-color: alpha(@theme_base_color, 0.9); text-shadow: inherit; box-shadow: initial; background-clip: initial; From 97e809a5769c1729af50af744be3e226b869cad5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Genov=C3=A9s?= Date: Mon, 9 Dec 2019 02:16:13 +0100 Subject: [PATCH 17/45] rework the autohiding mechanis for headerbars --- data/ui/Window.ui | 40 +++++++---- uberwriter/main_window.py | 135 +++++++++++++++++++------------------- 2 files changed, 93 insertions(+), 82 deletions(-) diff --git a/data/ui/Window.ui b/data/ui/Window.ui index 466d1b3..5007bdf 100644 --- a/data/ui/Window.ui +++ b/data/ui/Window.ui @@ -6,7 +6,6 @@ True False - 12 edit-find-replace-symbolic @@ -30,12 +29,12 @@ False gtk-spell-check - + FullscreenOverlay True False - + True False @@ -71,10 +70,9 @@ False True - + True False - vertical True @@ -87,15 +85,15 @@ - False - True - 0 + -1 - + True False + GDK_ENTER_NOTIFY_MASK | GDK_STRUCTURE_MASK + end crossfade 750 True @@ -116,11 +114,6 @@ - - False - True - 1 - @@ -236,6 +229,7 @@ True False + True aA @@ -416,10 +410,28 @@ 1 False start + False + True + + + 60 + True + False + start + False + True + + + + + + 1 + + diff --git a/uberwriter/main_window.py b/uberwriter/main_window.py index 55646f6..4c12258 100644 --- a/uberwriter/main_window.py +++ b/uberwriter/main_window.py @@ -74,7 +74,7 @@ class MainWindow(StyledWindow): builder = Gtk.Builder() builder.add_from_resource( "/de/wolfvollprecht/UberWriter/ui/Window.ui") - root = builder.get_object("FullscreenOverlay") + root = builder.get_object("AppOverlay") self.connect("delete-event", self.on_delete_called) self.add(root) @@ -102,11 +102,6 @@ class MainWindow(StyledWindow): self.title_end = " – UberWriter" self.set_headerbar_title("New File" + self.title_end) - self.timestamp_last_mouse_motion = 0 - if self.settings.get_value("poll-motion"): - self.connect("motion-notify-event", self.on_motion_notify) - GObject.timeout_add(3000, self.poll_for_motion) - self.accel_group = Gtk.AccelGroup() self.add_accel_group(self.accel_group) @@ -131,9 +126,10 @@ class MainWindow(StyledWindow): editor = builder.get_object('editor') self.preview_handler = PreviewHandler(self, content, editor, self.text_view) - # Setup header/stats bar hide after 3 seconds - self.top_bottom_bars_visible = True - self.was_motion = True + # Setup header/stats bar + self.headerbar_visible = True + self.bottombar_visible = True + self.previewbars_visible = True self.buffer_modified_for_status_bar = False # some people seems to have performance problems with the overlay. @@ -163,6 +159,14 @@ class MainWindow(StyledWindow): ### self.searchreplace = SearchAndReplace(self, self.text_view, builder) + # EventBoxes + + self.headerbar_eventbox = builder.get_object("HeaderbarEventbox") + self.headerbar_eventbox.connect('enter_notify_event', + self.reveal_headerbar_bottombar) + + self.stats_revealer.connect('enter_notify_event', self.reveal_bottombar) + def header_size_allocate(self, widget, allocation): """ When the main hb starts to shrink its size, add that size to the textview margin, so it stays in place @@ -192,6 +196,8 @@ class MainWindow(StyledWindow): self.set_headerbar_title("* " + title) self.buffer_modified_for_status_bar = True + if self.settings.get_value("autohide-headerbar"): + self.hide_headerbar_bottombar() def set_fullscreen(self, state): """Puts the application in fullscreen mode and show/hides @@ -555,72 +561,62 @@ class MainWindow(StyledWindow): return self.load_file(data) - def poll_for_motion(self): - """check if the user has moved the cursor to show the headerbar - - Returns: - True -- Gtk things - """ - - if (not self.was_motion - and self.buffer_modified_for_status_bar - and self.text_view.props.has_focus): - self.reveal_top_bottom_bars(False) - - self.was_motion = False - return True - - def on_motion_notify(self, _widget, event, _data=None): - """check the motion of the mouse to fade in the headerbar - """ - now = event.get_time() - if now - self.timestamp_last_mouse_motion > 150: - # filter out accidental motions - self.timestamp_last_mouse_motion = now - return - if now - self.timestamp_last_mouse_motion < 100: - # filter out accidental motion - return - if now - self.timestamp_last_mouse_motion > 100: - # react on motion by fading in headerbar and statusbar - self.reveal_top_bottom_bars(True) - self.was_motion = True - def focus_out(self, _widget, _data=None): """events called when the window losses focus """ - self.reveal_top_bottom_bars(True) + self.reveal_headerbar_bottombar() - def reveal_top_bottom_bars(self, reveal): - """handles (in conjunction with header_size_allocate) - the fading in and out of the headerbar - """ - # The logic may seem confusing because similar things are - # handled in headerbars.py, but for convenience (adding classes - # to the main window, and delayed calls) some functions are split - # between here and there + def reveal_headerbar_bottombar(self, _widget=None, _data=None): - # TODO: rework this logic? - - def reveal_hb(): + def __reveal_hb(): self.headerbar.hb_revealer.set_reveal_child(True) self.get_style_context().remove_class("focus") return False - if self.top_bottom_bars_visible != reveal: - if reveal: - self.dm_headerbar.hide_dm_hb() - GLib.timeout_add(400, reveal_hb) - else: - self.headerbar.hb_revealer.set_reveal_child(False) - self.dm_headerbar.show_dm_hb() - self.get_style_context().add_class("focus") - - self.stats_revealer.set_reveal_child(reveal) + self.reveal_bottombar() + + if not self.headerbar_visible: + self.dm_headerbar.hide_dm_hb() + GLib.timeout_add(400, __reveal_hb) + + self.headerbar_visible = True + + if not self.previewbars_visible: for revealer in self.preview_handler.get_top_bottom_bar_revealers(): - revealer.set_reveal_child(reveal) - self.top_bottom_bars_visible = reveal - self.buffer_modified_for_status_bar = reveal + revealer.set_reveal_child(True) + + self.previewbars_visible = True + + def reveal_bottombar(self, _widget=None, _data=None): + + if not self.bottombar_visible: + self.stats_revealer.set_reveal_child(True) + + self.bottombar_visible = True + + self.buffer_modified_for_status_bar = True + + def hide_headerbar_bottombar(self): + + if self.headerbar_visible: + self.headerbar.hb_revealer.set_reveal_child(False) + self.dm_headerbar.show_dm_hb() + self.get_style_context().add_class("focus") + + self.headerbar_visible = False + + if self.bottombar_visible: + self.stats_revealer.set_reveal_child(False) + + self.bottombar_visible = False + + if self.previewbars_visible: + for revealer in self.preview_handler.get_top_bottom_bar_revealers(): + revealer.set_reveal_child(False) + + self.previewbars_visible = False + + self.buffer_modified_for_status_bar = False def draw_gradient(self, _widget, cr): """draw fading gradient over the top and the bottom of the @@ -668,13 +664,16 @@ class MainWindow(StyledWindow): self.destroy() return - def set_headerbar_title(self, title, subtitle=""): + def set_headerbar_title(self, title, subtitle=None): """set the desired headerbar title """ self.headerbar.hb.props.title = title + self.dm_headerbar.hb.props.title = title self.fs_headerbar.hb.props.title = title - self.headerbar.hb.props.subtitle = subtitle - self.fs_headerbar.hb.props.subtitle = subtitle + if subtitle: + self.headerbar.hb.props.subtitle = subtitle + self.dm_headerbar.hb.props.subtitle = subtitle + self.fs_headerbar.hb.props.subtitle = subtitle self.set_title(title) def set_filename(self, filename=None): From 5a78d75668861736f107f0fa5c8228d45ec26fb0 Mon Sep 17 00:00:00 2001 From: Manuel Genoves Date: Tue, 10 Dec 2019 17:43:02 +0100 Subject: [PATCH 18/45] fix fullscreen issues --- data/ui/Window.ui | 3 +-- uberwriter/headerbars.py | 4 ++-- uberwriter/main_window.py | 3 +++ 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/data/ui/Window.ui b/data/ui/Window.ui index 5007bdf..21daefa 100644 --- a/data/ui/Window.ui +++ b/data/ui/Window.ui @@ -78,6 +78,7 @@ True True True + 6 True True @@ -410,8 +411,6 @@ 1 False start - False - True diff --git a/uberwriter/headerbars.py b/uberwriter/headerbars.py index ba81346..a7b1e01 100644 --- a/uberwriter/headerbars.py +++ b/uberwriter/headerbars.py @@ -79,12 +79,12 @@ class FullscreenHeaderbar(BaseHeaderbar): self.events.connect('leave_notify_event', self.hide_fs_hb) self.menu_button.get_popover().connect('closed', self.hide_fs_hb) - def show_fs_hb(self, _widget, _data=None): + def show_fs_hb(self, _widget=None, _data=None): """show headerbar of the fullscreen mode """ self.hb_revealer.set_reveal_child(True) - def hide_fs_hb(self, _widget, _data=None): + def hide_fs_hb(self, _widget=None, _data=None): """hide headerbar of the fullscreen mode """ if self.menu_button.get_active(): diff --git a/uberwriter/main_window.py b/uberwriter/main_window.py index 4c12258..f47d843 100644 --- a/uberwriter/main_window.py +++ b/uberwriter/main_window.py @@ -210,9 +210,12 @@ class MainWindow(StyledWindow): if state.get_boolean(): self.fullscreen() self.fs_headerbar.events.show() + self.fs_headerbar.hide_fs_hb() + self.headerbar_eventbox.hide() else: self.unfullscreen() self.fs_headerbar.events.hide() + self.headerbar_eventbox.show() self.text_view.grab_focus() def set_focus_mode(self, state): From d56623bfbdbc43e9cdb6c12b6e4d2896fdb446e0 Mon Sep 17 00:00:00 2001 From: Manuel Genoves Date: Tue, 10 Dec 2019 18:00:37 +0100 Subject: [PATCH 19/45] tweak headerbar reveal settings --- data/ui/Headerbar.ui | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/data/ui/Headerbar.ui b/data/ui/Headerbar.ui index 0a2f6aa..ce65cd8 100644 --- a/data/ui/Headerbar.ui +++ b/data/ui/Headerbar.ui @@ -17,8 +17,7 @@ True False start - slide-up - 750 + 350 True From 9216db1b804be2204a580498fe6b24329b6be9c0 Mon Sep 17 00:00:00 2001 From: Manuel Genoves Date: Wed, 11 Dec 2019 00:57:21 +0100 Subject: [PATCH 20/45] prevent headerbar to hide on open recents menu --- uberwriter/headerbars.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/uberwriter/headerbars.py b/uberwriter/headerbars.py index a7b1e01..f0203f3 100644 --- a/uberwriter/headerbars.py +++ b/uberwriter/headerbars.py @@ -78,6 +78,7 @@ class FullscreenHeaderbar(BaseHeaderbar): self.events.connect('enter_notify_event', self.show_fs_hb) self.events.connect('leave_notify_event', self.hide_fs_hb) self.menu_button.get_popover().connect('closed', self.hide_fs_hb) + self.recents_button.get_popover().connect('closed', self.hide_fs_hb) def show_fs_hb(self, _widget=None, _data=None): """show headerbar of the fullscreen mode @@ -87,7 +88,8 @@ class FullscreenHeaderbar(BaseHeaderbar): def hide_fs_hb(self, _widget=None, _data=None): """hide headerbar of the fullscreen mode """ - if self.menu_button.get_active(): + if (self.menu_button.get_active() or + self.recents_button.get_active()): pass else: self.hb_revealer.set_reveal_child(False) From d59994f3c998abfd921bd1b67b87b2b7fcfbc0a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Genov=C3=A9s?= Date: Wed, 25 Dec 2019 21:34:00 +0100 Subject: [PATCH 21/45] add nightly icon --- .../flatpak/de.wolfvollprecht.UberWriter.json | 192 +- .../de.wolfvollprecht.UberWriter.Devel.svg | 211 ++ .../icons/de.wolfvollprecht.uberwriter.Source | 2820 +++++++++++++++++ data/icons/meson.build | 5 +- meson.build | 2 +- 5 files changed, 3137 insertions(+), 93 deletions(-) create mode 100644 data/icons/de.wolfvollprecht.UberWriter.Devel.svg create mode 100644 data/icons/de.wolfvollprecht.uberwriter.Source diff --git a/build-aux/flatpak/de.wolfvollprecht.UberWriter.json b/build-aux/flatpak/de.wolfvollprecht.UberWriter.json index a0276fc..a847af9 100644 --- a/build-aux/flatpak/de.wolfvollprecht.UberWriter.json +++ b/build-aux/flatpak/de.wolfvollprecht.UberWriter.json @@ -1,10 +1,10 @@ { - "app-id": "de.wolfvollprecht.UberWriter", - "runtime": "org.gnome.Platform", - "runtime-version": "3.34", - "sdk": "org.gnome.Sdk", - "command": "uberwriter", - "finish-args": [ + "app-id" : "de.wolfvollprecht.UberWriter", + "runtime" : "org.gnome.Platform", + "runtime-version" : "3.34", + "sdk" : "org.gnome.Sdk", + "command" : "uberwriter", + "finish-args" : [ "--socket=x11", "--socket=wayland", "--share=ipc", @@ -13,94 +13,108 @@ "--env=PATH=/app/bin:/usr/bin:/app/extensions/TexLive/2019/bin/x86_64-linux/", "--metadata=X-DConf=migrate-path=/de/wolfvollprecht/UberWriter/" ], - "add-extensions": { - "de.wolfvollprecht.UberWriter.Plugin": { - "directory": "extensions", - "version": "stable", - "subdirectories": true, - "no-autodownload": true, - "autodelete": true - } + "add-extensions" : { + "de.wolfvollprecht.UberWriter.Plugin" : { + "directory" : "extensions", + "version" : "stable", + "subdirectories" : true, + "no-autodownload" : true, + "autodelete" : true + } }, - "modules": [{ - "name":"gspell", - "sources":[{ - "type":"archive", - "url":"https://download.gnome.org/sources/gspell/1.8/gspell-1.8.1.tar.xz", - "sha256":"819a1d23c7603000e73f5e738bdd284342e0cd345fb0c7650999c31ec741bbe5" - }] - }, - { - "name": "pandoc", - "only-arches": [ - "x86_64" - ], - "buildsystem": "simple", - "build-commands": [ - "cp bin/pandoc /app/bin/pandoc", - "cp bin/pandoc-citeproc /app/bin/pandoc-citeproc" - ], - "sources": [{ - "type": "archive", - "url": "https://github.com/jgm/pandoc/releases/download/2.2/pandoc-2.2-linux.tar.gz", - "sha256": "06ecd882e42ef9b7390b1c82e1e71b3ea48679181289b9b810a8797825bed8ed" - }] - }, - { - "name": "pipdeps", - "buildsystem": "simple", - "build-commands": [ - "pip3 install --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} regex pypandoc" - ], - "sources": [{ - "type": "file", - "url": "https://files.pythonhosted.org/packages/5d/c1/45947333669b31bc6b4933308dd07c2aa2fedcec0a95b14eedae993bd449/wheel-0.31.0.tar.gz", - "sha256": "1ae8153bed701cb062913b72429bcf854ba824f973735427681882a688cb55ce" + "modules" : [ + { + "name" : "gspell", + "sources" : [ + { + "type" : "archive", + "url" : "https://download.gnome.org/sources/gspell/1.8/gspell-1.8.1.tar.xz", + "sha256" : "819a1d23c7603000e73f5e738bdd284342e0cd345fb0c7650999c31ec741bbe5" + } + ] }, { - "type": "file", - "url": "https://files.pythonhosted.org/packages/ae/e8/2340d46ecadb1692a1e455f13f75e596d4eab3d11a57446f08259dee8f02/pip-10.0.1.tar.gz", - "sha256": "f2bd08e0cd1b06e10218feaf6fef299f473ba706582eb3bd9d52203fdbd7ee68" - }, - { - "type": "file", - "url": "https://files.pythonhosted.org/packages/71/81/00184643e5a10a456b4118fc12c96780823adb8ed974eb2289f29703b29b/pypandoc-1.4.tar.gz", - "sha256": "e914e6d5f84a76764887e4d909b09d63308725f0cbb5293872c2c92f07c11a5b" + "name" : "pandoc", + "only-arches" : [ + "x86_64" + ], + "buildsystem" : "simple", + "build-commands" : [ + "cp bin/pandoc /app/bin/pandoc", + "cp bin/pandoc-citeproc /app/bin/pandoc-citeproc" + ], + "sources" : [ + { + "type" : "archive", + "url" : "https://github.com/jgm/pandoc/releases/download/2.2/pandoc-2.2-linux.tar.gz", + "sha256" : "06ecd882e42ef9b7390b1c82e1e71b3ea48679181289b9b810a8797825bed8ed" + } + ] }, { - "type": "file", - "url": "https://files.pythonhosted.org/packages/a2/51/c39562cfed3272592c60cfd229e5464d715b78537e332eac2b695422dc49/regex-2018.02.21.tar.gz", - "sha256": "b44624a38d07d3c954c84ad302c29f7930f4bf01443beef5589e9157b14e2a29" + "name" : "pipdeps", + "buildsystem" : "simple", + "build-commands" : [ + "pip3 install --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} regex pypandoc" + ], + "sources" : [ + { + "type" : "file", + "url" : "https://files.pythonhosted.org/packages/5d/c1/45947333669b31bc6b4933308dd07c2aa2fedcec0a95b14eedae993bd449/wheel-0.31.0.tar.gz", + "sha256" : "1ae8153bed701cb062913b72429bcf854ba824f973735427681882a688cb55ce" + }, + { + "type" : "file", + "url" : "https://files.pythonhosted.org/packages/ae/e8/2340d46ecadb1692a1e455f13f75e596d4eab3d11a57446f08259dee8f02/pip-10.0.1.tar.gz", + "sha256" : "f2bd08e0cd1b06e10218feaf6fef299f473ba706582eb3bd9d52203fdbd7ee68" + }, + { + "type" : "file", + "url" : "https://files.pythonhosted.org/packages/71/81/00184643e5a10a456b4118fc12c96780823adb8ed974eb2289f29703b29b/pypandoc-1.4.tar.gz", + "sha256" : "e914e6d5f84a76764887e4d909b09d63308725f0cbb5293872c2c92f07c11a5b" + }, + { + "type" : "file", + "url" : "https://files.pythonhosted.org/packages/a2/51/c39562cfed3272592c60cfd229e5464d715b78537e332eac2b695422dc49/regex-2018.02.21.tar.gz", + "sha256" : "b44624a38d07d3c954c84ad302c29f7930f4bf01443beef5589e9157b14e2a29" + }, + { + "type" : "file", + "url" : "https://files.pythonhosted.org/packages/9e/54/04d88a59efa33fefb88133ceb638cdf754319030c28aadc5a379d82140ed/pyenchant-2.0.0.tar.gz", + "sha256" : "fc31cda72ace001da8fe5d42f11c26e514a91fa8c70468739216ddd8de64e2a0" + } + ] }, { - "type": "file", - "url": "https://files.pythonhosted.org/packages/9e/54/04d88a59efa33fefb88133ceb638cdf754319030c28aadc5a379d82140ed/pyenchant-2.0.0.tar.gz", - "sha256": "fc31cda72ace001da8fe5d42f11c26e514a91fa8c70468739216ddd8de64e2a0" - }] - }, - { - "name": "fonts", - "buildsystem": "simple", - "build-commands": [ - "mkdir -p /app/share/fonts/", - "cp ttf/* /app/share/fonts/" - ], - "sources": [{ - "type": "git", - "url": "https://github.com/mozilla/Fira", - "tag": "4.202" - }] - }, - { - "name": "uberwriter", - "buildsystem": "meson", - "sources": [{ - "type" : "dir", - "path" : "../../" - }], - "post-install": [ - "install -d /app/extensions" - ] - } - ] + "name" : "fonts", + "buildsystem" : "simple", + "build-commands" : [ + "mkdir -p /app/share/fonts/", + "cp ttf/* /app/share/fonts/" + ], + "sources" : [ + { + "type" : "git", + "url" : "https://github.com/mozilla/Fira", + "tag" : "4.202" + } + ] + }, + { + "name" : "uberwriter", + "buildsystem" : "meson", + "config-opts" : [ + "-Dprofile=development" + ], + "sources" : [ + { + "type" : "dir", + "path" : "../../" + } + ], + "post-install" : [ + "install -d /app/extensions" + ] + } + ] } diff --git a/data/icons/de.wolfvollprecht.UberWriter.Devel.svg b/data/icons/de.wolfvollprecht.UberWriter.Devel.svg new file mode 100644 index 0000000..4bca977 --- /dev/null +++ b/data/icons/de.wolfvollprecht.UberWriter.Devel.svg @@ -0,0 +1,211 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/icons/de.wolfvollprecht.uberwriter.Source b/data/icons/de.wolfvollprecht.uberwriter.Source new file mode 100644 index 0000000..942a89e --- /dev/null +++ b/data/icons/de.wolfvollprecht.uberwriter.Source @@ -0,0 +1,2820 @@ + + + Adwaita Icon Template + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + GNOME Design Team + + + + + Adwaita Icon Template + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/icons/meson.build b/data/icons/meson.build index 9aa6dc9..1b84295 100644 --- a/data/icons/meson.build +++ b/data/icons/meson.build @@ -1,7 +1,6 @@ install_data( - 'de.wolfvollprecht.UberWriter.svg', - install_dir: datadir / 'icons' / 'hicolor' / 'scalable' / 'apps', - rename: '@0@.svg'.format(application_id) + '@0@.svg'.format(application_id), + install_dir: datadir / 'icons' / 'hicolor' / 'scalable' / 'apps' ) install_data( diff --git a/meson.build b/meson.build index 6173c51..7718852 100644 --- a/meson.build +++ b/meson.build @@ -5,7 +5,7 @@ project( ) if get_option('profile') == 'development' - profile = 'Devel' + profile = '.Devel' name_suffix = ' (Development)' vcs_tag = run_command('git', 'rev-parse', '--short', 'HEAD').stdout().strip() if vcs_tag == '' From 07378d0ca80a28d26fe71ebd074971ac9e183ca9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Genov=C3=A9s?= Date: Tue, 28 Jan 2020 22:39:38 +0100 Subject: [PATCH 22/45] delete unnecessary icons --- data/media/icons/icon-case-off.png | Bin 603 -> 0 bytes data/media/icons/icon-regex-off.png | Bin 511 -> 0 bytes data/media/icons/icon-reverse-off.png | Bin 377 -> 0 bytes data/media/icons/icon-word-off.png | Bin 322 -> 0 bytes data/media/icons/icon-wrap-off.png | Bin 522 -> 0 bytes 5 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 data/media/icons/icon-case-off.png delete mode 100644 data/media/icons/icon-regex-off.png delete mode 100644 data/media/icons/icon-reverse-off.png delete mode 100644 data/media/icons/icon-word-off.png delete mode 100644 data/media/icons/icon-wrap-off.png diff --git a/data/media/icons/icon-case-off.png b/data/media/icons/icon-case-off.png deleted file mode 100644 index 281ae05dc8129e3411c1a0f51d2a981a7caa2a29..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 603 zcmV-h0;K(kP)fQ2sEo8eD9YFp`y(P3Pj`VqjxqyUEGP$pGXh;nIjM4mSws3s!!9{(v7pe*6jz z4ekH_{revt9-aW8I5S9-sHmuAH36XJ z>$#vuU}t1bLPxypi3A`OiUOA1qHo8-UjA?Z$NeG%*@PfKy??5jg49P`1m+L zhJXOrYuw!2!9YKA0BvCaI-dckh(Sh1hT+SXFAN|{fQEVk4xfD!0-ZXmN5h(7@FWFST^4nR>~1jMXB+yle`K&%GDFMyZ}h=qW- p0f-qu27zdb0V1?0G>U2l0RVDdoiXyF8zcY#002ovPDHLkV1fjO1F`@B diff --git a/data/media/icons/icon-regex-off.png b/data/media/icons/icon-regex-off.png deleted file mode 100644 index 61ff9322f3843388d742bf1fac0eb0221c691904..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 511 zcmVBO@a-FcSWPf< zZ}a*2`N3*{Vhey?jFp#{XS#d$uCA)8YR~Q4w|~M6Vnk0zKY#x8n>KA)(v>S$oS2!J zc|}D<89-jUfB!xM7Z=xGphc&0b91-K%F1>E4f%u9AfN=}n>TNa7c5v%^Wwz|e;ytl zu-ae0elY+oy&fDKTxVipvK1)!9cBoK#&8kP|8BrA=~Gr#*4EL{Vc_NEW%&2+AH(O* zpZ`C5_KflB)vF)hzklBb^maec;NLLAFajHBfTy~;x;8L8-kY17um1Gu(@$V{F~r2g zOcxLkxTC45$uBJ}ow$Ghe$*rZ3L|9v^5sjHj*gBkU%q@P0*Y%#MMZs&h=>3(|BC~0 z%(7+67O!8wz8S~{`vypZ^`jU96=VU@ra%m$8EkEBzgt^d1DS9ORe)?sBtF;-j4*=v z8Hom^84e(BKoY}X5@QgCCTs#2fsIWOF=A9R2moel>dq73$2I@}002ovPDHLkV1o0` B)gS-> diff --git a/data/media/icons/icon-reverse-off.png b/data/media/icons/icon-reverse-off.png deleted file mode 100644 index d6ec59580a2569358aaf4dfabc766cbe1f81739c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 377 zcmV-<0fzpGP)|y6`e^a2=IDML_|dT=g*&q6ciNF2pPnJO99Xo_QJx# zD{X9S#Q**Khf5h;9IHWMVq*Dna&kSkwze$%{QL~xzkg@Y(9rn*_wQe@#xGyKFg$<$ zoDpsckim$Yj-;ifxqkinHA6>7C)UEkf`Of#9a$}$ee2dOhGol^p%{eXA|D?g)`t%t z%1cU0GB7ftsDm4Vi-F=IpdwZv_HAitNd?;K1~ia~gM$O?wYP8If@zRJj~_o~IDGgp zicRPSfz*M3#rpN@Q&+EE9WEgu!TtXIdxrV*=Ql#6;A8`w1!9202nSZUa^*^MOiauZ z7Z(?x5}fM5`f(Wo6X*Nz;X_7hYU)`^4FVa+0>r+A48j#gDBdTAgExy1V*pGI)eHgv Xa&+{KUk0B700000NkvXXu0mjfrUakS diff --git a/data/media/icons/icon-word-off.png b/data/media/icons/icon-word-off.png deleted file mode 100644 index b0af0cab0a86f0f382a4c154d0d259ccefd5e0c3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 322 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+1|-AI^@TGqFmigjIEGjVCja^W-=5i&LD-as zai$>)kC3o%@Wd%o?kH(#{o=WM`^S@r38KuRw>UXDbHl>Jpa1^x@o{<5Q-@a%*gUfI%F^4gVS~W0-{19}9UKn$EO@=_u*k#7 z%_|#^&zdtQX2pU93d{kQ<;%;zA9Y~0Pwax|5)u%YkPZY7o<2>zc;P|?GfzQ<*HLwL zV~%&Getv#sX=!O}a&mHQ9UUBP(cAM5UNLwuxmmMmH%AJGUV}g1GWI+HpN1HzcUzD5 z%P*eMc*Z@gS!Cg7$D|&Qo%igP)C7Kmmo5ssUeWW9D~+EXcVHhHWwEsk%r_p zHi$Nq4@kqu_4Zv*=v?cxc;MsQ^Z0)J&v(vMh@wbV(UhxzNQ{+%I95dpG?U46rq}Ba z)oQhAJRZLehr>dv)w+@Um>`SAk`4p{IfuhRz$DY@)Y@n?uFYoiq}^`c{)90>PNy^N za=D1l=etWJ5`3{(^lLPl$Y?am0z!e983}^0$@4r3hr@Y}GC>IO z6nPZvb~^!NGMmjN3j>aXw=2GfLZNChnY>)gFM8@|ZnyggAc9+ZNTpJBz=Xv{^fTxK zszN+OH421^*6>zHEEdZH@`N{}MIN81=BwFkYAL5|K!IR-Ll#?pzke6UdNCLb$I)n% zbUK}$%(pb8u0I$I-oqq%z1}OM(Ktk?g?_&;U3YoODVtEp{(f7jR5~x0%lo*&bsVpU z+-jLjMtXpCnU@;MLDJ$jv Date: Tue, 28 Jan 2020 22:40:23 +0100 Subject: [PATCH 23/45] add preview layout icons --- .../preview-layout-full-width-symbolic.svg | 71 ++++++++++++++++++ .../preview-layout-half-height-symbolic.svg | 72 +++++++++++++++++++ .../preview-layout-half-width-symbolic.svg | 70 ++++++++++++++++++ .../preview-layout-windowed-symbolic.svg | 66 +++++++++++++++++ 4 files changed, 279 insertions(+) create mode 100644 data/media/icons/preview-layout-full-width-symbolic.svg create mode 100644 data/media/icons/preview-layout-half-height-symbolic.svg create mode 100644 data/media/icons/preview-layout-half-width-symbolic.svg create mode 100644 data/media/icons/preview-layout-windowed-symbolic.svg diff --git a/data/media/icons/preview-layout-full-width-symbolic.svg b/data/media/icons/preview-layout-full-width-symbolic.svg new file mode 100644 index 0000000..1519879 --- /dev/null +++ b/data/media/icons/preview-layout-full-width-symbolic.svg @@ -0,0 +1,71 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/data/media/icons/preview-layout-half-height-symbolic.svg b/data/media/icons/preview-layout-half-height-symbolic.svg new file mode 100644 index 0000000..1d39397 --- /dev/null +++ b/data/media/icons/preview-layout-half-height-symbolic.svg @@ -0,0 +1,72 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/data/media/icons/preview-layout-half-width-symbolic.svg b/data/media/icons/preview-layout-half-width-symbolic.svg new file mode 100644 index 0000000..66c963f --- /dev/null +++ b/data/media/icons/preview-layout-half-width-symbolic.svg @@ -0,0 +1,70 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/data/media/icons/preview-layout-windowed-symbolic.svg b/data/media/icons/preview-layout-windowed-symbolic.svg new file mode 100644 index 0000000..f2b61d3 --- /dev/null +++ b/data/media/icons/preview-layout-windowed-symbolic.svg @@ -0,0 +1,66 @@ + + + + + + image/svg+xml + + + + + + + + + + + + From 8e45b8d3daf5d23dcfd41120177f6da300c8fd5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Genov=C3=A9s?= Date: Tue, 28 Jan 2020 22:44:41 +0100 Subject: [PATCH 24/45] Start redesign of the headerbar Added (non functional) export and preview layout switcher popovers --- data/uberwriter.gresource.xml | 4 + data/ui/Headerbar.ui | 443 ++++++++++++++++++++++++++++++++-- uberwriter/headerbars.py | 6 + uberwriter/main_window.py | 6 + 4 files changed, 445 insertions(+), 14 deletions(-) diff --git a/data/uberwriter.gresource.xml b/data/uberwriter.gresource.xml index c85d3be..62f1d65 100644 --- a/data/uberwriter.gresource.xml +++ b/data/uberwriter.gresource.xml @@ -1,6 +1,10 @@ + media/icons/preview-layout-full-width-symbolic.svg + media/icons/preview-layout-half-width-symbolic.svg + media/icons/preview-layout-windowed-symbolic.svg + media/icons/preview-layout-half-height-symbolic.svg media/css/gtk/base.css ui/Export.ui ui/Menu.ui diff --git a/data/ui/Headerbar.ui b/data/ui/Headerbar.ui index ce65cd8..0e8cc2b 100644 --- a/data/ui/Headerbar.ui +++ b/data/ui/Headerbar.ui @@ -7,6 +7,316 @@ False view-restore-symbolic + + False + + + True + False + 6 + 18 + 12 + 12 + vertical + + + True + True + True + app.save_as + Save as... + + + False + True + 0 + + + + + True + False + + + False + True + 1 + + + + + True + True + True + Pdf + + + False + True + 2 + + + + + True + True + True + Html + + + False + True + 3 + + + + + True + True + True + ODT + + + False + True + 4 + + + + + True + True + True + Advanced + + + False + True + 5 + + + + + + + True + False + document-new-symbolic + + + True + False + view-dual-symbolic + + + False + + + True + False + vertical + + + True + False + 6 + 6 + 6 + 6 + 0 + in + + + True + False + + + True + False + + + True + False + 10 + + + True + False + 32 + preview-layout-full-width-symbolic + + + False + True + 0 + + + + + True + False + start + 6 + Full-Width + + + True + True + 1 + + + + + + + + + True + False + + + True + False + 10 + + + True + False + 32 + preview-layout-half-width-symbolic + + + False + True + 0 + + + + + True + False + start + 6 + Half-Width + + + True + True + 1 + + + + + + + + + True + True + + + True + False + 10 + + + True + False + 32 + preview-layout-half-height-symbolic + + + False + True + 0 + + + + + True + False + start + Half-Height + + + True + True + 1 + + + + + + + + + True + True + + + True + False + 10 + + + True + False + 32 + preview-layout-windowed-symbolic + + + False + True + 0 + + + + + True + False + start + Windowed + + + True + True + 1 + + + + + + + + + + + + + + False + True + 0 + + + + + Sync views + True + True + False + 4 + True + + + False + True + 1 + + + + + True False @@ -24,13 +334,14 @@ True False + 7 - New True True True app.new + new_icon @@ -76,6 +387,48 @@ 1 + + + True + False + + + Save + True + True + True + app.save + + + False + True + 0 + + + + + True + True + True + export_menu + + + + + + False + True + 1 + + + + + + 2 + + True @@ -108,6 +461,81 @@ 2 + + + True + False + 2 + + + True + True + True + app.preview + preview_icon + + + False + True + 0 + + + + + True + False + slide-right + + + True + True + True + preview_switcher + + + True + False + + + True + False + gtk-copy + + + False + True + 0 + + + + + True + False + pan-down-symbolic + + + False + True + 1 + + + + + + + + + False + True + 1 + + + + + end + 3 + + True @@ -118,19 +546,6 @@ search_icon True - - end - 3 - - - - - Save - True - True - True - app.save - end 4 diff --git a/uberwriter/headerbars.py b/uberwriter/headerbars.py index f0203f3..102b44a 100644 --- a/uberwriter/headerbars.py +++ b/uberwriter/headerbars.py @@ -35,9 +35,15 @@ class BaseHeaderbar: self.hb = self.builder.get_object("Headerbar") self.hb_revealer = self.builder.get_object("titlebar_revealer") + self.preview_toggle_revealer = self.builder.get_object("preview_switch_revealer") + self.menu_button = self.builder.get_object("menu_button") self.recents_button = self.builder.get_object("recents_button") + def set_preview_layout_icon(self, icon): + + self.preview_switcher_icon = self.builder.get_object("preview_switch_toggle_icon") + class MainHeaderbar(BaseHeaderbar): # pylint: disable=too-few-public-methods """Sets up the main application headerbar diff --git a/uberwriter/main_window.py b/uberwriter/main_window.py index f47d843..6db1653 100644 --- a/uberwriter/main_window.py +++ b/uberwriter/main_window.py @@ -242,9 +242,15 @@ class MainWindow(StyledWindow): if state.get_boolean(): self.text_view.grab_focus() self.preview_handler.show() + self.headerbar.preview_toggle_revealer.set_reveal_child(True) + self.fs_headerbar.preview_toggle_revealer.set_reveal_child(True) + self.dm_headerbar.preview_toggle_revealer.set_reveal_child(True) else: self.preview_handler.hide() self.text_view.grab_focus() + self.headerbar.preview_toggle_revealer.set_reveal_child(False) + self.fs_headerbar.preview_toggle_revealer.set_reveal_child(False) + self.dm_headerbar.preview_toggle_revealer.set_reveal_child(False) return True From 28fc4e0a72a94918e6574fa5caebd0111f9d1580 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Genov=C3=A9s?= Date: Wed, 12 Feb 2020 12:35:40 +0100 Subject: [PATCH 25/45] make preview layout switcher menu dynamic --- data/media/css/gtk/base.css | 4 + data/uberwriter.gresource.xml | 1 + data/ui/Headerbar.ui | 264 ++++++++++----------------- data/ui/PreviewLayoutSwitcherItem.ui | 48 +++++ uberwriter/headerbars.py | 76 +++++++- uberwriter/main_window.py | 1 + 6 files changed, 217 insertions(+), 177 deletions(-) create mode 100644 data/ui/PreviewLayoutSwitcherItem.ui diff --git a/data/media/css/gtk/base.css b/data/media/css/gtk/base.css index 01671f3..543da99 100644 --- a/data/media/css/gtk/base.css +++ b/data/media/css/gtk/base.css @@ -172,4 +172,8 @@ .quick-preview-popup label { color: @theme_fg_color; +} + +.plain-listview { + background-color: @fg-color; } \ No newline at end of file diff --git a/data/uberwriter.gresource.xml b/data/uberwriter.gresource.xml index 62f1d65..c875ef3 100644 --- a/data/uberwriter.gresource.xml +++ b/data/uberwriter.gresource.xml @@ -14,6 +14,7 @@ ui/Shortcuts.ui ui/Window.ui ui/Headerbar.ui + ui/PreviewLayoutSwitcherItem.ui About.ui diff --git a/data/ui/Headerbar.ui b/data/ui/Headerbar.ui index 0e8cc2b..3dafcb2 100644 --- a/data/ui/Headerbar.ui +++ b/data/ui/Headerbar.ui @@ -2,6 +2,45 @@ + + False + + + True + False + + + True + True + True + + + + + + False + True + 0 + + + + + True + True + True + + + + + + False + True + 1 + + + + + True False @@ -13,8 +52,8 @@ True False - 6 - 18 + 12 + 12 12 12 vertical @@ -119,174 +158,18 @@ True False - 6 - 6 - 6 + 12 6 + False 0 - in + none - + True False - - - True - False - - - True - False - 10 - - - True - False - 32 - preview-layout-full-width-symbolic - - - False - True - 0 - - - - - True - False - start - 6 - Full-Width - - - True - True - 1 - - - - - - - - - True - False - - - True - False - 10 - - - True - False - 32 - preview-layout-half-width-symbolic - - - False - True - 0 - - - - - True - False - start - 6 - Half-Width - - - True - True - 1 - - - - - - - - - True - True - - - True - False - 10 - - - True - False - 32 - preview-layout-half-height-symbolic - - - False - True - 0 - - - - - True - False - start - Half-Height - - - True - True - 1 - - - - - - - - - True - True - - - True - False - 10 - - - True - False - 32 - preview-layout-windowed-symbolic - - - False - True - 0 - - - - - True - False - start - Windowed - - - True - True - 1 - - - - - - + @@ -300,13 +183,9 @@ - - Sync views + True - True - False - 4 - True + False False @@ -314,6 +193,46 @@ 1 + + + True + False + 6 + 6 + 10 + 12 + 10 + + + True + True + + + False + True + 0 + + + + + True + False + 6 + Sync views + + + False + True + 1 + + + + + False + True + 2 + + @@ -467,12 +386,13 @@ False 2 - + True True True app.preview preview_icon + True False diff --git a/data/ui/PreviewLayoutSwitcherItem.ui b/data/ui/PreviewLayoutSwitcherItem.ui new file mode 100644 index 0000000..62a62a6 --- /dev/null +++ b/data/ui/PreviewLayoutSwitcherItem.ui @@ -0,0 +1,48 @@ + + + + + + True + True + app.preview_mode + + + True + False + 4 + 4 + 10 + 10 + 10 + + + True + False + 16 + preview-layout-full-width-symbolic + + + False + True + 0 + + + + + True + False + start + 6 + Full-Width + + + True + True + 1 + + + + + + diff --git a/uberwriter/headerbars.py b/uberwriter/headerbars.py index 102b44a..ca4af5f 100644 --- a/uberwriter/headerbars.py +++ b/uberwriter/headerbars.py @@ -18,31 +18,97 @@ import gi +from gettext import gettext as _ + gi.require_version('Gtk', '3.0') from gi.repository import Gtk, GLib from uberwriter.helpers import get_descendant +from uberwriter.settings import Settings class BaseHeaderbar: """Base class for all headerbars """ + # preview modes + FULL_WIDTH = 0 + HALF_WIDTH = 1 + HALF_HEIGHT = 2 + WINDOWED = 3 + def __init__(self, app): + self.settings = Settings.new() + self.builder = Gtk.Builder() self.builder.add_from_resource( "/de/wolfvollprecht/UberWriter/ui/Headerbar.ui") - self.hb = self.builder.get_object("Headerbar") - self.hb_revealer = self.builder.get_object("titlebar_revealer") + self.hb = self.builder.get_object( + "Headerbar") + self.hb_revealer = self.builder.get_object( + "titlebar_revealer") - self.preview_toggle_revealer = self.builder.get_object("preview_switch_revealer") + self.preview_toggle_revealer = self.builder.get_object( + "preview_switch_revealer") + self.preview_switcher_icon = self.builder.get_object( + "preview_switch_toggle_icon") + + self.__populate_layout_switcher_menu() + self.update_preview_layout_icon() self.menu_button = self.builder.get_object("menu_button") self.recents_button = self.builder.get_object("recents_button") - def set_preview_layout_icon(self, icon): + def update_preview_layout_icon(self): + mode = self.settings.get_enum("preview-mode") + self.preview_switcher_icon.set_from_icon_name( + self.__get_icon_for_preview_mode(mode), 4) - self.preview_switcher_icon = self.builder.get_object("preview_switch_toggle_icon") + def __populate_layout_switcher_menu(self): + preview_menu = self.builder.get_object("preview_switch_options") + modes = self.settings.props.settings_schema.get_key("preview-mode").get_range()[1] + + for i, mode in enumerate(modes): + item_builder = Gtk.Builder() + item_builder.add_from_resource( + "/de/wolfvollprecht/UberWriter/ui/PreviewLayoutSwitcherItem.ui") + menu_item = item_builder.get_object("switcherItem") + + menu_item.label = item_builder.get_object("label") + menu_item.label.set_text(self.__get_text_for_preview_mode(i)) + + menu_item.icon = item_builder.get_object("icon") + menu_item.icon.set_from_icon_name(self.__get_icon_for_preview_mode(i), 16) + + menu_item.set_action_name("app.preview_mode") + menu_item.set_action_target_value(GLib.Variant.new_string(mode)) + + menu_item.show_all() + preview_menu.insert(menu_item, -1) + + def __get_text_for_preview_mode(self, mode): + if mode == self.FULL_WIDTH: + return _("Full-Width") + elif mode == self.HALF_WIDTH: + return _("Half-Width") + elif mode == self.HALF_HEIGHT: + return _("Half-Height") + elif mode == self.WINDOWED: + return _("Windowed") + else: + raise ValueError("Unknown preview mode {}".format(mode)) + + def __get_icon_for_preview_mode(self, mode): + if mode == self.FULL_WIDTH: + return "preview-layout-full-width-symbolic" + elif mode == self.HALF_WIDTH: + return "preview-layout-half-width-symbolic" + elif mode == self.HALF_HEIGHT: + return "preview-layout-half-height-symbolic" + elif mode == self.WINDOWED: + return "preview-layout-windowed-symbolic" + else: + raise ValueError("Unknown preview mode {}".format(mode)) class MainHeaderbar(BaseHeaderbar): # pylint: disable=too-few-public-methods diff --git a/uberwriter/main_window.py b/uberwriter/main_window.py index 6db1653..81edfbd 100644 --- a/uberwriter/main_window.py +++ b/uberwriter/main_window.py @@ -450,6 +450,7 @@ class MainWindow(StyledWindow): def update_preview_mode(self): self.preview_handler.update_preview_mode() + self.headerbar.update_preview_layout_icon() def menu_toggle_sidebar(self, _widget=None): """WIP From 81d5aab9e4388be00ce046b03b9fe1a977f3c96b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Genov=C3=A9s?= Date: Sun, 16 Feb 2020 22:00:04 +0100 Subject: [PATCH 26/45] move the sync prev toggle to the preview popover --- data/ui/Preferences.ui | 33 +++----------------------------- uberwriter/headerbars.py | 8 ++++++++ uberwriter/preferences_dialog.py | 8 -------- 3 files changed, 11 insertions(+), 38 deletions(-) diff --git a/data/ui/Preferences.ui b/data/ui/Preferences.ui index 49bff6a..55c54db 100644 --- a/data/ui/Preferences.ui +++ b/data/ui/Preferences.ui @@ -137,30 +137,6 @@ 4 - - - True - False - start - Synchronize editor/preview scrolling - right - - - 0 - 5 - - - - - True - True - end - - - 2 - 5 - - True @@ -171,7 +147,7 @@ 0 - 6 + 5 @@ -184,7 +160,7 @@ 2 - 6 + 5 @@ -196,7 +172,7 @@ 1 - 6 + 5 @@ -239,9 +215,6 @@ - - - False diff --git a/uberwriter/headerbars.py b/uberwriter/headerbars.py index ca4af5f..b3d0f35 100644 --- a/uberwriter/headerbars.py +++ b/uberwriter/headerbars.py @@ -56,6 +56,10 @@ class BaseHeaderbar: self.__populate_layout_switcher_menu() self.update_preview_layout_icon() + self.sync_scroll_switch = self.builder.get_object("sync_scroll_switch") + self.sync_scroll_switch.set_active(self.settings.get_value("sync-scroll")) + self.sync_scroll_switch.connect("state-set", self.__on_sync_scroll) + self.menu_button = self.builder.get_object("menu_button") self.recents_button = self.builder.get_object("recents_button") @@ -110,6 +114,10 @@ class BaseHeaderbar: else: raise ValueError("Unknown preview mode {}".format(mode)) + def __on_sync_scroll(self, _, state): + self.settings.set_boolean("sync-scroll", state) + return False + class MainHeaderbar(BaseHeaderbar): # pylint: disable=too-few-public-methods """Sets up the main application headerbar diff --git a/uberwriter/preferences_dialog.py b/uberwriter/preferences_dialog.py index dbccf71..850379f 100644 --- a/uberwriter/preferences_dialog.py +++ b/uberwriter/preferences_dialog.py @@ -87,10 +87,6 @@ class PreferencesDialog: self.gradient_overlay_switch.set_active(self.settings.get_value("gradient-overlay")) self.gradient_overlay_switch.connect("state-set", self.on_gradient_overlay) - self.sync_scroll_switch = self.builder.get_object("sync_scroll_switch") - self.sync_scroll_switch.set_active(self.settings.get_value("sync-scroll")) - self.sync_scroll_switch.connect("state-set", self.on_sync_scroll) - input_format_store = Gtk.ListStore(int, str) input_format = self.settings.get_string("input-format") input_format_active = 0 @@ -139,10 +135,6 @@ class PreferencesDialog: self.settings.set_boolean("gradient-overlay", state) return False - def on_sync_scroll(self, _, state): - self.settings.set_boolean("sync-scroll", state) - return False - def on_input_format(self, combobox): fmt = self.formats[combobox.get_active()] self.settings.set_string("input-format", fmt["format"]) From 77eb75c36b8c1d3fb2ddb940448024071a4bd0ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Genov=C3=A9s?= Date: Sun, 16 Feb 2020 22:00:10 +0100 Subject: [PATCH 27/45] fix margins --- data/ui/Headerbar.ui | 6 +- data/ui/PreviewLayoutSwitcherItem.ui | 87 ++++++++++++++-------------- data/ui/Window.ui | 1 - 3 files changed, 46 insertions(+), 48 deletions(-) diff --git a/data/ui/Headerbar.ui b/data/ui/Headerbar.ui index 3dafcb2..f001d52 100644 --- a/data/ui/Headerbar.ui +++ b/data/ui/Headerbar.ui @@ -197,13 +197,13 @@ True False - 6 - 6 + 12 + 12 10 12 10 - + True True diff --git a/data/ui/PreviewLayoutSwitcherItem.ui b/data/ui/PreviewLayoutSwitcherItem.ui index 62a62a6..cddd539 100644 --- a/data/ui/PreviewLayoutSwitcherItem.ui +++ b/data/ui/PreviewLayoutSwitcherItem.ui @@ -1,48 +1,47 @@ + - - - True - True - app.preview_mode - - - True - False - 4 - 4 - 10 - 10 - 10 - - - True - False - 16 - preview-layout-full-width-symbolic - - - False - True - 0 - - - - - True - False - start - 6 - Full-Width - - - True - True - 1 - - - - - + + True + True + app.preview_mode + + + True + False + 4 + 4 + 10 + + + True + False + 12 + 16 + preview-layout-full-width-symbolic + + + False + True + 0 + + + + + True + False + start + 12 + Full-Width + + + True + True + 1 + + + + + diff --git a/data/ui/Window.ui b/data/ui/Window.ui index 21daefa..e62fc92 100644 --- a/data/ui/Window.ui +++ b/data/ui/Window.ui @@ -78,7 +78,6 @@ True True True - 6 True True From a6f7e8525506b19ceadfdeaf5ea34d0847d44e07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Genov=C3=A9s?= Date: Sun, 23 Feb 2020 19:54:57 +0100 Subject: [PATCH 28/45] rework the close-without-saving dialog --- uberwriter/main_window.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/uberwriter/main_window.py b/uberwriter/main_window.py index 81edfbd..2880793 100644 --- a/uberwriter/main_window.py +++ b/uberwriter/main_window.py @@ -405,16 +405,27 @@ class MainWindow(StyledWindow): """Show dialog to prevent loss of unsaved changes """ + if self.filename: + title = os.path.basename(self.filename) + else: + title = _("New File") + if self.did_change and self.text_view.get_text(): dialog = Gtk.MessageDialog(self, Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, Gtk.MessageType.WARNING, Gtk.ButtonsType.NONE, - _("You have not saved your changes.") + _("Save changes to document “%s” before closing?") % + title ) - dialog.add_button(_("Close without saving"), Gtk.ResponseType.NO) + + dialog.props.secondary_text = _("If you don’t save, " + + "all your changes will be permanently lost.") + close_button = dialog.add_button(_("Close without saving"), Gtk.ResponseType.NO) dialog.add_button(_("Cancel"), Gtk.ResponseType.CANCEL) dialog.add_button(_("Save now"), Gtk.ResponseType.YES) + + close_button.get_style_context().add_class("destructive-action") # dialog.set_default_size(200, 60) dialog.set_default_response(Gtk.ResponseType.YES) response = dialog.run() From bf1fe7f59c1683deaa2096f48db26a89dba2e802 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Genov=C3=A9s?= Date: Mon, 24 Feb 2020 13:13:04 +0100 Subject: [PATCH 29/45] =?UTF-8?q?Reword=20=E2=80=9Cfree=20distraction?= =?UTF-8?q?=E2=80=9D=20into=20=E2=80=9Cdistraction-free=E2=80=9D=20Closes?= =?UTF-8?q?=20#203?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- data/de.wolfvollprecht.UberWriter.appdata.xml.in.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/de.wolfvollprecht.UberWriter.appdata.xml.in.in b/data/de.wolfvollprecht.UberWriter.appdata.xml.in.in index 4ae13b4..a124815 100644 --- a/data/de.wolfvollprecht.UberWriter.appdata.xml.in.in +++ b/data/de.wolfvollprecht.UberWriter.appdata.xml.in.in @@ -3,7 +3,7 @@ @app-id@ @app-id@.desktop UberWriter - An elegant, free distraction GTK+ markdown editor + An elegant, distraction-free GTK+ markdown editor

Uberwriter is a GTK+ based distraction free Markdown editor, mainly developed by Wolf Vollprecht and Manuel Genovés. It uses pandoc as backend for markdown parsing and offers a very clean and sleek user interface.

You can install the recommended TexLive extension with the command:

From a02c61ec7eaebdaedb50419530b3e2b1290e0139 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Genov=C3=A9s?= Date: Tue, 25 Feb 2020 13:32:10 +0100 Subject: [PATCH 30/45] Implement theme switcher auth.: @Exalm --- data/media/css/gtk/base.css | 41 ++++- data/media/css/web/adwaita.css | 20 ++- data/media/css/web/adwaita_dark.css | 18 --- data/media/css/web/arc.css | 21 ++- data/media/css/web/arc_dark.css | 18 --- data/media/css/web/arc_darker.css | 1 - data/uberwriter.gresource.xml | 1 + data/ui/Menu2.ui | 229 ++++++++++++++++++++++++++++ uberwriter/application.py | 21 ++- uberwriter/headerbars.py | 23 ++- uberwriter/main_window.py | 1 - uberwriter/styled_window.py | 33 +--- uberwriter/theme.py | 6 +- 13 files changed, 359 insertions(+), 74 deletions(-) delete mode 100644 data/media/css/web/adwaita_dark.css delete mode 100644 data/media/css/web/arc_dark.css delete mode 100644 data/media/css/web/arc_darker.css create mode 100644 data/ui/Menu2.ui diff --git a/data/media/css/gtk/base.css b/data/media/css/gtk/base.css index 543da99..8d4bffa 100644 --- a/data/media/css/gtk/base.css +++ b/data/media/css/gtk/base.css @@ -171,9 +171,48 @@ } .quick-preview-popup label { - color: @theme_fg_color; + color: @theme_fg_color; } .plain-listview { background-color: @fg-color; +} + +/* theme selector */ + +.color-button { + padding: 12px; + border-radius: 999px; + -gtk-outline-radius: 999px; + outline-offset: 1px; + border: none; + -gtk-icon-shadow: none; + min-width: 0px; + min-height: 0px; + color: transparent; + transition: all 200ms ease-out; +} + +.color-light { + background: #ffffff; + box-shadow: inset 0 0 0 1px #2e3436; +} + +.color-light:checked { + color: #2e3436; + box-shadow: inset 0 0 0 2px @theme_selected_bg_color; +} + +.color-dark { + background: #2d2d2d; + box-shadow: inset 0 0 0 1px alpha(black, .35); +} +.color-dark:checked { + color: #eeeeec; + box-shadow: inset 0 0 0 2px @theme_selected_bg_color; +} + +.color-button:disabled { + background: #929292; + box-shadow: inset 0 0 0 1px #2e3436; } \ No newline at end of file diff --git a/data/media/css/web/adwaita.css b/data/media/css/web/adwaita.css index e784b20..f37b57e 100644 --- a/data/media/css/web/adwaita.css +++ b/data/media/css/web/adwaita.css @@ -15,5 +15,23 @@ --kbd-background-color: #f1f1f1; --kbd-border-color: #bdc1c6; --kbd-shadow-color: #8c939a; +} -} \ No newline at end of file +@media (prefers-color-scheme: dark) { + :root { + --text-color: #eeeeec; + --background-color: #353535; + --alt-background-color: #3a3a3a; + --link-color: #b5daff; + --blockquote-text-color: #a8a8a6; + --blockquote-border-color: #525252; + --header-border-color: #474747; + --hr-background-color: #505050; + --table-tr-border-color: #696969; + --table-td-border-color: #525252; + --kbd-text-color: #cececc; + --kbd-background-color: #3c3c3c; + --kbd-border-color: #696969; + --kbd-shadow-color: #979797; + } +} diff --git a/data/media/css/web/adwaita_dark.css b/data/media/css/web/adwaita_dark.css deleted file mode 100644 index afedc5c..0000000 --- a/data/media/css/web/adwaita_dark.css +++ /dev/null @@ -1,18 +0,0 @@ -@import url("base.css"); - -:root { - --text-color: #eeeeec; - --background-color: #353535; - --alt-background-color: #3a3a3a; - --link-color: #b5daff; - --blockquote-text-color: #a8a8a6; - --blockquote-border-color: #525252; - --header-border-color: #474747; - --hr-background-color: #505050; - --table-tr-border-color: #696969; - --table-td-border-color: #525252; - --kbd-text-color: #cececc; - --kbd-background-color: #3c3c3c; - --kbd-border-color: #696969; - --kbd-shadow-color: #979797; -} \ No newline at end of file diff --git a/data/media/css/web/arc.css b/data/media/css/web/arc.css index 7ee62ac..ea0d3c4 100644 --- a/data/media/css/web/arc.css +++ b/data/media/css/web/arc.css @@ -15,4 +15,23 @@ --kbd-background-color: #f0f2f4; --kbd-border-color: #bcc2c9; --kbd-shadow-color: #8b949d; -} \ No newline at end of file +} + +@media (prefers-color-scheme: dark) { + :root { + --text-color: #d3dae3; + --background-color: #383c4a; + --alt-background-color: #3d414f; + --link-color: #9ac6ff; + --blockquote-text-color: #8d949d; + --blockquote-border-color: #555967; + --header-border-color: #4a4e5c; + --hr-background-color: #535765; + --table-tr-border-color: #6c707e; + --table-td-border-color: #555967; + --kbd-text-color: #b3bac3; + --kbd-background-color: #3f4351; + --kbd-border-color: #6c707e; + --kbd-shadow-color: #9a9eac; + } +} diff --git a/data/media/css/web/arc_dark.css b/data/media/css/web/arc_dark.css deleted file mode 100644 index f421845..0000000 --- a/data/media/css/web/arc_dark.css +++ /dev/null @@ -1,18 +0,0 @@ -@import url("base.css"); - -:root { - --text-color: #d3dae3; - --background-color: #383c4a; - --alt-background-color: #3d414f; - --link-color: #9ac6ff; - --blockquote-text-color: #8d949d; - --blockquote-border-color: #555967; - --header-border-color: #4a4e5c; - --hr-background-color: #535765; - --table-tr-border-color: #6c707e; - --table-td-border-color: #555967; - --kbd-text-color: #b3bac3; - --kbd-background-color: #3f4351; - --kbd-border-color: #6c707e; - --kbd-shadow-color: #9a9eac; -} \ No newline at end of file diff --git a/data/media/css/web/arc_darker.css b/data/media/css/web/arc_darker.css deleted file mode 100644 index a2b855f..0000000 --- a/data/media/css/web/arc_darker.css +++ /dev/null @@ -1 +0,0 @@ -@import url("arc.css"); diff --git a/data/uberwriter.gresource.xml b/data/uberwriter.gresource.xml index c875ef3..b129813 100644 --- a/data/uberwriter.gresource.xml +++ b/data/uberwriter.gresource.xml @@ -8,6 +8,7 @@ media/css/gtk/base.css ui/Export.ui ui/Menu.ui + ui/Menu2.ui ui/Preferences.ui ui/Preview.ui ui/Recents.ui diff --git a/data/ui/Menu2.ui b/data/ui/Menu2.ui new file mode 100644 index 0000000..2cc2ade --- /dev/null +++ b/data/ui/Menu2.ui @@ -0,0 +1,229 @@ + + + + + + False + + + True + False + 12 + 12 + 12 + 12 + vertical + + + True + False + center + 12 + 12 + 6 + 24 + + + True + True + False + center + app.dark_mode + False + + + True + False + emblem-ok-symbolic + + + + + + False + True + 0 + + + + + True + True + False + center + False + light_mode_button + + + True + False + emblem-ok-symbolic + + + + + + False + True + 1 + + + + + False + True + 0 + + + + + True + False + + + False + True + 1 + + + + + True + True + True + app.hemingway_mode + Hemingway mode + + + False + True + 2 + + + + + True + True + True + app.focus_mode + Focus Mode + + + False + True + 3 + + + + + True + False + + + False + True + 4 + + + + + True + True + True + app.search_replace + Find and Replace + + + False + True + 5 + + + + + True + False + + + False + True + 6 + + + + + True + True + True + app.preferences + Preferences + + + False + True + 7 + + + + + True + False + + + False + True + 8 + + + + + True + True + True + app.open_tutorial + Open Tutorial + + + False + True + 9 + + + + + True + True + True + app.shortcuts + Keyboard Shortcuts + + + False + True + 10 + + + + + True + True + True + app.about + About Uberwriter + + + False + True + 11 + + + + + + diff --git a/uberwriter/application.py b/uberwriter/application.py index 5fc8ebf..badcc9d 100644 --- a/uberwriter/application.py +++ b/uberwriter/application.py @@ -41,6 +41,7 @@ class Application(Gtk.Application): Gtk.Application.do_startup(self) self.settings.connect("changed", self.on_settings_changed) + self._set_dark_mode () # Header bar @@ -65,6 +66,10 @@ class Application(Gtk.Application): self.add_action(action) # App Menu + action = Gio.SimpleAction.new_stateful( + "dark_mode", None, GLib.Variant.new_boolean(False)) + action.connect("change-state", self.on_dark_mode) + self.add_action(action) action = Gio.SimpleAction.new_stateful( "focus_mode", None, GLib.Variant.new_boolean(False)) @@ -184,9 +189,20 @@ class Application(Gtk.Application): self.activate() return 0 + def _set_dark_mode (self): + dark = self.settings.get_value("dark-mode") + settings = Gtk.Settings.get_default() + + settings.props.gtk_application_prefer_dark_theme = dark + + if settings.props.gtk_theme_name == "HighContrast" and dark: + settings.props.gtk_theme_name = "HighContrastInverse" + elif settings.props.gtk_theme_name == "HighContrastInverse" and not dark: + settings.props.gtk_theme_name = "HighContrast" + def on_settings_changed(self, settings, key): if key == "dark-mode-auto" or key == "dark-mode": - self.window.apply_current_theme() + self._set_dark_mode () elif key == "spellcheck": self.window.toggle_spellcheck(settings.get_value(key)) elif key == "gradient-overlay": @@ -203,6 +219,9 @@ class Application(Gtk.Application): def on_new(self, _action, _value): self.window.new_document() + def on_dark_mode(self, action, value): + print(action, value) + def on_open(self, _action, _value): self.window.open_document() diff --git a/uberwriter/headerbars.py b/uberwriter/headerbars.py index b3d0f35..45fd18d 100644 --- a/uberwriter/headerbars.py +++ b/uberwriter/headerbars.py @@ -63,6 +63,17 @@ class BaseHeaderbar: self.menu_button = self.builder.get_object("menu_button") self.recents_button = self.builder.get_object("recents_button") + add_menus(self, app) + + settings = Gtk.Settings.get_default() + if global_dark:= settings.props.gtk_theme_name.endswith("-dark"): + self.light_button.set_sensitive(False) + self.light_button.set_tooltip_text(_("Light mode isn't available while using a dark global theme")) + + self.dark_button.set_active(self.settings.get_boolean("dark-mode") or global_dark) + + self.light_button.connect("toggled", self.__on_dark_mode) + def update_preview_layout_icon(self): mode = self.settings.get_enum("preview-mode") self.preview_switcher_icon.set_from_icon_name( @@ -118,6 +129,8 @@ class BaseHeaderbar: self.settings.set_boolean("sync-scroll", state) return False + def __on_dark_mode(self, _): + self.settings.set_boolean("dark-mode", self.dark_button.get_active()) class MainHeaderbar(BaseHeaderbar): # pylint: disable=too-few-public-methods """Sets up the main application headerbar @@ -129,7 +142,7 @@ class MainHeaderbar(BaseHeaderbar): # pylint: disable=too-few-public-methods self.hb.set_show_close_button(True) - add_menus(self, app) + #add_menus(self, app) self.hb_revealer.props.transition_duration = 0 @@ -147,7 +160,7 @@ class FullscreenHeaderbar(BaseHeaderbar): self.exit_fs_button = self.builder.get_object("exit_fs_button") self.exit_fs_button.set_visible(True) - add_menus(self, app) + #add_menus(self, app) self.events = fs_builder.get_object("FullscreenEventbox") self.events.add(self.hb_revealer) @@ -248,10 +261,12 @@ def add_menus(headerbar, app): builder_window_menu = Gtk.Builder() builder_window_menu.add_from_resource( - "/de/wolfvollprecht/UberWriter/ui/Menu.ui") + "/de/wolfvollprecht/UberWriter/ui/Menu2.ui") model = builder_window_menu.get_object("Menu") + headerbar.light_button = builder_window_menu.get_object("light_mode_button") + headerbar.dark_button = builder_window_menu.get_object("dark_mode_button") - headerbar.menu_button.set_menu_model(model) + headerbar.menu_button.set_popover(model) # Add recents menu to the open recents button diff --git a/uberwriter/main_window.py b/uberwriter/main_window.py index 2880793..20dfa97 100644 --- a/uberwriter/main_window.py +++ b/uberwriter/main_window.py @@ -35,7 +35,6 @@ from gi.repository import Gtk, Gdk, GObject, GLib, Gio import cairo from uberwriter import helpers -from uberwriter.theme import Theme from uberwriter.sidebar import Sidebar from uberwriter.search_and_replace import SearchAndReplace diff --git a/uberwriter/styled_window.py b/uberwriter/styled_window.py index b95ad03..9e0fed6 100644 --- a/uberwriter/styled_window.py +++ b/uberwriter/styled_window.py @@ -1,7 +1,6 @@ import gi from uberwriter import helpers -from uberwriter.theme import Theme gi.require_version('Gtk', '3.0') from gi.repository import Gtk, GLib, Gio @@ -13,27 +12,11 @@ class StyledWindow(Gtk.ApplicationWindow): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - self.connect("style-updated", self.apply_current_theme) - self.apply_current_theme() - - def apply_current_theme(self, *_): - """Adjusts the window, CSD and preview for the current theme.""" - # Get current theme - theme, changed = Theme.get_current_changed() - if changed: - # Set theme variant (dark/light) - Gtk.Settings.get_default().set_property( - "gtk-application-prefer-dark-theme", - GLib.Variant("b", theme.is_dark)) - - # Set theme css - css_provider_file = Gio.File.new_for_uri( - "resource:///de/wolfvollprecht/UberWriter/media/css/gtk/base.css") - style_provider = Gtk.CssProvider() - style_provider.load_from_file(css_provider_file) - Gtk.StyleContext.add_provider_for_screen( - self.get_screen(), style_provider, - Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION) - - # Redraw contents of window - self.queue_draw() \ No newline at end of file + # Set theme css + css_provider_file = Gio.File.new_for_uri( + "resource:///de/wolfvollprecht/UberWriter/media/css/gtk/base.css") + style_provider = Gtk.CssProvider() + style_provider.load_from_file(css_provider_file) + Gtk.StyleContext.add_provider_for_screen( + self.get_screen(), style_provider, + Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION) diff --git a/uberwriter/theme.py b/uberwriter/theme.py index 2c11e2f..732c774 100644 --- a/uberwriter/theme.py +++ b/uberwriter/theme.py @@ -56,11 +56,11 @@ class Theme: defaultThemes = [ # https://gitlab.gnome.org/GNOME/gtk/tree/master/gtk/theme/Adwaita Theme('Adwaita', get_css_path('web/adwaita.css'), False, 'Adwaita-dark'), - Theme('Adwaita-dark', get_css_path('web/adwaita_dark.css'), True, 'Adwaita'), + Theme('Adwaita-dark', get_css_path('web/adwaita.css'), True, 'Adwaita'), # https://github.com/NicoHood/arc-theme/tree/master/common/gtk-3.0/3.20/sass Theme('Arc', get_css_path('web/arc.css'), False, 'Arc-Dark'), - Theme('Arc-Darker', get_css_path('web/arc_darker.css'), False, 'Arc-Dark'), - Theme('Arc-Dark', get_css_path('web/arc_dark.css'), True, 'Arc'), + Theme('Arc-Darker', get_css_path('web/arc.css'), False, 'Arc-Dark'), + Theme('Arc-Dark', get_css_path('web/arc.css'), True, 'Arc'), # https://gitlab.gnome.org/GNOME/gtk/tree/master/gtk/theme/HighContrast Theme('HighContrast', get_css_path('web/highcontrast.css'), False, 'HighContrastInverse'), Theme('HighContrastInverse', get_css_path('web/highcontrast_inverse.css'), True, 'HighContrast') From 6ca2410432ce9a73d08b13df92bca297bd67278b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Genov=C3=A9s?= Date: Wed, 26 Feb 2020 01:07:22 +0100 Subject: [PATCH 31/45] Refine theme switcher --- data/de.wolfvollprecht.UberWriter.gschema.xml | 10 +- data/uberwriter.gresource.xml | 1 - data/ui/Menu.ui | 285 ++++++++++++++---- data/ui/Menu2.ui | 229 -------------- uberwriter/application.py | 8 - uberwriter/main_window.py | 11 + 6 files changed, 238 insertions(+), 306 deletions(-) delete mode 100644 data/ui/Menu2.ui diff --git a/data/de.wolfvollprecht.UberWriter.gschema.xml b/data/de.wolfvollprecht.UberWriter.gschema.xml index 34f9300..5c43fd2 100644 --- a/data/de.wolfvollprecht.UberWriter.gschema.xml +++ b/data/de.wolfvollprecht.UberWriter.gschema.xml @@ -18,17 +18,9 @@ - - - true - Set dark mode automatically - - Whether dark mode depends on the system theme, or is set to what the user specifies. - - false - Force dark mode + Use dark mode Enable or disable the dark mode. diff --git a/data/uberwriter.gresource.xml b/data/uberwriter.gresource.xml index b129813..c875ef3 100644 --- a/data/uberwriter.gresource.xml +++ b/data/uberwriter.gresource.xml @@ -8,7 +8,6 @@ media/css/gtk/base.css ui/Export.ui ui/Menu.ui - ui/Menu2.ui ui/Preferences.ui ui/Preview.ui ui/Recents.ui diff --git a/data/ui/Menu.ui b/data/ui/Menu.ui index 33f6df7..cb2214f 100644 --- a/data/ui/Menu.ui +++ b/data/ui/Menu.ui @@ -1,61 +1,228 @@ - - -
- - Focus Mode - app.focus_mode - - - Hemingway Mode - app.hemingway_mode - - - Preview - app.preview - - - Fullscreen - app.fullscreen - -
-
- - Save As - app.save_as - - - Export - app.export - - - Copy HTML - app.copy_html - -
-
- - Find and Replace - app.search_replace - -
-
- - Preferences - app.preferences - - - app.shortcuts - _Keyboard Shortcuts - - - Open Tutorial - app.open_tutorial - - - app.about - _About UberWriter - -
-
+ + + + + False + + + True + False + 12 + 12 + 12 + 12 + vertical + + + True + False + center + 12 + 12 + 6 + 24 + + + True + True + False + center + False + + + True + False + emblem-ok-symbolic + + + + + + False + True + 0 + + + + + True + True + False + center + False + light_mode_button + + + True + False + emblem-ok-symbolic + + + + + + False + True + 1 + + + + + False + True + 0 + + + + + True + False + + + False + True + 1 + + + + + True + True + True + app.hemingway_mode + Hemingway mode + + + False + True + 2 + + + + + True + True + True + app.focus_mode + Focus Mode + + + False + True + 3 + + + + + True + False + + + False + True + 4 + + + + + True + True + True + app.search_replace + Find and Replace + + + False + True + 5 + + + + + True + False + + + False + True + 6 + + + + + True + True + True + app.preferences + Preferences + + + False + True + 7 + + + + + True + False + + + False + True + 8 + + + + + True + True + True + app.open_tutorial + Open Tutorial + + + False + True + 9 + + + + + True + True + True + app.shortcuts + Keyboard Shortcuts + + + False + True + 10 + + + + + True + True + True + app.about + About Uberwriter + + + False + True + 11 + + + + + diff --git a/data/ui/Menu2.ui b/data/ui/Menu2.ui deleted file mode 100644 index 2cc2ade..0000000 --- a/data/ui/Menu2.ui +++ /dev/null @@ -1,229 +0,0 @@ - - - - - - False - - - True - False - 12 - 12 - 12 - 12 - vertical - - - True - False - center - 12 - 12 - 6 - 24 - - - True - True - False - center - app.dark_mode - False - - - True - False - emblem-ok-symbolic - - - - - - False - True - 0 - - - - - True - True - False - center - False - light_mode_button - - - True - False - emblem-ok-symbolic - - - - - - False - True - 1 - - - - - False - True - 0 - - - - - True - False - - - False - True - 1 - - - - - True - True - True - app.hemingway_mode - Hemingway mode - - - False - True - 2 - - - - - True - True - True - app.focus_mode - Focus Mode - - - False - True - 3 - - - - - True - False - - - False - True - 4 - - - - - True - True - True - app.search_replace - Find and Replace - - - False - True - 5 - - - - - True - False - - - False - True - 6 - - - - - True - True - True - app.preferences - Preferences - - - False - True - 7 - - - - - True - False - - - False - True - 8 - - - - - True - True - True - app.open_tutorial - Open Tutorial - - - False - True - 9 - - - - - True - True - True - app.shortcuts - Keyboard Shortcuts - - - False - True - 10 - - - - - True - True - True - app.about - About Uberwriter - - - False - True - 11 - - - - - - diff --git a/uberwriter/application.py b/uberwriter/application.py index badcc9d..35f9d24 100644 --- a/uberwriter/application.py +++ b/uberwriter/application.py @@ -66,11 +66,6 @@ class Application(Gtk.Application): self.add_action(action) # App Menu - action = Gio.SimpleAction.new_stateful( - "dark_mode", None, GLib.Variant.new_boolean(False)) - action.connect("change-state", self.on_dark_mode) - self.add_action(action) - action = Gio.SimpleAction.new_stateful( "focus_mode", None, GLib.Variant.new_boolean(False)) action.connect("change-state", self.on_focus_mode) @@ -219,9 +214,6 @@ class Application(Gtk.Application): def on_new(self, _action, _value): self.window.new_document() - def on_dark_mode(self, action, value): - print(action, value) - def on_open(self, _action, _value): self.window.open_document() diff --git a/uberwriter/main_window.py b/uberwriter/main_window.py index 20dfa97..bd3d931 100644 --- a/uberwriter/main_window.py +++ b/uberwriter/main_window.py @@ -91,6 +91,17 @@ class MainWindow(StyledWindow): self.fs_headerbar = headerbars.FullscreenHeaderbar(builder, app) + # Bind properties between normal and fs headerbar + self.headerbar.light_button.bind_property( + "active", self.fs_headerbar.light_button, "active", + GObject.BindingFlags.BIDIRECTIONAL + | GObject.BindingFlags.SYNC_CREATE) + + self.headerbar.dark_button.bind_property( + "active", self.fs_headerbar.dark_button, "active", + GObject.BindingFlags.BIDIRECTIONAL + | GObject.BindingFlags.SYNC_CREATE) + # The dummy headerbar is a cosmetic hack to be able to # crossfade the hb on top of the window self.dm_headerbar = headerbars.DummyHeaderbar(app) From 004c7544a08de7ed72b62bdfe3e1db93a04882c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Genov=C3=A9s?= Date: Wed, 26 Feb 2020 01:07:58 +0100 Subject: [PATCH 32/45] refine fullscreen headerbar behavior --- data/ui/Headerbar.ui | 2 +- uberwriter/headerbars.py | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/data/ui/Headerbar.ui b/data/ui/Headerbar.ui index f001d52..d8bacca 100644 --- a/data/ui/Headerbar.ui +++ b/data/ui/Headerbar.ui @@ -406,7 +406,7 @@ False slide-right - + True True True diff --git a/uberwriter/headerbars.py b/uberwriter/headerbars.py index 45fd18d..3631f0e 100644 --- a/uberwriter/headerbars.py +++ b/uberwriter/headerbars.py @@ -62,6 +62,8 @@ class BaseHeaderbar: self.menu_button = self.builder.get_object("menu_button") self.recents_button = self.builder.get_object("recents_button") + self.export_button = self.builder.get_object("export_button") + self.preview_switch_button = self.builder.get_object("preview_switch_button") add_menus(self, app) @@ -172,6 +174,8 @@ class FullscreenHeaderbar(BaseHeaderbar): self.events.connect('leave_notify_event', self.hide_fs_hb) self.menu_button.get_popover().connect('closed', self.hide_fs_hb) self.recents_button.get_popover().connect('closed', self.hide_fs_hb) + self.export_button.get_popover().connect('closed', self.hide_fs_hb) + self.preview_switch_button.get_popover().connect('closed', self.hide_fs_hb) def show_fs_hb(self, _widget=None, _data=None): """show headerbar of the fullscreen mode @@ -182,7 +186,9 @@ class FullscreenHeaderbar(BaseHeaderbar): """hide headerbar of the fullscreen mode """ if (self.menu_button.get_active() or - self.recents_button.get_active()): + self.recents_button.get_active() or + self.export_button.get_active() or + self.preview_switch_button.get_active()): pass else: self.hb_revealer.set_reveal_child(False) @@ -261,7 +267,7 @@ def add_menus(headerbar, app): builder_window_menu = Gtk.Builder() builder_window_menu.add_from_resource( - "/de/wolfvollprecht/UberWriter/ui/Menu2.ui") + "/de/wolfvollprecht/UberWriter/ui/Menu.ui") model = builder_window_menu.get_object("Menu") headerbar.light_button = builder_window_menu.get_object("light_mode_button") headerbar.dark_button = builder_window_menu.get_object("dark_mode_button") From 45f42059390879abf4863e19eac890a5f137d562 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Genov=C3=A9s?= Date: Wed, 26 Feb 2020 01:08:11 +0100 Subject: [PATCH 33/45] fix typo --- data/de.wolfvollprecht.UberWriter.appdata.xml.in.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/de.wolfvollprecht.UberWriter.appdata.xml.in.in b/data/de.wolfvollprecht.UberWriter.appdata.xml.in.in index 4ae13b4..a124815 100644 --- a/data/de.wolfvollprecht.UberWriter.appdata.xml.in.in +++ b/data/de.wolfvollprecht.UberWriter.appdata.xml.in.in @@ -3,7 +3,7 @@ @app-id@ @app-id@.desktop UberWriter - An elegant, free distraction GTK+ markdown editor + An elegant, distraction-free GTK+ markdown editor

Uberwriter is a GTK+ based distraction free Markdown editor, mainly developed by Wolf Vollprecht and Manuel Genovés. It uses pandoc as backend for markdown parsing and offers a very clean and sleek user interface.

You can install the recommended TexLive extension with the command:

From bcd08397f18dea0df6d67ca3a75d62c702bec7bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Genov=C3=A9s?= Date: Wed, 26 Feb 2020 12:50:31 +0100 Subject: [PATCH 34/45] remove unneeded preferences --- data/de.wolfvollprecht.UberWriter.gschema.xml | 8 -- data/ui/Preferences.ui | 95 ++----------------- uberwriter/application.py | 4 +- uberwriter/main_window.py | 46 --------- uberwriter/preferences_dialog.py | 28 ------ uberwriter/theme.py | 3 +- 6 files changed, 9 insertions(+), 175 deletions(-) diff --git a/data/de.wolfvollprecht.UberWriter.gschema.xml b/data/de.wolfvollprecht.UberWriter.gschema.xml index 5c43fd2..a043c68 100644 --- a/data/de.wolfvollprecht.UberWriter.gschema.xml +++ b/data/de.wolfvollprecht.UberWriter.gschema.xml @@ -32,14 +32,6 @@ Enable or disable spellchecking.
- - false - Draw scroll gradient - - Show a gradient overlay over the text at the top anf bottom of the window. - It can cause performance problems to some users. - - true Synchronize editor/preview scrolling diff --git a/data/ui/Preferences.ui b/data/ui/Preferences.ui index 55c54db..509e55d 100644 --- a/data/ui/Preferences.ui +++ b/data/ui/Preferences.ui @@ -41,54 +41,6 @@ 16 8 8 - - - True - False - start - Set dark mode automatically - right - - - 0 - 0 - - - - - True - True - end - - - 2 - 0 - - - - - True - False - start - Force dark mode - right - - - 0 - 1 - - - - - True - True - end - - - 2 - 1 - - True @@ -99,7 +51,7 @@ 0 - 3 + 1 @@ -110,31 +62,7 @@
2 - 3 - - - - - True - False - start - Draw scroll gradient - right - - - 0 - 4 - - - - - True - True - end - - - 2 - 4 + 1 @@ -147,7 +75,7 @@
0 - 5 + 2
@@ -160,7 +88,7 @@
2 - 5 + 2
@@ -172,7 +100,7 @@
1 - 5 + 2 @@ -186,7 +114,7 @@
0 - 2 + 0
@@ -197,7 +125,7 @@
2 - 2 + 0
@@ -206,15 +134,6 @@ - - - - - - - - -
False diff --git a/uberwriter/application.py b/uberwriter/application.py index 35f9d24..c1a7959 100644 --- a/uberwriter/application.py +++ b/uberwriter/application.py @@ -196,12 +196,10 @@ class Application(Gtk.Application): settings.props.gtk_theme_name = "HighContrast" def on_settings_changed(self, settings, key): - if key == "dark-mode-auto" or key == "dark-mode": + if key == "dark-mode": self._set_dark_mode () elif key == "spellcheck": self.window.toggle_spellcheck(settings.get_value(key)) - elif key == "gradient-overlay": - self.window.toggle_gradient_overlay(settings.get_value(key)) elif key == "input-format": self.window.reload_preview() elif key == "sync-scroll": diff --git a/uberwriter/main_window.py b/uberwriter/main_window.py index bd3d931..997e948 100644 --- a/uberwriter/main_window.py +++ b/uberwriter/main_window.py @@ -142,11 +142,6 @@ class MainWindow(StyledWindow): self.previewbars_visible = True self.buffer_modified_for_status_bar = False - # some people seems to have performance problems with the overlay. - # Let them disable it - self.overlay_id = None - self.toggle_gradient_overlay(self.settings.get_value("gradient-overlay")) - # Init file name with None self.set_filename() @@ -487,18 +482,6 @@ class MainWindow(StyledWindow): self.text_view.set_spellcheck(state.get_boolean()) - def toggle_gradient_overlay(self, state): - """Toggle the gradient overlay - - Arguments: - state {gtk bool} -- Desired state of the gradient overlay (enabled/disabled) - """ - - if state.get_boolean(): - self.overlay_id = self.scrolled_window.connect_after("draw", self.draw_gradient) - elif self.overlay_id: - self.scrolled_window.disconnect(self.overlay_id) - def reload_preview(self, reshow=False): self.preview_handler.reload(reshow=reshow) @@ -649,35 +632,6 @@ class MainWindow(StyledWindow): self.buffer_modified_for_status_bar = False - def draw_gradient(self, _widget, cr): - """draw fading gradient over the top and the bottom of the - TextWindow - """ - bg_color = self.get_style_context().get_background_color(Gtk.StateFlags.ACTIVE) - - lg_top = cairo.LinearGradient(0, 0, 0, 32) # pylint: disable=no-member - lg_top.add_color_stop_rgba( - 0, bg_color.red, bg_color.green, bg_color.blue, 1) - lg_top.add_color_stop_rgba( - 1, bg_color.red, bg_color.green, bg_color.blue, 0) - - width = self.scrolled_window.get_allocation().width - height = self.scrolled_window.get_allocation().height - - cr.rectangle(0, 0, width, 32) - cr.set_source(lg_top) - cr.fill() - cr.rectangle(0, height - 32, width, height) - - lg_btm = cairo.LinearGradient(0, height - 32, 0, height) # pylint: disable=no-member - lg_btm.add_color_stop_rgba( - 1, bg_color.red, bg_color.green, bg_color.blue, 1) - lg_btm.add_color_stop_rgba( - 0, bg_color.red, bg_color.green, bg_color.blue, 0) - - cr.set_source(lg_btm) - cr.fill() - def on_delete_called(self, _widget, _data=None): """Called when the TexteditorWindow is closed. """ diff --git a/uberwriter/preferences_dialog.py b/uberwriter/preferences_dialog.py index 850379f..d679dca 100644 --- a/uberwriter/preferences_dialog.py +++ b/uberwriter/preferences_dialog.py @@ -67,14 +67,6 @@ class PreferencesDialog: self.builder.add_from_resource( "/de/wolfvollprecht/UberWriter/ui/Preferences.ui") - self.dark_mode_auto_switch = self.builder.get_object("dark_mode_auto_switch") - self.dark_mode_auto_switch.set_active(self.settings.get_value("dark-mode-auto")) - self.dark_mode_auto_switch.connect("state-set", self.on_dark_mode_auto) - - self.dark_mode_switch = self.builder.get_object("dark_mode_switch") - self.dark_mode_switch.set_active(self.settings.get_value("dark-mode")) - self.dark_mode_switch.connect("state-set", self.on_dark_mode) - self.autohide_headerbar_switch = self.builder.get_object("autohide_headerbar_switch") self.autohide_headerbar_switch.set_active(self.settings.get_value("autohide-headerbar")) self.autohide_headerbar_switch.connect("state-set", self.on_autohide_headerbar) @@ -83,10 +75,6 @@ class PreferencesDialog: self.spellcheck_switch.set_active(self.settings.get_value("spellcheck")) self.spellcheck_switch.connect("state-set", self.on_spellcheck) - self.gradient_overlay_switch = self.builder.get_object("gradient_overlay_switch") - self.gradient_overlay_switch.set_active(self.settings.get_value("gradient-overlay")) - self.gradient_overlay_switch.connect("state-set", self.on_gradient_overlay) - input_format_store = Gtk.ListStore(int, str) input_format = self.settings.get_string("input-format") input_format_active = 0 @@ -111,18 +99,6 @@ class PreferencesDialog: preferences_window.set_transient_for(window) preferences_window.show() - def on_dark_mode_auto(self, _, state): - self.settings.set_boolean("dark-mode-auto", state) - if state and self.dark_mode_switch.get_active(): - self.dark_mode_switch.set_active(GLib.Variant.new_boolean(False)) - return False - - def on_dark_mode(self, _, state): - self.settings.set_boolean("dark-mode", state) - if state and self.dark_mode_auto_switch.get_active(): - self.dark_mode_auto_switch.set_active(GLib.Variant.new_boolean(False)) - return False - def on_autohide_headerbar(self, _, state): self.settings.set_boolean("autohide-headerbar", state) return False @@ -131,10 +107,6 @@ class PreferencesDialog: self.settings.set_boolean("spellcheck", state) return False - def on_gradient_overlay(self, _, state): - self.settings.set_boolean("gradient-overlay", state) - return False - def on_input_format(self, combobox): fmt = self.formats[combobox.get_active()] self.settings.set_string("input-format", fmt["format"]) diff --git a/uberwriter/theme.py b/uberwriter/theme.py index 732c774..a80cc18 100644 --- a/uberwriter/theme.py +++ b/uberwriter/theme.py @@ -31,10 +31,9 @@ class Theme: @classmethod def get_current_changed(cls): theme_name = Gtk.Settings.get_default().get_property('gtk-theme-name') - dark_mode_auto = cls.settings.get_boolean('dark-mode-auto') dark_mode = cls.settings.get_boolean('dark-mode') current_theme = cls.get_for_name(theme_name) - if not dark_mode_auto and dark_mode != current_theme.is_dark and current_theme.inverse_name: + if dark_mode != current_theme.is_dark and current_theme.inverse_name: current_theme = cls.get_for_name(current_theme.inverse_name, current_theme.name) changed = current_theme != cls.previous cls.previous = current_theme From bdc2e6cda7b1d8eee96de16633364f6c09555827 Mon Sep 17 00:00:00 2001 From: Manuel Genoves Date: Thu, 27 Feb 2020 12:22:22 +0100 Subject: [PATCH 35/45] backport to python 2.7 --- uberwriter/headerbars.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/uberwriter/headerbars.py b/uberwriter/headerbars.py index 3631f0e..bfacfde 100644 --- a/uberwriter/headerbars.py +++ b/uberwriter/headerbars.py @@ -68,9 +68,13 @@ class BaseHeaderbar: add_menus(self, app) settings = Gtk.Settings.get_default() - if global_dark:= settings.props.gtk_theme_name.endswith("-dark"): + # TODO: use walrust operator whenever Python3.8 lands on SDK + # if global_dark:= settings.props.gtk_theme_name.endswith("-dark"): + global_dark = settings.props.gtk_theme_name.endswith("-dark") + if global_dark: self.light_button.set_sensitive(False) - self.light_button.set_tooltip_text(_("Light mode isn't available while using a dark global theme")) + self.light_button.set_tooltip_text(_( + "Light mode isn't available while using a dark global theme")) self.dark_button.set_active(self.settings.get_boolean("dark-mode") or global_dark) From 48f32afa1b495423dfab166d88d1a6d53a684166 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Genov=C3=A9s?= Date: Thu, 27 Feb 2020 13:05:47 +0100 Subject: [PATCH 36/45] remove bottom preview bar --- uberwriter/preview_handler.py | 4 ++-- uberwriter/preview_renderer.py | 9 +++------ 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/uberwriter/preview_handler.py b/uberwriter/preview_handler.py index 4331957..d4c20aa 100644 --- a/uberwriter/preview_handler.py +++ b/uberwriter/preview_handler.py @@ -35,13 +35,13 @@ class PreviewHandler: builder = Gtk.Builder() builder.add_from_resource( "/de/wolfvollprecht/UberWriter/ui/Preview.ui") - preview = builder.get_object("preview") + # preview = builder.get_object("preview") mode_button = builder.get_object("preview_mode_button") self.mode_revealer = builder.get_object("preview_mode_revealer") self.preview_converter = PreviewConverter() self.preview_renderer = PreviewRenderer( - window, content, editor, text_view, preview, self.mode_revealer, mode_button) + window, content, editor, text_view, self.mode_revealer, mode_button) window.connect("style-updated", self.reload) diff --git a/uberwriter/preview_renderer.py b/uberwriter/preview_renderer.py index 2185486..15290ef 100644 --- a/uberwriter/preview_renderer.py +++ b/uberwriter/preview_renderer.py @@ -17,13 +17,12 @@ class PreviewRenderer: WINDOWED = 3 def __init__( - self, main_window, content, editor, text_view, preview, mode_revealer, mode_button): + self, main_window, content, editor, text_view, mode_revealer, mode_button): self.main_window = main_window self.main_window.connect("delete-event", self.on_window_closed) self.content = content self.editor = editor self.text_view = text_view - self.preview = preview self.mode_revealer = mode_revealer self.mode_button = mode_button self.mode_button.connect("clicked", self.show_mode_popover) @@ -67,8 +66,7 @@ class PreviewRenderer: self.window.show() else: - self.preview.pack_start(web_view, True, True, 0) - self.content.add(self.preview) + self.content.pack_start(web_view, True, True, 0) # Full-width preview: swap editor with preview. if self.mode == self.FULL_WIDTH: @@ -106,8 +104,7 @@ class PreviewRenderer: self.window = None else: - self.preview.remove(web_view) - self.content.remove(self.preview) + self.content.remove(web_view) # Full-width preview: swap preview with editor. if self.mode == self.FULL_WIDTH: From 8358571c8ee223bdcd636f8da4f12398b4e2c0a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Genov=C3=A9s?= Date: Thu, 27 Feb 2020 16:56:05 +0100 Subject: [PATCH 37/45] remove all references to preview.ui --- data/uberwriter.gresource.xml | 1 - data/ui/Preview.ui | 51 ---------------------------------- uberwriter/main_window.py | 12 -------- uberwriter/preview_handler.py | 15 +--------- uberwriter/preview_renderer.py | 37 +----------------------- uberwriter/preview_web_view.py | 2 ++ 6 files changed, 4 insertions(+), 114 deletions(-) delete mode 100644 data/ui/Preview.ui diff --git a/data/uberwriter.gresource.xml b/data/uberwriter.gresource.xml index c875ef3..2f90616 100644 --- a/data/uberwriter.gresource.xml +++ b/data/uberwriter.gresource.xml @@ -9,7 +9,6 @@ ui/Export.ui ui/Menu.ui ui/Preferences.ui - ui/Preview.ui ui/Recents.ui ui/Shortcuts.ui ui/Window.ui diff --git a/data/ui/Preview.ui b/data/ui/Preview.ui deleted file mode 100644 index ddc354b..0000000 --- a/data/ui/Preview.ui +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - True - False - pan-down-symbolic - 2 - - - True - False - True - vertical - - - - - - True - False - crossfade - 750 - True - - - Full-Width - True - True - True - Switch Preview Mode - end - pan-down - right - True - - - - - - False - True - end - 1 - - - - diff --git a/uberwriter/main_window.py b/uberwriter/main_window.py index 997e948..ec0126f 100644 --- a/uberwriter/main_window.py +++ b/uberwriter/main_window.py @@ -139,7 +139,6 @@ class MainWindow(StyledWindow): # Setup header/stats bar self.headerbar_visible = True self.bottombar_visible = True - self.previewbars_visible = True self.buffer_modified_for_status_bar = False # Init file name with None @@ -595,12 +594,6 @@ class MainWindow(StyledWindow): self.headerbar_visible = True - if not self.previewbars_visible: - for revealer in self.preview_handler.get_top_bottom_bar_revealers(): - revealer.set_reveal_child(True) - - self.previewbars_visible = True - def reveal_bottombar(self, _widget=None, _data=None): if not self.bottombar_visible: @@ -624,11 +617,6 @@ class MainWindow(StyledWindow): self.bottombar_visible = False - if self.previewbars_visible: - for revealer in self.preview_handler.get_top_bottom_bar_revealers(): - revealer.set_reveal_child(False) - - self.previewbars_visible = False self.buffer_modified_for_status_bar = False diff --git a/uberwriter/preview_handler.py b/uberwriter/preview_handler.py index d4c20aa..1e3a2c6 100644 --- a/uberwriter/preview_handler.py +++ b/uberwriter/preview_handler.py @@ -32,16 +32,9 @@ class PreviewHandler: self.web_view = None self.web_view_pending_html = None - builder = Gtk.Builder() - builder.add_from_resource( - "/de/wolfvollprecht/UberWriter/ui/Preview.ui") - # preview = builder.get_object("preview") - mode_button = builder.get_object("preview_mode_button") - self.mode_revealer = builder.get_object("preview_mode_revealer") - self.preview_converter = PreviewConverter() self.preview_renderer = PreviewRenderer( - window, content, editor, text_view, self.mode_revealer, mode_button) + window, content, editor, text_view) window.connect("style-updated", self.reload) @@ -135,12 +128,6 @@ class PreviewHandler: def update_preview_mode(self): self.preview_renderer.update_mode(self.web_view) - def get_top_bottom_bar_revealers(self): - if self.shown and not self.preview_renderer.window: - return [self.mode_revealer] - else: - return [] - def on_load_changed(self, _web_view, event): if event == WebKit2.LoadEvent.FINISHED: self.loading = False diff --git a/uberwriter/preview_renderer.py b/uberwriter/preview_renderer.py index 15290ef..3e81d7a 100644 --- a/uberwriter/preview_renderer.py +++ b/uberwriter/preview_renderer.py @@ -17,15 +17,12 @@ class PreviewRenderer: WINDOWED = 3 def __init__( - self, main_window, content, editor, text_view, mode_revealer, mode_button): + self, main_window, content, editor, text_view): self.main_window = main_window self.main_window.connect("delete-event", self.on_window_closed) self.content = content self.editor = editor self.text_view = text_view - self.mode_revealer = mode_revealer - self.mode_button = mode_button - self.mode_button.connect("clicked", self.show_mode_popover) self.settings = Settings.new() self.popover = None @@ -48,9 +45,6 @@ class PreviewRenderer: headerbar = headerbars.PreviewHeaderbar() self.headerbar = headerbar.hb self.headerbar.set_title(_("Preview")) - self.mode_button.get_style_context().remove_class("inline-button") - self.mode_revealer.remove(self.mode_button) - self.headerbar.pack_end(self.mode_button) self.window.set_titlebar(headerbar.hb_container) # Position it next to the main window. @@ -95,9 +89,6 @@ class PreviewRenderer: # Windowed preview: remove preview and destroy window. if self.mode == self.WINDOWED: self.main_window.present() - self.headerbar.remove(self.mode_button) - self.mode_button.get_style_context().add_class("inline-button") - self.mode_revealer.add(self.mode_button) self.headerbar = None self.window.remove(web_view) self.window.destroy() @@ -127,32 +118,6 @@ class PreviewRenderer: self.show(web_view) else: self.mode = mode - if self.mode_button: - text = self.get_text_for_preview_mode(self.mode) - self.mode_button.set_label(text) - if self.popover: - self.popover.popdown() - - def show_mode_popover(self, button): - """Show preview mode popover.""" - - self.mode_button.set_state_flags(Gtk.StateFlags.CHECKED, False) - - menu = Gio.Menu() - modes = self.settings.props.settings_schema.get_key("preview-mode").get_range()[1] - for i, mode in enumerate(modes): - menu_item = Gio.MenuItem.new(self.get_text_for_preview_mode(i), None) - menu_item.set_action_and_target_value("app.preview_mode", GLib.Variant.new_string(mode)) - menu.append_item(menu_item) - self.popover = Gtk.Popover.new_from_model(button, menu) - self.popover.connect('closed', self.on_popover_closed) - self.popover.popup() - - def on_popover_closed(self, _popover): - self.mode_button.unset_state_flags(Gtk.StateFlags.CHECKED) - - self.popover = None - self.text_view.grab_focus() def on_window_closed(self, window, _event): preview_action = window.get_application().lookup_action("preview") diff --git a/uberwriter/preview_web_view.py b/uberwriter/preview_web_view.py index 7e02fcb..f242596 100644 --- a/uberwriter/preview_web_view.py +++ b/uberwriter/preview_web_view.py @@ -62,6 +62,8 @@ if (canScroll && isRendered) {{ self.connect("load-failed", self.on_load_failed) self.connect("destroy", self.on_destroy) + self.props.expand = True + self.scroll_scale = -1 self.state_loaded = False From a4d0d3038c2588651a1a3925104968c932e31d42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Genov=C3=A9s?= Date: Thu, 27 Feb 2020 17:27:21 +0100 Subject: [PATCH 38/45] update correctly selected row on preview swicther --- uberwriter/headerbars.py | 15 +++++++++------ uberwriter/main_window.py | 3 +++ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/uberwriter/headerbars.py b/uberwriter/headerbars.py index bfacfde..3ffc9a5 100644 --- a/uberwriter/headerbars.py +++ b/uberwriter/headerbars.py @@ -80,13 +80,20 @@ class BaseHeaderbar: self.light_button.connect("toggled", self.__on_dark_mode) + self.select_preview_layout_row() + def update_preview_layout_icon(self): mode = self.settings.get_enum("preview-mode") self.preview_switcher_icon.set_from_icon_name( self.__get_icon_for_preview_mode(mode), 4) + def select_preview_layout_row(self): + mode = self.settings.get_enum("preview-mode") + row = self.preview_menu.get_row_at_index(mode) + self.preview_menu.select_row(row) + def __populate_layout_switcher_menu(self): - preview_menu = self.builder.get_object("preview_switch_options") + self.preview_menu = self.builder.get_object("preview_switch_options") modes = self.settings.props.settings_schema.get_key("preview-mode").get_range()[1] for i, mode in enumerate(modes): @@ -105,7 +112,7 @@ class BaseHeaderbar: menu_item.set_action_target_value(GLib.Variant.new_string(mode)) menu_item.show_all() - preview_menu.insert(menu_item, -1) + self.preview_menu.insert(menu_item, -1) def __get_text_for_preview_mode(self, mode): if mode == self.FULL_WIDTH: @@ -148,8 +155,6 @@ class MainHeaderbar(BaseHeaderbar): # pylint: disable=too-few-public-methods self.hb.set_show_close_button(True) - #add_menus(self, app) - self.hb_revealer.props.transition_duration = 0 @@ -166,8 +171,6 @@ class FullscreenHeaderbar(BaseHeaderbar): self.exit_fs_button = self.builder.get_object("exit_fs_button") self.exit_fs_button.set_visible(True) - #add_menus(self, app) - self.events = fs_builder.get_object("FullscreenEventbox") self.events.add(self.hb_revealer) diff --git a/uberwriter/main_window.py b/uberwriter/main_window.py index ec0126f..06a0682 100644 --- a/uberwriter/main_window.py +++ b/uberwriter/main_window.py @@ -466,6 +466,9 @@ class MainWindow(StyledWindow): def update_preview_mode(self): self.preview_handler.update_preview_mode() self.headerbar.update_preview_layout_icon() + self.headerbar.select_preview_layout_row() + self.fs_headerbar.update_preview_layout_icon() + self.fs_headerbar.select_preview_layout_row() def menu_toggle_sidebar(self, _widget=None): """WIP From 5b1571293c19c0b6633fbd2750dab532dd9ac9c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Genov=C3=A9s?= Date: Fri, 28 Feb 2020 01:06:10 +0100 Subject: [PATCH 39/45] Add tooltips --- data/ui/Headerbar.ui | 3 +++ 1 file changed, 3 insertions(+) diff --git a/data/ui/Headerbar.ui b/data/ui/Headerbar.ui index d8bacca..15497ab 100644 --- a/data/ui/Headerbar.ui +++ b/data/ui/Headerbar.ui @@ -259,6 +259,7 @@ True True True + New app.new new_icon
@@ -329,6 +330,7 @@ True True True + Save as... export_menu @@ -390,6 +392,7 @@ True True True + Preview app.preview preview_icon True From b70416709c7fb7f111cf2618581d96bebb5e155f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Genov=C3=A9s?= Date: Mon, 2 Mar 2020 14:33:11 +0100 Subject: [PATCH 40/45] externalize export popover --- data/uberwriter.gresource.xml | 1 + data/ui/ExportPopover.ui | 101 ++++++++++++++++++++++++++++++++++ data/ui/Headerbar.ui | 92 ------------------------------- uberwriter/application.py | 6 +- uberwriter/export_dialog.py | 57 ++++++++++++++++++- uberwriter/headerbars.py | 5 ++ uberwriter/main_window.py | 4 +- 7 files changed, 166 insertions(+), 100 deletions(-) create mode 100644 data/ui/ExportPopover.ui diff --git a/data/uberwriter.gresource.xml b/data/uberwriter.gresource.xml index 2f90616..9be8947 100644 --- a/data/uberwriter.gresource.xml +++ b/data/uberwriter.gresource.xml @@ -7,6 +7,7 @@ media/icons/preview-layout-half-height-symbolic.svg media/css/gtk/base.css ui/Export.ui + ui/ExportPopover.ui ui/Menu.ui ui/Preferences.ui ui/Recents.ui diff --git a/data/ui/ExportPopover.ui b/data/ui/ExportPopover.ui new file mode 100644 index 0000000..d164a1e --- /dev/null +++ b/data/ui/ExportPopover.ui @@ -0,0 +1,101 @@ + + + + + + False + + + True + False + 12 + vertical + + + True + True + True + app.save_as + Save as... + + + False + True + 0 + + + + + True + False + + + False + True + 1 + + + + + True + True + True + app.export + "pdf" + Pdf + + + False + True + 2 + + + + + True + True + True + app.export + "html" + Html + + + False + True + 3 + + + + + True + True + True + app.export + "odt" + ODT + + + False + True + 4 + + + + + True + True + True + app.export + "advanced" + Advanced + + + False + True + 5 + + + + + + \ No newline at end of file diff --git a/data/ui/Headerbar.ui b/data/ui/Headerbar.ui index 15497ab..051366f 100644 --- a/data/ui/Headerbar.ui +++ b/data/ui/Headerbar.ui @@ -46,97 +46,6 @@ False view-restore-symbolic
- - False - - - True - False - 12 - 12 - 12 - 12 - vertical - - - True - True - True - app.save_as - Save as... - - - False - True - 0 - - - - - True - False - - - False - True - 1 - - - - - True - True - True - Pdf - - - False - True - 2 - - - - - True - True - True - Html - - - False - True - 3 - - - - - True - True - True - ODT - - - False - True - 4 - - - - - True - True - True - Advanced - - - False - True - 5 - - - - - True False @@ -331,7 +240,6 @@ True True Save as... - export_menu diff --git a/uberwriter/application.py b/uberwriter/application.py index c1a7959..1aeaac9 100644 --- a/uberwriter/application.py +++ b/uberwriter/application.py @@ -90,7 +90,7 @@ class Application(Gtk.Application): action.connect("activate", self.on_save_as) self.add_action(action) - action = Gio.SimpleAction.new("export", None) + action = Gio.SimpleAction.new("export", GLib.VariantType("s")) action.connect("activate", self.on_export) self.add_action(action) @@ -246,8 +246,8 @@ class Application(Gtk.Application): def on_save_as(self, _action, _value): self.window.save_document_as() - def on_export(self, _action, _value): - self.window.open_advanced_export() + def on_export(self, _action, value): + self.window.open_advanced_export(value.get_string()) def on_copy_html(self, _action, _value): self.window.copy_html_to_clipboard() diff --git a/uberwriter/export_dialog.py b/uberwriter/export_dialog.py index 2c5b0c4..f31b7ea 100644 --- a/uberwriter/export_dialog.py +++ b/uberwriter/export_dialog.py @@ -39,6 +39,35 @@ class Export: __gtype_name__ = "export_dialog" + export_menu = { + "pdf": + { + "extension": "pdf", + "name": "PDF", + "mimetype": "application/pdf", + "dialog": regular_export_dialog() + }, + "html": + { + "extension": "html", + "name": "HTML", + "mimetype": "text/html" + }, + "odt": + { + "extension": "odt", + "name": "ODT", + "mimetype": "application/vnd.oasis.opendocument.text" + }, + "advanced": + { + "extension": "", + "name": "", + "mimetype": "", + "dialog": advanced_export_dialog() + }, + } + formats = [ { "name": "LaTeX (pdf)", @@ -147,12 +176,30 @@ class Export: } ] - def __init__(self, filename): - """Set up the about dialog""" + def __init__(self, filename, export_format): + """Set up the export dialog""" self.builder = Gtk.Builder() self.builder.add_from_resource( "/de/wolfvollprecht/UberWriter/ui/Export.ui") - self.dialog = self.builder.get_object("Export") + #self.dialog = self.builder.get_object("Export") + + self.dialog = Gtk.FileChooserNative.new(_("Export"), + None, + Gtk.FileChooserAction.SAVE, + _("Export to %s") % + self.export_menu[export_format]["extension"], + _("Cancel")) + print(self.export_menu[export_format]["mimetype"]) + filter = Gtk.FileFilter.new() + filter.set_name(self.export_menu[export_format]["name"]) + filter.add_mime_type(self.export_menu[export_format]["mimetype"]) + self.dialog.add_filter(filter) + self.dialog.set_do_overwrite_confirmation(True) + self.dialog.set_current_name("%s.%s" % (filename, self.export_menu[export_format]["extension"])) + #filechooser.connect("response", self.__on_save_response) + #filechooser.run() + + self.stack = self.builder.get_object("export_stack") self.stack_switcher = self.builder.get_object("format_switcher") @@ -196,6 +243,9 @@ class Export: self.format_field.add_attribute(format_renderer, "text", 1) self.format_field.set_active(0) + def regular_export_dialog(): + + def export(self, text=""): """Export the given text using the specified format. For advanced export, this includes special flags for the enabled options. @@ -330,6 +380,7 @@ class Export: else: export_btn.set_sensitive(True) + def disabled_text(): """Return the TexLive installation instructions diff --git a/uberwriter/headerbars.py b/uberwriter/headerbars.py index 3ffc9a5..d72f3b0 100644 --- a/uberwriter/headerbars.py +++ b/uberwriter/headerbars.py @@ -42,6 +42,8 @@ class BaseHeaderbar: self.builder = Gtk.Builder() self.builder.add_from_resource( "/de/wolfvollprecht/UberWriter/ui/Headerbar.ui") + self.builder.add_from_resource( + "/de/wolfvollprecht/UberWriter/ui/ExportPopover.ui") self.hb = self.builder.get_object( "Headerbar") @@ -63,8 +65,11 @@ class BaseHeaderbar: self.menu_button = self.builder.get_object("menu_button") self.recents_button = self.builder.get_object("recents_button") self.export_button = self.builder.get_object("export_button") + export_popover = self.builder.get_object("export_menu") self.preview_switch_button = self.builder.get_object("preview_switch_button") + self.export_button.set_popover(export_popover) + add_menus(self, app) settings = Gtk.Settings.get_default() diff --git a/uberwriter/main_window.py b/uberwriter/main_window.py index 06a0682..c5e3f14 100644 --- a/uberwriter/main_window.py +++ b/uberwriter/main_window.py @@ -544,11 +544,11 @@ class MainWindow(StyledWindow): self.searchreplace.toggle_search(replace=replace) - def open_advanced_export(self, _widget=None, _data=None): + def open_advanced_export(self, export_format): """open the export and advanced export dialog """ - self.export = Export(self.filename) + self.export = Export(self.filename, export_format) self.export.dialog.set_transient_for(self) response = self.export.dialog.run() From ef04a90fd765db22f66bf536a1fd2d6a973271c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Genov=C3=A9s?= Date: Tue, 3 Mar 2020 14:26:32 +0100 Subject: [PATCH 41/45] update advanced export dialog --- data/ui/Export.ui | 72 +-------------- uberwriter/export_dialog.py | 177 ++++++++++++++++++++---------------- 2 files changed, 100 insertions(+), 149 deletions(-) diff --git a/data/ui/Export.ui b/data/ui/Export.ui index 3ea4419..2ad3ff2 100644 --- a/data/ui/Export.ui +++ b/data/ui/Export.ui @@ -507,28 +507,9 @@ - - - text/html - - - - - application/vnd.oasis.opendocument.text - - - - - application/pdf - - False dialog - - cancel_btn - export_btn - True @@ -549,7 +530,6 @@ True False - export_stack @@ -583,58 +563,10 @@ - + True False - crossfade - - - True - False - save - html_filter - - - html - HTML - 2 - - - - - True - False - save - pdf_filter - - - pdf - PDF - - - - - False - label - - - pdf_disabled - PDF - 1 - - - - - True - False - advanced_export_options - - - advanced - Advanced - 4 - - + advanced_export_options False diff --git a/uberwriter/export_dialog.py b/uberwriter/export_dialog.py index f31b7ea..bda3e5c 100644 --- a/uberwriter/export_dialog.py +++ b/uberwriter/export_dialog.py @@ -39,35 +39,6 @@ class Export: __gtype_name__ = "export_dialog" - export_menu = { - "pdf": - { - "extension": "pdf", - "name": "PDF", - "mimetype": "application/pdf", - "dialog": regular_export_dialog() - }, - "html": - { - "extension": "html", - "name": "HTML", - "mimetype": "text/html" - }, - "odt": - { - "extension": "odt", - "name": "ODT", - "mimetype": "application/vnd.oasis.opendocument.text" - }, - "advanced": - { - "extension": "", - "name": "", - "mimetype": "", - "dialog": advanced_export_dialog() - }, - } - formats = [ { "name": "LaTeX (pdf)", @@ -178,54 +149,116 @@ class Export: def __init__(self, filename, export_format): """Set up the export dialog""" - self.builder = Gtk.Builder() - self.builder.add_from_resource( - "/de/wolfvollprecht/UberWriter/ui/Export.ui") - #self.dialog = self.builder.get_object("Export") - self.dialog = Gtk.FileChooserNative.new(_("Export"), - None, - Gtk.FileChooserAction.SAVE, - _("Export to %s") % - self.export_menu[export_format]["extension"], - _("Cancel")) - print(self.export_menu[export_format]["mimetype"]) - filter = Gtk.FileFilter.new() - filter.set_name(self.export_menu[export_format]["name"]) - filter.add_mime_type(self.export_menu[export_format]["mimetype"]) - self.dialog.add_filter(filter) - self.dialog.set_do_overwrite_confirmation(True) - self.dialog.set_current_name("%s.%s" % (filename, self.export_menu[export_format]["extension"])) + self.export_menu = { + "pdf": + { + "extension": "pdf", + "name": "PDF", + "mimetype": "application/pdf", + "dialog": self.regular_export_dialog + }, + "html": + { + "extension": "html", + "name": "HTML", + "mimetype": "text/html", + "dialog": self.regular_export_dialog + }, + "odt": + { + "extension": "odt", + "name": "ODT", + "mimetype": "application/vnd.oasis.opendocument.text", + "dialog": self.regular_export_dialog + }, + "advanced": + { + "extension": "", + "name": "", + "mimetype": "", + "dialog": self.advanced_export_dialog + } + } + + self.filename = filename or _("Untitled document.md") + self.export_format = export_format + + self.dialog = self.export_menu[export_format]["dialog"]() + + + #filechooser.connect("response", self.__on_save_response) #filechooser.run() - self.stack = self.builder.get_object("export_stack") - self.stack_switcher = self.builder.get_object("format_switcher") + #self.stack = self.builder.get_object("export_stack") + #self.stack_switcher = self.builder.get_object("format_switcher") - stack_pdf_disabled = self.builder.get_object("pdf_disabled") + #stack_pdf_disabled = self.builder.get_object("pdf_disabled") filename = filename or _("Untitled document.md") - self.filechoosers = {export_format: self.stack.get_child_by_name(export_format) - for export_format in ["pdf", "html", "advanced"]} - for export_format, filechooser in self.filechoosers.items(): - filechooser.set_do_overwrite_confirmation(True) - filechooser.set_current_folder(os.path.dirname(filename)) - if export_format == "advanced": - self.adv_export_name = self.builder.get_object("advanced_export_name") - self.adv_export_name.set_text(os.path.basename(filename)[:-3]) - else: - filechooser.set_current_name(os.path.basename(filename)[:-2] + export_format) + #self.filechoosers = {export_format: self.stack.get_child_by_name(export_format) + # for export_format in ["pdf", "html", "advanced"]} + #for export_format, filechooser in self.filechoosers.items(): + # filechooser.set_do_overwrite_confirmation(True) + # filechooser.set_current_folder(os.path.dirname(filename)) + # if export_format == "advanced": + # self.adv_export_name = self.builder.get_object("advanced_export_name") + # self.adv_export_name.set_text(os.path.basename(filename)[:-3]) + # else: + # filechooser.set_current_name(os.path.basename(filename)[:-2] + export_format) # Disable pdf if Texlive not installed + #texlive_installed = helpers.exist_executable("pdftex") + + #if not texlive_installed: + # self.filechoosers["pdf"].set_visible(False) + # stack_pdf_disabled.set_visible(True) + # stack_pdf_disabled.set_text(disabled_text()) + # stack_pdf_disabled.set_justify(Gtk.Justification.CENTER) + # self.stack.connect('notify', self.allow_export, 'visible_child_name') + + + + def regular_export_dialog(self): texlive_installed = helpers.exist_executable("pdftex") - if not texlive_installed: - self.filechoosers["pdf"].set_visible(False) - stack_pdf_disabled.set_visible(True) - stack_pdf_disabled.set_text(disabled_text()) - stack_pdf_disabled.set_justify(Gtk.Justification.CENTER) - self.stack.connect('notify', self.allow_export, 'visible_child_name') + if (self.export_menu[self.export_format]["extension"] == "pdf" and + not texlive_installed): + dialog = Gtk.MessageDialog(None, + Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, + Gtk.MessageType.INFO, + Gtk.ButtonsType.CLOSE, + _("Oh, no!") + ) + + dialog.props.secondary_text = _("Seems that you don't have TexLive installed.\n" + + disabled_text()) + + else: + dialog = Gtk.FileChooserNative.new(_("Export"), + None, + Gtk.FileChooserAction.SAVE, + _("Export to %s") % + self.export_menu[self.export_format]["extension"], + _("Cancel")) + dialog_filter = Gtk.FileFilter.new() + dialog_filter.set_name(self.export_menu[self.export_format]["name"]) + dialog_filter.add_mime_type(self.export_menu[self.export_format]["mimetype"]) + dialog.add_filter(dialog_filter) + dialog.set_do_overwrite_confirmation(True) + dialog.set_current_folder(os.path.dirname(self.filename)) + dialog.set_current_name("%s.%s" % (os.path.basename(self.filename)[:-2], + self.export_menu[self.export_format]["extension"])) + + return dialog + + def advanced_export_dialog(self): + self.builder = Gtk.Builder() + self.builder.add_from_resource( + "/de/wolfvollprecht/UberWriter/ui/Export.ui") + return self.builder.get_object("Export") self.builder.get_object("highlight_style").set_active(0) @@ -243,8 +276,6 @@ class Export: self.format_field.add_attribute(format_renderer, "text", 1) self.format_field.set_active(0) - def regular_export_dialog(): - def export(self, text=""): """Export the given text using the specified format. @@ -367,18 +398,6 @@ class Export: return args - def allow_export(self, widget, data, signal): - """Disable export button if the visible child is "pdf_disabled" - """ - - del widget, data, signal - - export_btn = self.builder.get_object("export_btn") - - if self.stack.get_visible_child_name() == "pdf_disabled": - export_btn.set_sensitive(False) - else: - export_btn.set_sensitive(True) def disabled_text(): From 7a8d3a8459e4f83f71f0cdbf315aff9c045491a1 Mon Sep 17 00:00:00 2001 From: Manuel Genoves Date: Wed, 11 Mar 2020 02:54:56 +0100 Subject: [PATCH 42/45] make new export dialogs actually work --- data/ui/Export.ui | 16 +++++--- uberwriter/export_dialog.py | 79 ++++++++++++++++--------------------- uberwriter/main_window.py | 21 +--------- 3 files changed, 47 insertions(+), 69 deletions(-) diff --git a/data/ui/Export.ui b/data/ui/Export.ui index 2ad3ff2..11000f2 100644 --- a/data/ui/Export.ui +++ b/data/ui/Export.ui @@ -500,6 +500,9 @@ 1 + 0 @@ -510,10 +513,15 @@ False dialog + + cancel_btn + export_btn + True False + False gtk-cancel @@ -526,12 +534,6 @@ 1 - - - True - False - - Export @@ -566,6 +568,8 @@ True False + select-folder + True advanced_export_options diff --git a/uberwriter/export_dialog.py b/uberwriter/export_dialog.py index bda3e5c..df7b21d 100644 --- a/uberwriter/export_dialog.py +++ b/uberwriter/export_dialog.py @@ -24,7 +24,7 @@ from gettext import gettext as _ import gi gi.require_version('Gtk', '3.0') -from gi.repository import Gtk +from gi.repository import Gtk, GLib from uberwriter import helpers from uberwriter.theme import Theme @@ -147,7 +147,7 @@ class Export: } ] - def __init__(self, filename, export_format): + def __init__(self, filename, export_format, text): """Set up the export dialog""" self.export_menu = { @@ -186,41 +186,23 @@ class Export: self.dialog = self.export_menu[export_format]["dialog"]() + response = self.dialog.run() + + if response == Gtk.ResponseType.ACCEPT: + try: + self.export(export_format, text) + except (NotADirectoryError, Exception) as e: + dialog = Gtk.MessageDialog(None, + Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, + Gtk.MessageType.ERROR, + Gtk.ButtonsType.CLOSE, + _("An error happened while trying to export:\n\n{err_msg}") + .format(err_msg= str(e).encode().decode("unicode-escape")) + ) + dialog.run() + dialog.destroy() - #filechooser.connect("response", self.__on_save_response) - #filechooser.run() - - - #self.stack = self.builder.get_object("export_stack") - #self.stack_switcher = self.builder.get_object("format_switcher") - - #stack_pdf_disabled = self.builder.get_object("pdf_disabled") - filename = filename or _("Untitled document.md") - - #self.filechoosers = {export_format: self.stack.get_child_by_name(export_format) - # for export_format in ["pdf", "html", "advanced"]} - #for export_format, filechooser in self.filechoosers.items(): - # filechooser.set_do_overwrite_confirmation(True) - # filechooser.set_current_folder(os.path.dirname(filename)) - # if export_format == "advanced": - # self.adv_export_name = self.builder.get_object("advanced_export_name") - # self.adv_export_name.set_text(os.path.basename(filename)[:-3]) - # else: - # filechooser.set_current_name(os.path.basename(filename)[:-2] + export_format) - - # Disable pdf if Texlive not installed - #texlive_installed = helpers.exist_executable("pdftex") - - #if not texlive_installed: - # self.filechoosers["pdf"].set_visible(False) - # stack_pdf_disabled.set_visible(True) - # stack_pdf_disabled.set_text(disabled_text()) - # stack_pdf_disabled.set_justify(Gtk.Justification.CENTER) - # self.stack.connect('notify', self.allow_export, 'visible_child_name') - - - def regular_export_dialog(self): texlive_installed = helpers.exist_executable("pdftex") @@ -235,7 +217,6 @@ class Export: dialog.props.secondary_text = _("Seems that you don't have TexLive installed.\n" + disabled_text()) - else: dialog = Gtk.FileChooserNative.new(_("Export"), None, @@ -249,19 +230,18 @@ class Export: dialog.add_filter(dialog_filter) dialog.set_do_overwrite_confirmation(True) dialog.set_current_folder(os.path.dirname(self.filename)) - dialog.set_current_name("%s.%s" % (os.path.basename(self.filename)[:-2], - self.export_menu[self.export_format]["extension"])) + dialog.set_current_name(os.path.basename(self.filename)[:-2] + + self.export_menu[self.export_format]["extension"]) return dialog def advanced_export_dialog(self): + self.builder = Gtk.Builder() self.builder.add_from_resource( "/de/wolfvollprecht/UberWriter/ui/Export.ui") - return self.builder.get_object("Export") self.builder.get_object("highlight_style").set_active(0) - self.builder.get_object("css_filechooser").set_uri( helpers.path_to_file(Theme.get_current().web_css_path)) @@ -276,8 +256,14 @@ class Export: self.format_field.add_attribute(format_renderer, "text", 1) self.format_field.set_active(0) + self.adv_export_folder = self.builder.get_object("advanced") - def export(self, text=""): + self.adv_export_name = self.builder.get_object("advanced_export_name") + self.adv_export_name.set_text(os.path.basename(self.filename)[:-3]) + + return self.builder.get_object("Export") + + def export(self, export_type, text=""): """Export the given text using the specified format. For advanced export, this includes special flags for the enabled options. @@ -285,11 +271,16 @@ class Export: text {str} -- Text to export (default: {""}) """ - export_type = self.stack.get_visible_child_name() args = [] if export_type == "advanced": filename = self.adv_export_name.get_text() - output_dir = os.path.abspath(self.filechoosers["advanced"].get_current_folder()) + + # TODO: use walrust operator + output_uri = self.adv_export_folder.get_uri() + if output_uri: + output_dir = GLib.filename_from_uri(output_uri)[0] + else: + raise NotADirectoryError(_("A folder must be selected before proceeding")) basename = os.path.basename(filename) fmt = self.formats[self.format_field.get_active()] @@ -304,7 +295,7 @@ class Export: args.extend(self.get_advanced_arguments()) else: - filename = self.filechoosers[export_type].get_filename() + filename = self.dialog.get_filename() if filename.endswith("." + export_type): filename = filename[:-len(export_type)-1] output_dir = os.path.abspath(os.path.join(filename, os.path.pardir)) diff --git a/uberwriter/main_window.py b/uberwriter/main_window.py index c5e3f14..0190155 100644 --- a/uberwriter/main_window.py +++ b/uberwriter/main_window.py @@ -547,26 +547,9 @@ class MainWindow(StyledWindow): def open_advanced_export(self, export_format): """open the export and advanced export dialog """ + text = bytes(self.text_view.get_text(), "utf-8") - self.export = Export(self.filename, export_format) - self.export.dialog.set_transient_for(self) - - response = self.export.dialog.run() - if response == 1: - try: - self.export.export(bytes(self.text_view.get_text(), "utf-8")) - except Exception as e: - dialog = Gtk.MessageDialog(self, - Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, - Gtk.MessageType.ERROR, - Gtk.ButtonsType.CLOSE, - _("An error happened while trying to export:\n\n{err_msg}") - .format(err_msg= str(e).encode().decode("unicode-escape")) - ) - dialog.run() - dialog.destroy() - - self.export.dialog.destroy() + self.export = Export(self.filename, export_format, text) def open_recent(self, _widget, data=None): """open the given recent document From 4a85f21d35dd91f744600b60f3b1322c6b0987a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Genov=C3=A9s?= Date: Wed, 11 Mar 2020 21:08:16 +0100 Subject: [PATCH 43/45] remove event catcher when not needed --- data/ui/Window.ui | 4 ++-- uberwriter/main_window.py | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/data/ui/Window.ui b/data/ui/Window.ui index e62fc92..d3bb82f 100644 --- a/data/ui/Window.ui +++ b/data/ui/Window.ui @@ -1,5 +1,5 @@ - + @@ -410,6 +410,7 @@ 1 False start + False @@ -418,7 +419,6 @@ 60 - True False start False diff --git a/uberwriter/main_window.py b/uberwriter/main_window.py index 0190155..d1d8a31 100644 --- a/uberwriter/main_window.py +++ b/uberwriter/main_window.py @@ -568,6 +568,7 @@ class MainWindow(StyledWindow): def reveal_headerbar_bottombar(self, _widget=None, _data=None): def __reveal_hb(): + self.headerbar_eventbox.hide() self.headerbar.hb_revealer.set_reveal_child(True) self.get_style_context().remove_class("focus") return False @@ -603,7 +604,7 @@ class MainWindow(StyledWindow): self.bottombar_visible = False - + self.headerbar_eventbox.show() self.buffer_modified_for_status_bar = False def on_delete_called(self, _widget, _data=None): From c9b4bdd1101daaa0ec292890f31f77c591c592c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Genov=C3=A9s?= Date: Wed, 11 Mar 2020 21:20:08 +0100 Subject: [PATCH 44/45] add tooltip to headerbar --- data/ui/Window.ui | 1 - uberwriter/main_window.py | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/data/ui/Window.ui b/data/ui/Window.ui index d3bb82f..fabc638 100644 --- a/data/ui/Window.ui +++ b/data/ui/Window.ui @@ -410,7 +410,6 @@ 1 False start - False diff --git a/uberwriter/main_window.py b/uberwriter/main_window.py index d1d8a31..3a7cf82 100644 --- a/uberwriter/main_window.py +++ b/uberwriter/main_window.py @@ -634,6 +634,8 @@ class MainWindow(StyledWindow): self.headerbar.hb.props.subtitle = subtitle self.dm_headerbar.hb.props.subtitle = subtitle self.fs_headerbar.hb.props.subtitle = subtitle + self.headerbar.hb.set_tooltip_text(subtitle) + self.fs_headerbar.hb.set_tooltip_text(subtitle) self.set_title(title) def set_filename(self, filename=None): From 5f3bbb9fd918b5ff534aa443b77c849a062e3028 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Genov=C3=A9s?= Date: Thu, 12 Mar 2020 01:39:13 +0100 Subject: [PATCH 45/45] hide revealer when not needed --- uberwriter/headerbars.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/uberwriter/headerbars.py b/uberwriter/headerbars.py index d72f3b0..f2243df 100644 --- a/uberwriter/headerbars.py +++ b/uberwriter/headerbars.py @@ -227,6 +227,7 @@ class DummyHeaderbar(BaseHeaderbar): """show dummy headerbar: It appears instantly to inmediatly fade away """ + self.hb_revealer.show() self.hb_revealer.set_transition_duration(0) self.hb_revealer.set_reveal_child(True) self.hb_revealer.set_transition_duration(600) @@ -243,6 +244,7 @@ class DummyHeaderbar(BaseHeaderbar): def hide_dm_hb_with_wait(self): self.hb_revealer.set_transition_duration(0) self.hb_revealer.set_reveal_child(False) + self.hb_revealer.hide() return False