2018-07-29 11:44:07 +00:00
|
|
|
# This program is free software: you can redistribute it and/or modify it
|
|
|
|
# under the terms of the GNU General Public License version 3, as published
|
2018-03-22 00:21:58 +00:00
|
|
|
# by the Free Software Foundation.
|
2018-07-29 11:44:07 +00:00
|
|
|
#
|
|
|
|
# This program is distributed in the hope that it will be useful, but
|
|
|
|
# WITHOUT ANY WARRANTY; without even the implied warranties of
|
|
|
|
# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
|
2018-03-22 00:21:58 +00:00
|
|
|
# PURPOSE. See the GNU General Public License for more details.
|
2018-07-29 11:44:07 +00:00
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU General Public License along
|
2018-03-22 00:21:58 +00:00
|
|
|
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
2018-03-27 18:49:13 +00:00
|
|
|
import argparse
|
2018-07-29 11:44:07 +00:00
|
|
|
from gettext import gettext as _
|
2018-03-22 12:13:25 +00:00
|
|
|
|
2018-03-20 23:20:49 +00:00
|
|
|
import gi
|
2019-03-09 19:43:48 +00:00
|
|
|
|
2018-07-29 11:44:07 +00:00
|
|
|
gi.require_version('Gtk', '3.0') # pylint: disable=wrong-import-position
|
2019-04-15 01:35:24 +00:00
|
|
|
from gi.repository import GLib, Gio, Gtk, GdkPixbuf
|
2018-03-20 23:20:49 +00:00
|
|
|
|
2019-04-01 20:40:59 +00:00
|
|
|
from uberwriter import window
|
|
|
|
from uberwriter.settings import Settings
|
2019-04-01 16:00:17 +00:00
|
|
|
from uberwriter.helpers import set_up_logging
|
2019-04-01 20:40:59 +00:00
|
|
|
from uberwriter.preferences_dialog import PreferencesDialog
|
2019-04-01 16:00:17 +00:00
|
|
|
from uberwriter.helpers import get_builder, get_media_path
|
2018-07-29 11:44:07 +00:00
|
|
|
|
2019-01-27 19:21:35 +00:00
|
|
|
|
2018-03-20 23:20:49 +00:00
|
|
|
class Application(Gtk.Application):
|
|
|
|
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
super().__init__(*args, application_id="de.wolfvollprecht.UberWriter",
|
|
|
|
flags=Gio.ApplicationFlags.HANDLES_COMMAND_LINE,
|
|
|
|
**kwargs)
|
|
|
|
self.window = None
|
2018-04-13 18:17:32 +00:00
|
|
|
self.settings = Settings.new()
|
2018-07-29 11:44:07 +00:00
|
|
|
|
2018-10-14 15:48:25 +00:00
|
|
|
def do_startup(self, *args, **kwargs):
|
2018-11-23 20:58:29 +00:00
|
|
|
|
2018-03-20 23:20:49 +00:00
|
|
|
Gtk.Application.do_startup(self)
|
|
|
|
|
2019-04-15 01:35:24 +00:00
|
|
|
self.settings.connect("changed", self.on_settings_changed)
|
2018-07-29 11:44:07 +00:00
|
|
|
|
2019-04-15 01:35:24 +00:00
|
|
|
action = Gio.SimpleAction.new("new", None)
|
|
|
|
action.connect("activate", self.on_new)
|
2018-03-22 00:21:58 +00:00
|
|
|
self.add_action(action)
|
2018-07-29 11:44:07 +00:00
|
|
|
|
2019-04-15 01:35:24 +00:00
|
|
|
action = Gio.SimpleAction.new("open", None)
|
|
|
|
action.connect("activate", self.on_open)
|
2018-03-22 00:21:58 +00:00
|
|
|
self.add_action(action)
|
2018-03-20 23:20:49 +00:00
|
|
|
|
2019-04-15 01:35:24 +00:00
|
|
|
action = Gio.SimpleAction.new("open_recent", None)
|
|
|
|
action.connect("activate", self.on_open_recent)
|
2018-03-20 23:20:49 +00:00
|
|
|
self.add_action(action)
|
|
|
|
|
2019-04-15 01:35:24 +00:00
|
|
|
action = Gio.SimpleAction.new("save", None)
|
|
|
|
action.connect("activate", self.on_save)
|
2019-03-29 00:46:53 +00:00
|
|
|
self.add_action(action)
|
|
|
|
|
2019-04-15 01:35:24 +00:00
|
|
|
action = Gio.SimpleAction.new("search", None)
|
|
|
|
action.connect("activate", self.on_search)
|
2018-06-19 18:36:16 +00:00
|
|
|
self.add_action(action)
|
|
|
|
|
2019-04-15 01:35:24 +00:00
|
|
|
action = Gio.SimpleAction.new_stateful(
|
|
|
|
"focus_mode", None, GLib.Variant.new_boolean(False))
|
2018-06-19 19:43:49 +00:00
|
|
|
action.connect("change-state", self.on_focus_mode)
|
|
|
|
self.add_action(action)
|
|
|
|
|
2019-04-15 01:35:24 +00:00
|
|
|
action = Gio.SimpleAction.new_stateful(
|
|
|
|
"hemingway_mode", None, GLib.Variant.new_boolean(False))
|
2019-03-27 02:29:29 +00:00
|
|
|
action.connect("change-state", self.on_hemingway_mode)
|
|
|
|
self.add_action(action)
|
|
|
|
|
2019-04-15 01:35:24 +00:00
|
|
|
action = Gio.SimpleAction.new_stateful(
|
|
|
|
"preview", None, GLib.Variant.new_boolean(False))
|
2018-06-23 19:34:53 +00:00
|
|
|
action.connect("change-state", self.on_preview)
|
|
|
|
self.add_action(action)
|
|
|
|
|
2019-04-15 01:35:24 +00:00
|
|
|
action = Gio.SimpleAction.new_stateful(
|
|
|
|
"fullscreen", None, GLib.Variant.new_boolean(False))
|
|
|
|
action.connect("change-state", self.on_fullscreen)
|
2018-06-28 00:03:48 +00:00
|
|
|
self.add_action(action)
|
|
|
|
|
2019-04-15 01:35:24 +00:00
|
|
|
action = Gio.SimpleAction.new("save_as", None)
|
|
|
|
action.connect("activate", self.on_save_as)
|
2018-06-28 00:03:48 +00:00
|
|
|
self.add_action(action)
|
|
|
|
|
2019-04-15 01:35:24 +00:00
|
|
|
action = Gio.SimpleAction.new("export", None)
|
|
|
|
action.connect("activate", self.on_export)
|
2018-06-28 00:03:48 +00:00
|
|
|
self.add_action(action)
|
|
|
|
|
2019-04-15 01:35:24 +00:00
|
|
|
action = Gio.SimpleAction.new("copy_html", None)
|
|
|
|
action.connect("activate", self.on_copy_html)
|
2018-06-28 00:03:48 +00:00
|
|
|
self.add_action(action)
|
|
|
|
|
2019-04-15 01:35:24 +00:00
|
|
|
action = Gio.SimpleAction.new("preferences", None)
|
|
|
|
action.connect("activate", self.on_preferences)
|
2018-06-28 00:03:48 +00:00
|
|
|
self.add_action(action)
|
|
|
|
|
2019-04-15 01:35:24 +00:00
|
|
|
action = Gio.SimpleAction.new("shortcuts", None)
|
|
|
|
action.connect("activate", self.on_shortcuts)
|
2018-06-28 00:03:48 +00:00
|
|
|
self.add_action(action)
|
|
|
|
|
2019-04-15 01:35:24 +00:00
|
|
|
action = Gio.SimpleAction.new("open_tutorial", None)
|
|
|
|
action.connect("activate", self.on_open_tutorial)
|
2018-06-28 00:03:48 +00:00
|
|
|
self.add_action(action)
|
|
|
|
|
2019-04-15 01:35:24 +00:00
|
|
|
action = Gio.SimpleAction.new("about", None)
|
|
|
|
action.connect("activate", self.on_about)
|
2018-06-28 00:03:48 +00:00
|
|
|
self.add_action(action)
|
|
|
|
|
2019-04-15 01:35:24 +00:00
|
|
|
action = Gio.SimpleAction.new("quit", None)
|
|
|
|
action.connect("activate", self.on_quit)
|
2018-07-01 01:14:11 +00:00
|
|
|
self.add_action(action)
|
|
|
|
|
2018-10-14 15:48:25 +00:00
|
|
|
# Shortcuts
|
2018-06-23 19:34:53 +00:00
|
|
|
|
2019-04-06 18:19:53 +00:00
|
|
|
# TODO: be aware that a couple of shortcuts are defined in _gtk_base.css
|
|
|
|
|
2018-07-29 11:44:07 +00:00
|
|
|
self.set_accels_for_action("app.focus_mode", ["<Ctl>d"])
|
2019-03-27 02:29:29 +00:00
|
|
|
self.set_accels_for_action("app.hemingway_mode", ["<Ctl>t"])
|
2018-07-29 11:44:07 +00:00
|
|
|
self.set_accels_for_action("app.fullscreen", ["F11"])
|
|
|
|
self.set_accels_for_action("app.preview", ["<Ctl>p"])
|
|
|
|
self.set_accels_for_action("app.search", ["<Ctl>f"])
|
|
|
|
self.set_accels_for_action("app.spellcheck", ["F7"])
|
2018-06-28 00:16:17 +00:00
|
|
|
|
2018-07-29 11:44:07 +00:00
|
|
|
self.set_accels_for_action("app.new", ["<Ctl>n"])
|
|
|
|
self.set_accels_for_action("app.open", ["<Ctl>o"])
|
|
|
|
self.set_accels_for_action("app.save", ["<Ctl>s"])
|
|
|
|
self.set_accels_for_action("app.save_as", ["<Ctl><shift>s"])
|
2019-04-06 18:19:53 +00:00
|
|
|
self.set_accels_for_action("app.quit", ["<Ctl>w", "<Ctl>q"])
|
2018-03-21 00:43:01 +00:00
|
|
|
|
2018-10-14 15:48:25 +00:00
|
|
|
def do_activate(self, *args, **kwargs):
|
2018-03-20 23:20:49 +00:00
|
|
|
# We only allow a single window and raise any existing ones
|
|
|
|
if not self.window:
|
|
|
|
# Windows are associated with the application
|
|
|
|
# when the last one is closed the application shuts down
|
2018-03-21 00:43:01 +00:00
|
|
|
# self.window = Window(application=self, title="UberWriter")
|
2019-04-01 20:40:59 +00:00
|
|
|
self.window = window.Window(self)
|
2018-07-29 11:44:07 +00:00
|
|
|
if self.args:
|
|
|
|
self.window.load_file(self.args[0])
|
2018-03-20 23:20:49 +00:00
|
|
|
|
|
|
|
self.window.present()
|
|
|
|
|
2018-07-29 11:44:07 +00:00
|
|
|
def do_command_line(self, _command_line):
|
2018-03-27 18:49:13 +00:00
|
|
|
"""Support for command line options"""
|
|
|
|
parser = argparse.ArgumentParser()
|
|
|
|
parser.add_argument(
|
|
|
|
"-v", "--verbose", action="count", dest="verbose",
|
2019-04-01 16:00:17 +00:00
|
|
|
help=_("Show debug messages (-vv debugs uberwriter also)"))
|
2018-03-27 18:49:13 +00:00
|
|
|
parser.add_argument(
|
|
|
|
"-e", "--experimental-features", help=_("Use experimental features"),
|
2019-04-15 01:35:24 +00:00
|
|
|
action='store_true')
|
2018-03-27 18:49:13 +00:00
|
|
|
(self.options, self.args) = parser.parse_known_args()
|
|
|
|
|
|
|
|
set_up_logging(self.options)
|
2018-07-29 11:44:07 +00:00
|
|
|
|
2018-03-20 23:20:49 +00:00
|
|
|
self.activate()
|
|
|
|
return 0
|
|
|
|
|
2019-04-15 01:35:24 +00:00
|
|
|
def on_settings_changed(self, settings, key):
|
|
|
|
if key == "dark-mode-auto" or key == "dark-mode":
|
|
|
|
self.window.apply_current_theme()
|
|
|
|
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()
|
2018-07-29 11:44:07 +00:00
|
|
|
|
2019-04-15 01:35:24 +00:00
|
|
|
def on_new(self, _action, _value):
|
|
|
|
self.window.new_document()
|
2019-03-29 00:46:53 +00:00
|
|
|
|
2019-04-15 01:35:24 +00:00
|
|
|
def on_open(self, _action, _value):
|
|
|
|
self.window.open_document()
|
2019-03-29 00:46:53 +00:00
|
|
|
|
2019-04-15 01:35:24 +00:00
|
|
|
def on_open_recent(self, file):
|
|
|
|
self.window.load_file(file.get_current_uri())
|
2018-06-19 18:36:16 +00:00
|
|
|
|
2019-04-15 01:35:24 +00:00
|
|
|
def on_save(self, _action, _value):
|
|
|
|
self.window.save_document()
|
2019-03-29 00:46:53 +00:00
|
|
|
|
2019-04-15 01:35:24 +00:00
|
|
|
def on_search(self, _action, _value):
|
|
|
|
self.window.open_search_and_replace()
|
2018-06-19 18:36:16 +00:00
|
|
|
|
2018-06-19 19:43:49 +00:00
|
|
|
def on_focus_mode(self, action, value):
|
|
|
|
action.set_state(value)
|
2019-03-27 02:29:29 +00:00
|
|
|
self.window.set_focus_mode(value)
|
|
|
|
|
|
|
|
def on_hemingway_mode(self, action, value):
|
|
|
|
action.set_state(value)
|
|
|
|
self.window.set_hemingway_mode(value)
|
2018-06-19 19:43:49 +00:00
|
|
|
|
2018-06-23 19:34:53 +00:00
|
|
|
def on_preview(self, action, value):
|
|
|
|
action.set_state(value)
|
2019-03-24 04:57:06 +00:00
|
|
|
self.window.toggle_preview(value)
|
2018-06-23 19:34:53 +00:00
|
|
|
|
2019-04-15 01:35:24 +00:00
|
|
|
def on_fullscreen(self, action, value):
|
2018-12-14 19:01:00 +00:00
|
|
|
action.set_state(value)
|
2019-04-15 01:35:24 +00:00
|
|
|
self.window.set_fullscreen(value)
|
2018-07-29 11:44:07 +00:00
|
|
|
|
|
|
|
def on_save_as(self, _action, _value):
|
2018-06-28 00:03:48 +00:00
|
|
|
self.window.save_document_as()
|
2018-07-29 11:44:07 +00:00
|
|
|
|
|
|
|
def on_export(self, _action, _value):
|
2018-06-28 00:03:48 +00:00
|
|
|
self.window.open_advanced_export()
|
2018-07-29 11:44:07 +00:00
|
|
|
|
2019-04-15 01:35:24 +00:00
|
|
|
def on_copy_html(self, _action, _value):
|
2018-06-28 00:03:48 +00:00
|
|
|
self.window.copy_html_to_clipboard()
|
2018-07-01 01:14:11 +00:00
|
|
|
|
2018-07-29 11:44:07 +00:00
|
|
|
def on_preferences(self, _action, _value):
|
2019-04-15 01:35:24 +00:00
|
|
|
PreferencesDialog(self.settings).show(self.window)
|
|
|
|
|
|
|
|
def on_shortcuts(self, _action, _param):
|
|
|
|
builder = get_builder('Shortcuts')
|
|
|
|
builder.get_object("shortcuts").set_transient_for(self.window)
|
|
|
|
builder.get_object("shortcuts").show()
|
|
|
|
|
|
|
|
def on_open_tutorial(self, _action, _value):
|
|
|
|
self.window.open_uberwriter_markdown()
|
|
|
|
|
|
|
|
def on_about(self, _action, _param):
|
|
|
|
builder = get_builder('About')
|
|
|
|
about_dialog = builder.get_object("AboutDialog")
|
|
|
|
about_dialog.set_transient_for(self.window)
|
|
|
|
|
|
|
|
logo_file = get_media_path("de.wolfvollprecht.UberWriter.svg")
|
|
|
|
logo = GdkPixbuf.Pixbuf.new_from_file(logo_file)
|
|
|
|
|
|
|
|
about_dialog.set_logo(logo)
|
|
|
|
about_dialog.present()
|
2018-07-29 11:44:07 +00:00
|
|
|
|
|
|
|
def on_quit(self, _action, _param):
|
2018-03-20 23:20:49 +00:00
|
|
|
self.quit()
|
|
|
|
|
2018-03-21 00:43:01 +00:00
|
|
|
# ~ if __name__ == "__main__":
|
|
|
|
# ~ app = Application()
|
|
|
|
# ~ app.run(sys.argv)
|