Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion scriptorium/dialogs/preferences.blp
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,25 @@ template $ScrptPreferencesDialog: Adw.PreferencesDialog {
title: _("Restore Previous Session");
subtitle: _("Open the last project when starting Scriptorium");
}

Adw.ActionRow projects_directory {
title: _("Data directory");
subtitle: _("");

[suffix]
Gtk.Button projects_directory_button {
icon-name: "folder-symbolic";
tooltip-text: _("Change storage location");
valign: center;
clicked => $on_projects_directory_button_clicked();
}
}
}
}

Adw.PreferencesPage {
title: _("Editor");
icon-name: "settings-symbolic";
icon-name: "edit-symbolic";

Adw.PreferencesGroup {
title: _("Preview");
Expand Down Expand Up @@ -95,3 +108,8 @@ template $ScrptPreferencesDialog: Adw.PreferencesDialog {
}
}
}

Gtk.FileDialog projects_directory_dialog {
title: _("Select storage location");
modal: true;
}
46 changes: 42 additions & 4 deletions scriptorium/dialogs/preferences.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
#
# SPDX-License-Identifier: GPL-3.0-or-later
"""Dialog to select scenes in Scriptorium."""
from gi.repository import Adw, Gtk, Gio, Pango
from gi.repository import Adw, Gtk, Gio, Pango, GLib
from scriptorium.globals import BASE
from scriptorium.utils import html_to_buffer
from gettext import gettext as _
Expand All @@ -27,9 +27,9 @@
logger = logging.getLogger(__name__)

PLACEHOLDER_TEXT = _(
"<p>This is a <hint>placeholder text</hint> to <warning>select</warning>"
"<p>This is a <hint>placeholder text</hint> to <warning>select</warning> "
"the font of the scene editor.</p>"
"<p>You can also see how <error>annotations</error> are shown and how words"
"<p>You can also see how <error>annotations</error> are shown and how words "
"with an <em>emphasis</em> or noted as <strong>strong</strong> will appear.</p>"
)
UNDERLINE_OPTIONS = ["single", "double", "dashed"]
Expand All @@ -39,13 +39,20 @@
class ScrptPreferencesDialog(Adw.PreferencesDialog):
__gtype_name__ = "ScrptPreferencesDialog"

# Setting to open the last project on application launch
open_last_project = Gtk.Template.Child()

# Settings for the editor
text_view = Gtk.Template.Child()
font_dialog_button = Gtk.Template.Child()
editor_line_height = Gtk.Template.Child()
font_dialog_button = Gtk.Template.Child()
editor_underline_style = Gtk.Template.Child()

# Information about the storage location for manuscripts
projects_directory: Adw.ActionRow = Gtk.Template.Child()
projects_directory_button: Gtk.Button = Gtk.Template.Child()
projects_directory_dialog: Gtk.FileDialog = Gtk.Template.Child()

def __init__(self):
"""Create a new instance of the class."""
super().__init__()
Expand All @@ -62,6 +69,13 @@ def __init__(self):
Gio.SettingsBindFlags.DEFAULT
)

settings.bind(
"manuscripts-folder",
self.projects_directory,
"subtitle",
Gio.SettingsBindFlags.DEFAULT
)

settings.bind(
"editor-line-height",
self.editor_line_height,
Expand Down Expand Up @@ -111,3 +125,27 @@ def on_underline_style_selected(self, _combo, _value):
UNDERLINE_OPTIONS[selected_value]
)

@Gtk.Template.Callback()
def on_projects_directory_button_clicked(self, _button):
"""Handle a click to select storage location."""
def on_folder_selected(dialog, result):
try:
folder = dialog.select_folder_finish(result)
except GLib.Error as e:
logger.info(f"Error when changing data folder: {e}")
return
self.projects_directory.set_subtitle(folder.get_path())

# Configure the dialog to open the current storage value
self.projects_directory_dialog.set_initial_folder(
Gio.File.new_for_path(self.projects_directory.get_subtitle())
)

# Open the dialog
self.projects_directory_dialog.select_folder(
parent=self.get_root(),
cancellable=None,
callback=on_folder_selected,
)


