DLC-based editor install.

When the user goes to edit something and no editor has been selected,
the launcher will prompt the creator to select an editor. If the editor
selected is not installed, it will be downloaded and installed.
This commit is contained in:
Tom Rothamel
2012-07-05 00:30:11 -04:00
parent 0be10220b3
commit 76ba294af3
7 changed files with 294 additions and 88 deletions
+19 -2
View File
@@ -896,7 +896,13 @@ init -1000 python in updater:
def get_installed_packages(base=None):
"""
:doc: updater
Returns a list of installed DLC package names.
`base`
The base directory to update. Defaults to the current project's
base directory.
"""
global installed_packages_cache
@@ -910,8 +916,8 @@ init -1000 python in updater:
fn = os.path.join(base, "update", "current.json")
if not os.path.exists(fn):
raise UpdateError("Either this project does not support updating, or the update status file was deleted.")
return [ ]
with open(fn, "r") as f:
state = json.load(f)
@@ -919,6 +925,17 @@ init -1000 python in updater:
installed_packages_cache = rv
return rv
def can_update(base=None):
"""
:doc: updater
Returns true if it's possible that an update can succeed. Returns false
if updating is totally impossible. (For example, if the update directory
was deleted.)
"""
return not not get_installed_packages(base)
def update(url, base=None, force=False, public_key=None, simulate=None, add=[], restart=True):
"""
:doc: updater
+238 -43
View File
@@ -7,7 +7,8 @@ init python in editor:
from store import Action, renpy, config, persistent
import store.project as project
import store.updater as updater
import glob
import re
import traceback
@@ -62,30 +63,192 @@ init python in editor:
for filename in glob.glob(d + "/*/*.edit.py"):
scan_editor(filename)
def setup():
"""
Sets up the editor contained in system.editor.
"""
########################################################################
# A list of fancy_editor_info objects.
fancy_editors = [ ]
class FancyEditorInfo(object):
"""
Represents an editor in the selection screen. A FEI knows if the
editor is installed or not.
"""
def __init__(self, priority, name, description=None, dlc=None, dldescription=None):
# The priority of the editor. Lower priorities will come later
# in the list.
self.priority = priority
# The name of the editor.
self.name = name
# Is the editor installed?
self.installed = name in editors
# The dlc needed to install the editor.
self.dlc = dlc
# A description of the editor.
self.description = description
# A description of the download.
self.dldescription = dldescription
def fancy_scan_editors():
"""
Creates the list of FancyEditorInfo objects.
"""
global fancy_editors
scan_all()
fei = fancy_editors = [ ]
# Editra.
ED = _("{b}Recommended.{/b} A beta editor with an easy to use interface and features that aid in development, such as spell-checking.")
EDL = _("{b}Recommended.{/b} A beta editor with an easy to use interface and features that aid in development, such as spell-checking. On Linux, Editra requires wxPython.")
if renpy.windows:
dlc = "editra-windows"
installed = os.path.exists(os.path.join(config.basedir, "editra/Editra-win32"))
description = ED
elif renpy.macintosh:
dlc = "editra-mac"
installed = os.path.exists(os.path.join(config.basedir, "editra/Editra-mac.app"))
description = ED
else:
dlc = "editra-linux"
installed = os.path.exists(os.path.join(config.basedir, "editra/Editra"))
description = EDL
e = FancyEditorInfo(
1,
"Editra",
description,
dlc,
_("Up to 22 MB download required."))
e.installed = e.installed or installed
fei.append(e)
# jEdit
fei.append(FancyEditorInfo(
2,
"jEdit",
"A mature editor that requires Java to be installed.",
"jedit",
_("1.8 MB download required.")))
fei.append(FancyEditorInfo(
3,
"System Editor",
"Invokes the editor your operating system has associated with .rpy files.",
None))
for k in editors:
if k in [ "Editra", "jEdit", "System Editor", "None" ]:
continue
fei.append(FancyEditorInfo(
4,
k,
None,
None))
fei.append(FancyEditorInfo(
5,
"None",
"Prevents Ren'Py from opening a text editor.",
None))
fei.sort(key=lambda e : (e.priority, e.name.lower()))
# If we're in a linux distro or something, assume all editors work.
if not updater.can_update():
for i in fei:
i.installed = True
def fancy_activate_editor():
"""
Activates the editor in persistent.editor, if it's installed.
"""
if not set_editor:
return
for i in [ persistent.editor, "Editra", "None" ]:
if i in editors:
persistent.editor = i
ei = editors[i]
os.environ["RENPY_EDIT_PY"] = renpy.fsencode(os.path.abspath(ei.filename))
renpy.editor.init()
return
os.environ.discard("RENPY_EDIT_PY")
fancy_scan_editors()
for i in fancy_editors:
if i.name == persistent.editor:
if i.installed:
ei = editors[i.name]
os.environ["RENPY_EDIT_PY"] = renpy.fsencode(os.path.abspath(ei.filename))
break
else:
persistent.editor = None
os.environ.pop("RENPY_EDIT_PY", None)
renpy.editor.init()
scan_all()
setup()
def fancy_select_editor(name):
"""
Selects the editor with the given name, installing it if it
doesn't already exist.
"""
for fe in fancy_editors:
if fe.name == name:
break
else:
return
if not fe.installed:
updater.add_dlc(fe.dlc)
persistent.editor = fe.name
fancy_activate_editor()
# Call fancy_activate_editor on startup.
fancy_activate_editor()
class SelectEditor(Action):
def __init__(self, name):
self.name = name
def get_selected(self):
return persistent.editor == self.name
def __call__(self):
fancy_select_editor(self.name)
return True
def check_editor():
"""
Checks to see if an editor is set. If one isn't asks the user to
select one.
Returns True if the editor is set and editing can proceed, and
False otherwise.
"""
if not set_editor:
return True
if persistent.editor:
return True
return renpy.invoke_in_new_context(renpy.call_screen, "editor")
##########################################################################
# Editing actions.
class Edit(Action):
def __init__(self, filename, line=None, check=False):
"""
@@ -119,6 +282,9 @@ init python in editor:
if not self.get_sensitive():
return
if not check_editor():
return
fn = project.current.unelide_filename(self.filename)
e = renpy.editor.editor
@@ -135,6 +301,10 @@ init python in editor:
return
def __call__(self):
if not check_editor():
return
scripts = project.current.script_files()
scripts.sort(key=lambda fn : fn.lower())
@@ -151,33 +321,58 @@ init python in editor:
e.open(fn)
e.end()
class Select(Action):
"""
Selects the text editor to use.
"""
screen editor:
frame:
style_group "l"
style "l_root"
def __init__(self, name):
self.name = name
window:
has vbox
label _("Select Editor")
def __call__(self):
persistent.editor = self.name
setup()
renpy.restart_interaction()
add HALF_SPACER
def get_selected(self):
return persistent.editor == self.name
def editor_action_list():
"""
Gets a list of (editor name, select action) tuples, one for each
editor we know of.
"""
rv = [ ]
for i in sorted(editors, key=lambda a : a.lower()):
rv.append((i, Select(i)))
hbox:
frame:
style "l_indent"
xfill True
viewport:
scrollbars "vertical"
mousewheel True
has vbox
text _("A text editor is the program you'll use to edit Ren'Py script files. Here, you can select the editor Ren'Py will be used. If not already present, the editor will be automatically downloaded and installed.") style "l_small_text"
for fe in editor.fancy_editors:
add SPACER
textbutton fe.name action editor.SelectEditor(fe.name)
add HALF_SPACER
frame:
style "l_indent"
has vbox
if fe.description:
text fe.description style "l_small_text"
if not fe.installed:
add HALF_SPACER
text fe.dldescription style "l_small_text"
return rv
textbutton _("Cancel") action Return(False) style "l_left_button"
label editor_preference:
call screen editor
jump preferences
-6
View File
@@ -169,12 +169,6 @@ label main_menu:
return
label start:
menu:
"TEST DLC":
$ add_dlc("editra-linux")
"CANCEL":
pass
show screen bottom_info
label front_page:
+36 -32
View File
@@ -1,5 +1,3 @@
define foo = 1
screen preferences:
frame:
@@ -16,13 +14,14 @@ screen preferences:
hbox:
frame:
style "l_indent"
xmaximum TWOTHIRDS
xmaximum ONEHALF
xfill True
has vbox
# Projects directory selection.
add SEPARATOR2
@@ -44,8 +43,26 @@ screen preferences:
add SPACER
# Update URL selection.
# Text editor selection.
add SEPARATOR2
frame:
style "l_indent"
has vbox
text _("Text Editor:")
add HALF_SPACER
frame style "l_indent":
if persistent.editor:
textbutton persistent.editor action Jump("editor_preference")
else:
textbutton _("Not Set") action Jump("editor_preference")
add SPACER
# Update URL selection.
add SEPARATOR2
frame:
@@ -61,8 +78,13 @@ screen preferences:
add SPACER
# Navigation Options.
frame:
style "l_indent"
xmaximum ONEHALF
xfill True
has vbox
add SEPARATOR2
frame:
@@ -75,39 +97,21 @@ screen preferences:
textbutton "Include private names" style "l_checkbox" action ToggleField(persistent, "navigate_private")
textbutton "Include library names" style "l_checkbox" action ToggleField(persistent, "navigate_library")
add HALF_SPACER
textbutton "Open launcher project" style "l_nonbox" action [ project.Select("launcher"), Jump("front_page") ]
frame:
style "l_indent"
xmaximum ONETHIRD
xfill True
has vbox
add SPACER
add SEPARATOR2
frame:
style "l_indent"
style "l_indent"
has vbox
text _("Text Editor:")
text _("Actions:")
add HALF_SPACER
viewport:
scrollbars "vertical"
mousewheel True
has vbox
for name, action in editor.editor_action_list():
textbutton "[name!q]":
action action
style "l_list"
textbutton _("Open launcher as project") style "l_nonbox" action [ project.Select("launcher"), Jump("front_page") ]
textbutton _("Back") action Jump("front_page") style "l_left_button"
label projects_directory_preference:
+1 -1
View File
@@ -1 +1 @@
{"build_update": true, "packages": ["all", "linux", "mac", "win", "editra-linux", "sdk"], "type": "hidden"}
{"build_update": true, "packages": ["all", "linux", "mac", "win", "sdk", "source", "jedit", "editra-mac", "editra-linux", "editra-windows"], "type": "hidden"}
-4
View File
@@ -1,4 +0,0 @@
import renpy
# Pass the file off to the system editor (as determined by file associations).
Editor = renpy.editor.SystemEditor