3 changes: 2 additions & 1 deletion scriptorium/views/editor.blp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ using Adw 1;
template $ScrptEditorView: Adw.NavigationPage {
title: _("Editor");
tag: "editor";
unrealize => $on_editorview_closed();
realize => $on_scrpteditorview_realize();
unrealize => $on_scrpteditorview_unrealize();

child: Adw.ToolbarView {
top-bar-style: raised_border;
Expand Down
18 changes: 11 additions & 7 deletions scriptorium/views/editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class ScrptEditorView(Adw.NavigationPage):
plan_page = Gtk.Template.Child()
file_filter_image = Gtk.Template.Child()

def __init__(self):
def __init__(self, project: Project):
"""Create a new instance of the editor."""
super().__init__()

Expand Down Expand Up @@ -114,16 +114,20 @@ def __init__(self):
)
group.add_action(action)

def connect_to_project(self, project: Project):
# Keep track of the project the editor is associated to
# Keep track of the project for this editor window
self.project = project

self.write_page.connect_to_project(project)
self.publish_page.connect_to_project(project)
self.plan_page.connect_to_project(project)
@Gtk.Template.Callback()
def on_scrpteditorview_realize(self, _editorview):
"""Called when the editor widgets are all created."""
if self.project is not None:
logger.info("Editor is open, connect the tabs to the manuscript")
self.plan_page.connect_to_project(self.project)
self.write_page.connect_to_project(self.project)
self.publish_page.connect_to_project(self.project)

@Gtk.Template.Callback()
def on_editorview_closed(self, _editorview):
def on_scrpteditorview_unrealize(self, _editorview):
"""Handle a request to close the editor."""
if self.project is not None:
logger.info("Editor is closed, saving the manuscript")
Expand Down
1 change: 1 addition & 0 deletions scriptorium/views/library.blp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ template $ScrptLibraryView: Adw.NavigationPage {
tag: "library";

shown => $on_scrptlibraryview_shown();
realize => $on_scrptlibraryview_realize();

child: Adw.ToolbarView {
[top]
Expand Down
73 changes: 48 additions & 25 deletions scriptorium/views/library.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
from gi.repository import Adw, GObject, Gio, Gtk
from gi.repository import GLib

from scriptorium.views import ScrptEditorView

from scriptorium.globals import BASE
from scriptorium.models import Library, Project
from scriptorium.dialogs import ScrptAddDialog
Expand All @@ -38,8 +40,6 @@ class ScrptLibraryView(Adw.NavigationPage):
# The Library is the data model holding the list of projects
library: Library = Library()

selected_project = GObject.Property(type=Project)

# The base path of all the manuscripts
manuscripts_base_path = GObject.Property(type=str)

Expand All @@ -55,8 +55,10 @@ class ScrptLibraryView(Adw.NavigationPage):

identifier = Gtk.Template.Child()

def __init__(self, **kwargs):
super().__init__(**kwargs)
def __init__(self, manuscripts_base_path):
super().__init__()

self.manuscripts_base_path = manuscripts_base_path

# Connect an instance of the theme button to the menu
popover = self.win_menu.get_popover()
Expand All @@ -83,6 +85,7 @@ def __init__(self, **kwargs):
group.add_action(action)

# Signal to the list model to detect when content is available
# this is useful when a new Manuscript is created
self.library.projects.connect(
"items-changed",
self.on_grid_content_changed
Expand All @@ -98,16 +101,25 @@ def __init__(self, **kwargs):

@Gtk.Template.Callback()
def on_scrptlibraryview_shown(self, _src):
"""Update the selected project to None."""
"""
Called when the window becomes visible. This is likely to happen
when the editor is closed so we use the callback to unset the selected
manuscript.
"""
logger.info("Shown")

# Disable the current selection
selection_model = self.projects_grid.get_model()
selection_model.set_selected(Gtk.INVALID_LIST_POSITION)

# Set the window to no project opened
window = self.props.root
if window is not None:
window.project = None
@Gtk.Template.Callback()
def on_scrptlibraryview_realize(self, _src):
logger.info(f"Opening library at {self.manuscripts_base_path}")

# Connect the library to the folder
self.library.open_folder(self.manuscripts_base_path)

self.open_last_project()

@Gtk.Template.Callback()
def on_add_manuscript_clicked(self, _button):
Expand Down Expand Up @@ -142,20 +154,40 @@ def on_grid_content_changed(self, list_model, _position, _added, _removed):

def on_selection_changed(self, selection_model, position, n_items):
"""
Called when a manuscript is selected
Called when a manuscript is selected in the list.
"""
# Get the selected project
selected_item = selection_model.get_selected_item()
if selected_item is not None:
selected_project = selection_model.get_selected_item()
selected_project = selection_model.get_selected_item()

# Keep track of the last manuscript selected (this could be None)
logger.info(f"Set last selected project to {selected_project}")
settings = Gio.Settings(schema_id="io.github.cgueret.Scriptorium")
settings.set_string(
"last-manuscript-name",
selected_project.identifier if selected_project is not None else ""
)

selected_project = selection_model.get_selected_item()
if selected_project is not None:
logger.info(f"Selected project {selected_project.identifier}")
if not selected_project.can_be_opened:
self.migrate_dialog.choose(self)
#selection_model.set_selected(Gtk.INVALID_LIST_POSITION)
else:
# Open the project
window = self.props.root
window.project = selected_project
self._open_project(selected_project)

def _open_project(self, project):
"""
Open a selected project and remember it as the last project selected
"""
# If we did select something, open the editor
if project is not None:
logger.info(f"\"{project.title}\": create and open editor")

# Create an editor navigation page and push it to the navigation
editor_page = ScrptEditorView(project)
self.get_parent().push(editor_page)

def open_last_project(self):
"""Check if we need to open the last project."""
Expand All @@ -182,15 +214,6 @@ def open_last_project(self):
if model[index].can_be_opened:
model.select_item(index, True)

def on_projects_base_path_changed(self, window, parameter):
base_path = window.get_property(parameter.name)
logger.info(f"Opening library at {base_path}")

# Connect the library to the folder
self.library.open_folder(base_path)

self.open_last_project()

@Gtk.Template.Callback()
def on_migrate_dialog_response(self, _dialog, response):
"""Handle a response to migrating a project."""
Expand All @@ -211,7 +234,7 @@ def on_migrate_dialog_response(self, _dialog, response):
window.inform("Project successfuly migrated!")

# Open the project right away
window.project = selected_project
self._open_project(selected_project)
else:
window.inform("Something went wrong. See logs for details")

Expand Down
14 changes: 11 additions & 3 deletions scriptorium/views/write/navigation.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# SPDX-License-Identifier: GPL-3.0-or-later
from gettext import gettext as _

import logging

from gi.repository import Gio, Graphene, Gtk, Adw
from gi.repository import Gio, Graphene, Gtk, Adw, GLib

from scriptorium.globals import BASE
from scriptorium.models import Chapter, Manuscript, Scene
Expand Down Expand Up @@ -76,6 +78,7 @@ def on_list_item_bind(self, _, list_item):

def connect_to(self, project):
"""Connect the navigation to the project and its contents."""
logger.info(f"Connect navigation to {project}")

# Turn the content into a tree, instance of Chapter may have children
roots = Gio.ListStore.new(Manuscript)
Expand All @@ -102,6 +105,7 @@ def connect_to(self, project):
# append items at the end of the manuscript by default. Users who want
# to position items directly can use the context actions instead
manuscript_id = project.manuscript.identifier
logger.info(f"Connect navigation to {manuscript_id}")
menu = Gio.Menu()
menu.append(
label=_("Add new Scene"),
Expand All @@ -112,7 +116,11 @@ def connect_to(self, project):
detailed_action=f"editor.add_resource(('Chapter', '{manuscript_id}'))"
)
self.add_menu.set_menu_model(menu)
self.add_menu.set_detailed_action_name(
f"editor.add_resource(('Scene', '{manuscript_id}'))"
self.add_menu.connect(
"clicked",
lambda _: self.activate_action(
"editor.add_resource",
GLib.Variant("(ss)", ("Scene", manuscript_id))
)
)

1 change: 1 addition & 0 deletions scriptorium/views/write/page.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class WritePage(Adw.Bin):
def __init__(self):
"""Create an instance of the editor."""
super().__init__()

# By default we have no active scene
self.active_scene = None

Expand Down
2 changes: 1 addition & 1 deletion scriptorium/window.blp
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ template $ScrptWindow: Adw.ApplicationWindow {

content: Adw.ToastOverlay toast_overlay {
child: Adw.NavigationView navigation {
$ScrptLibraryView library_panel {}
};
};

close-request => $on_close_request();
realize => $on_scrptwindow_realize();

ShortcutController {
Shortcut {
Expand Down
Loading