Merge branch 'master' into develop

This commit is contained in:
Griatch 2018-12-30 11:15:10 +01:00
commit daa9c55653
10 changed files with 488 additions and 356 deletions

View file

@ -105,7 +105,7 @@ def _create_version():
print(err)
try:
version = "%s (rev %s)" % (version, check_output("git rev-parse --short HEAD", shell=True, cwd=root, stderr=STDOUT).strip())
except (IOError, CalledProcessError, WindowsError):
except (IOError, CalledProcessError, OSError):
# ignore if we cannot get to git
pass
return version

View file

@ -3047,7 +3047,7 @@ class CmdSpawn(COMMAND_DEFAULT_CLASS):
caller.msg("|rDeletion cancelled.|n")
return
try:
success = protlib.delete_db_prototype(caller, self.args)
success = protlib.delete_prototype(self.args)
except protlib.PermissionError as err:
caller.msg("|rError deleting:|R {}|n".format(err))
caller.msg("Deletion {}.".format(

View file

@ -1,7 +1,7 @@
# Contrib folder
This folder contains 'contributions': extra snippets of code that are
`evennia/contrib/` contains 'contributions': extra snippets of code that are
potentially very useful for the game coder but which are considered
too game-specific to be a part of the main Evennia game server. These
modules are not used unless you explicitly import them. See each file
@ -17,7 +17,7 @@ things you want from here into your game folder and change them there.
* Barter system (Griatch 2012) - A safe and effective barter-system
for any game. Allows safe trading of any goods (including coin).
* Building menu (vincent-lg 2018) - An @edit command for modifying
* Building menu (vincent-lg 2018) - An `@edit` command for modifying
objects using a generated menu. Customizable for different games.
* CharGen (Griatch 2011) - A simple Character creator for OOC mode.
Meant as a starting point for a more fleshed-out system.
@ -60,9 +60,6 @@ things you want from here into your game folder and change them there.
* Tree Select (FlutterSprite 2017) - A simple system for creating a
branching EvMenu with selection options sourced from a single
multi-line string.
* Turnbattle (Tim Ashley Jenkins 2017) - This is a framework for a turn-based
combat system with different levels of complexity, including versions with
equipment and magic as well as ranged combat.
* Wilderness (titeuf87 2017) - Make infinitely large wilderness areas
with dynamically created locations.
* UnixCommand (Vincent Le Geoff 2017) - Add commands with UNIX-style syntax.
@ -75,7 +72,8 @@ things you want from here into your game folder and change them there.
objects and events using Python from in-game.
* Turnbattle (FlutterSprite 2017) - A turn-based combat engine meant
as a start to build from. Has attack/disengage and turn timeouts,
and includes optional expansions for equipment and combat movement.
and includes optional expansions for equipment and combat movement, magic
and ranged combat.
* Tutorial examples (Griatch 2011, 2015) - A folder of basic
example objects, commands and scripts.
* Tutorial world (Griatch 2011, 2015) - A folder containing the

View file

@ -1,253 +1,346 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-03-02 16:22-0500\n"
"PO-Revision-Date: 2016-03-04 11:51-0500\n"
"Language: fr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
"Last-Translator: \n"
"Language-Team: \n"
"X-Generator: Poedit 1.7.6\n"
#: commands/cmdhandler.py:485
msgid "There were multiple matches."
msgstr "Il y a eu plusieurs correspondances."
#: commands/cmdhandler.py:513
#, python-format
msgid "Command '%s' is not available."
msgstr "Commande '%s' n'est pas disponible."
#: commands/cmdhandler.py:518
#, python-format
msgid " Maybe you meant %s?"
msgstr "Voulez-vous dire %s?"
#: commands/cmdhandler.py:518
msgid "or"
msgstr "ou"
#: commands/cmdhandler.py:520
msgid " Type \"help\" for help."
msgstr "Tapez \"help\" pour de l'aide."
#: commands/cmdparser.py:183
#, python-format
msgid "Could not find '%s'."
msgstr "Peut pas trouver '%s'."
#: commands/cmdsethandler.py:130
#, python-format
msgid ""
"\n"
"(Unsuccessfully tried '%s.' + '%s.%s')."
msgstr ""
"\n"
"(Essayé sans succès '%s.' + '%s.%s')."
#: commands/cmdsethandler.py:151
#, python-brace-format
msgid ""
"\n"
"Error loading cmdset {path}: \"{error}\""
msgstr ""
"\n"
"Erreur de chargement de cmdset {path}: \"{error}\""
#: commands/cmdsethandler.py:155
#, python-brace-format
msgid ""
"\n"
"Error in loading cmdset: No cmdset class '{classname}' in {path}."
msgstr ""
"\n"
"Erreur lors du chargement de cmdset: Pas de classe cmdset '{classname}' in "
"{path}."
#: commands/cmdsethandler.py:159
#, python-brace-format
msgid ""
"\n"
"SyntaxError encountered when loading cmdset '{path}': \"{error}\"."
msgstr ""
"\n"
"Erreur de syntaxe lors du chargement de cmdset '{path}': \"{error}\"."
#: commands/cmdsethandler.py:163
#, python-brace-format
msgid ""
"\n"
"Compile/Run error when loading cmdset '{path}': \"{error}\"."
msgstr ""
"\n"
"Erreur de compilation/exécution lors du chargement de cmdset '{path}': "
"\"{error}\"."
#: commands/cmdsethandler.py:174
msgid ""
"\n"
" (See log for details.)"
msgstr ""
"\n"
"(Voir registre pour plus de détails.)"
#: commands/cmdsethandler.py:247
#, python-brace-format
msgid "custom {mergetype} on cmdset '{cmdset}'"
msgstr "custom {mergetype} sur cmdset '{cmdset}'"
#: commands/cmdsethandler.py:250
#, python-brace-format
msgid " <Merged {mergelist} {mergetype}, prio {prio}>: {current}"
msgstr " <Fusionné {mergelist} {mergetype}, prio {prio}>: {current}"
#: commands/cmdsethandler.py:258
#, python-brace-format
msgid ""
" <{key} ({mergetype}, prio {prio}, {permstring})>:\n"
" {keylist}"
msgstr ""
" <{key} ({mergetype}, prio {prio}, {permstring})>:\n"
" {keylist}"
#: commands/cmdsethandler.py:347
msgid "Only CmdSets can be added to the cmdsethandler!"
msgstr "Seulement CmdSets peuvent être ajoutés au cmdsethandler!"
#: comms/channelhandler.py:94
msgid " (channel)"
msgstr " (channel)"
#: locks/lockhandler.py:230
#, python-format
msgid "Lock: lock-function '%s' is not available."
msgstr "Vérou: lock-function '%s' n'est pas disponible."
#: locks/lockhandler.py:243
#, python-format
msgid "Lock: definition '%s' has syntax errors."
msgstr "Vérou: définition '%s' a des erreurs de syntaxe."
#: locks/lockhandler.py:247
#, python-format
msgid ""
"LockHandler on %(obj)s: access type '%(access_type)s' changed from "
"'%(source)s' to '%(goal)s' "
msgstr ""
"Gestionnaire de vérrou sur %(obj)s: type d'accès '%(access_type)s' a changé "
"de '%(source)s' à '%(goal)s'"
#: locks/lockhandler.py:304
#, python-format
msgid "Lock: '%s' contains no colon (:)."
msgstr "Verrou: '%s' contient pas de deux points (:)."
#: locks/lockhandler.py:308
#, python-format
msgid "Lock: '%s' has no access_type (left-side of colon is empty)."
msgstr ""
"Verrou: '%s' n'a pas de access_type (côté gauche du deux point est vide)."
#: locks/lockhandler.py:311
#, python-format
msgid "Lock: '%s' has mismatched parentheses."
msgstr "Verrou: '%s' a des parenthèses dépareillées."
#: locks/lockhandler.py:314
#, python-format
msgid "Lock: '%s' has no valid lock functions."
msgstr "Verrou: '%s' n'a pas de fonctions verrou valides."
#: objects/objects.py:528
#, python-format
msgid "Couldn't perform move ('%s'). Contact an admin."
msgstr "Ne pouvait effectuer le coup ('%s'). Contactez un administrateur."
#: objects/objects.py:538
msgid "The destination doesn't exist."
msgstr "La destination n'existe pas."
#: objects/objects.py:651
#, python-format
msgid "Could not find default home '(#%d)'."
msgstr "Ne peut trouver la maison '(#%d)' par défaut."
#: objects/objects.py:667
msgid "Something went wrong! You are dumped into nowhere. Contact an admin."
msgstr ""
"Quelque chose a mal tourné! Vous êtes nulle part. Contactez un "
"administrateur."
#: objects/objects.py:747
#, python-format
msgid "Your character %s has been destroyed."
msgstr "Votre personnage %s a été détruit."
#: players/players.py:356
msgid "Player being deleted."
msgstr "Suppression de joueur."
#: scripts/scripthandler.py:50
#, python-format
msgid ""
"\n"
" '%(key)s' (%(next_repeat)s/%(interval)s, %(repeats)s repeats): %(desc)s"
msgstr ""
"\n"
" '%(key)s' (%(next_repeat)s/%(interval)s, %(repeats)s répète): %(desc)s"
#: scripts/scripts.py:202
#, python-format
msgid ""
"Script %(key)s(#%(dbid)s) of type '%(cname)s': at_repeat() error '%(err)s'."
msgstr ""
"Scripte %(key)s(#%(dbid)s) de type '%(cname)s': at_repeat() erreur "
"'%(err)s'."
#: server/initial_setup.py:29
msgid ""
"\n"
"Welcome to your new |wEvennia|n-based game! Visit http://www.evennia.com if "
"you need\n"
"help, want to contribute, report issues or just join the community.\n"
"As Player #1 you can create a demo/tutorial area with |w@batchcommand "
"tutorial_world.build|n.\n"
" "
msgstr ""
"\n"
"Bienvenue dans ton nouveau jeu basé sur |wEvennia|n ! Visitez http://www."
"evennia.com si vous avez besoin\n"
"d'aide, si vous voulez contribuer, rapporter des problèmes ou faire partie "
"de la communauté.\n"
"En tant que Joueur #1 vous pouvez créer une zone de démo/tutoriel avec "
"|w@batchcommand tutorial_world.build|n.\n"
" "
#: server/initial_setup.py:102
msgid "This is User #1."
msgstr "Utilisateur #1."
#: server/initial_setup.py:111
msgid "Limbo"
msgstr "Limbes."
#: server/sessionhandler.py:258
msgid " ... Server restarted."
msgstr " ... Serveur redémarré."
#: server/sessionhandler.py:408
msgid "Logged in from elsewhere. Disconnecting."
msgstr "Connecté d'ailleurs. Déconnexion."
#: server/sessionhandler.py:432
msgid "Idle timeout exceeded, disconnecting."
msgstr "Délai d'inactivité dépassé, déconnexion."
# The French translation for the Evennia server.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the Evennia package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
# Maintained by: vincent-lg <vincent.legoff.srs@gmail.com>, 2018-
#
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-11-22 08:45+0100\n"
"PO-Revision-Date: 2016-03-04 11:51-0500\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: fr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
"X-Generator: Poedit 1.7.6\n"
#: .\accounts\accounts.py:440
#, fuzzy
msgid "Account being deleted."
msgstr "Suppression du compte."
#: .\commands\cmdhandler.py:681
msgid "There were multiple matches."
msgstr "Il y a plusieurs correspondances possibles."
#: .\commands\cmdhandler.py:704
#, python-format
msgid "Command '%s' is not available."
msgstr "La commande '%s' n'est pas disponible."
#: .\commands\cmdhandler.py:709
#, python-format
msgid " Maybe you meant %s?"
msgstr " Vouliez-vous dire %s ?"
#: .\commands\cmdhandler.py:709
msgid "or"
msgstr "ou"
#: .\commands\cmdhandler.py:711
msgid " Type \"help\" for help."
msgstr " Tapez \"help\" pour obtenir de l'aide."
#: .\commands\cmdsethandler.py:89
#, python-brace-format
msgid ""
"{traceback}\n"
"Error loading cmdset '{path}'\n"
"(Traceback was logged {timestamp})"
msgstr ""
"{traceback}\n"
"Une erreur s'est produite lors du chargement du cmdset '{path}'\n"
"(Référence de l'erreur : {timestamp})"
#: .\commands\cmdsethandler.py:94
#, fuzzy, python-brace-format
msgid ""
"Error loading cmdset: No cmdset class '{classname}' in '{path}'.\n"
"(Traceback was logged {timestamp})"
msgstr ""
"\n"
"Une erreur s'est produite lors du chargement de cmdset : la classe cmdset '{classname}' est introuvable dans "
"{path}.\n"
"(Référence de l'erreur : {timestamp})"
#: .\commands\cmdsethandler.py:98
#, fuzzy, python-brace-format
msgid ""
"{traceback}\n"
"SyntaxError encountered when loading cmdset '{path}'.\n"
"(Traceback was logged {timestamp})"
msgstr ""
"\n"
"Erreur de syntaxe lors du chargement de cmdset '{path}' : \"{error}\".\n"
"(Référence de l'erreur : {timestamp})"
#: .\commands\cmdsethandler.py:103
#, fuzzy, python-brace-format
msgid ""
"{traceback}\n"
"Compile/Run error when loading cmdset '{path}'.\",\n"
"(Traceback was logged {timestamp})"
msgstr ""
"\n"
"Erreur de compilation/exécution lors du chargement de cmdset '{path}' : "
"\"{error}\".\n"
"(Référence de l'erreur : {timestamp})"
#: .\commands\cmdsethandler.py:108
#, python-brace-format
msgid ""
"\n"
"Error encountered for cmdset at path '{path}'.\n"
"Replacing with fallback '{fallback_path}'.\n"
msgstr ""
"\n"
"Une erreur a été rencontrée lors du chargement du cmdset '{path}'.\n"
"Le cmdset '{fallback_path}' est utilisé en remplacement.\n"
#: .\commands\cmdsethandler.py:114
#, python-brace-format
msgid "Fallback path '{fallback_path}' failed to generate a cmdset."
msgstr "Impossible de générer le cmdset de remplacement : '{fallback_path}'."
#: .\commands\cmdsethandler.py:182 .\commands\cmdsethandler.py:192
#, fuzzy, python-format
msgid ""
"\n"
"(Unsuccessfully tried '%s')."
msgstr ""
"\n"
"(Essayé sans succès '%s.' + '%s.%s')."
#: .\commands\cmdsethandler.py:311
#, python-brace-format
msgid "custom {mergetype} on cmdset '{cmdset}'"
msgstr "custom {mergetype} sur cmdset '{cmdset}'"
#: .\commands\cmdsethandler.py:314
#, python-brace-format
msgid " <Merged {mergelist} {mergetype}, prio {prio}>: {current}"
msgstr " <Fusionné {mergelist} {mergetype}, prio {prio}>: {current}"
#: .\commands\cmdsethandler.py:322
#, python-brace-format
msgid ""
" <{key} ({mergetype}, prio {prio}, {permstring})>:\n"
" {keylist}"
msgstr ""
" <{key} ({mergetype}, prio {prio}, {permstring})>:\n"
" {keylist}"
#: .\commands\cmdsethandler.py:426
msgid "Only CmdSets can be added to the cmdsethandler!"
msgstr "Seuls des CmdSets peuvent être ajoutés au cmdsethandler !"
#: .\comms\channelhandler.py:100
msgid "Say what?"
msgstr "Que voulez-vous dire ?"
#: .\comms\channelhandler.py:105
#, python-format
msgid "Channel '%s' not found."
msgstr "Le canal '%s' ne semble pas exister."
#: .\comms\channelhandler.py:108
#, python-format
msgid "You are not connected to channel '%s'."
msgstr "Vous n'êtes pas connecté au canal '%s'."
#: .\comms\channelhandler.py:112
#, python-format
msgid "You are not permitted to send to channel '%s'."
msgstr "Vous n'avez pas le droit de parler sur le canal '%s'."
#: .\comms\channelhandler.py:155
msgid " (channel)"
msgstr " (canal)"
#: .\locks\lockhandler.py:236
#, python-format
msgid "Lock: lock-function '%s' is not available."
msgstr "Verrou : lock-function '%s' n'est pas disponible."
#: .\locks\lockhandler.py:249
#, python-format
msgid "Lock: definition '%s' has syntax errors."
msgstr "Verrou : la définition '%s' a des erreurs de syntaxe."
#: .\locks\lockhandler.py:253
#, python-format
msgid ""
"LockHandler on %(obj)s: access type '%(access_type)s' changed from "
"'%(source)s' to '%(goal)s' "
msgstr ""
"Gestionnaire de verrous sur %(obj)s: type d'accès '%(access_type)s' a changé "
"de '%(source)s' à '%(goal)s'"
#: .\locks\lockhandler.py:320
#, fuzzy, python-brace-format
msgid "Lock: '{lockdef}' contains no colon (:)."
msgstr "Verrou : '%s' ne contient pas de deux points (:)."
#: .\locks\lockhandler.py:328
#, fuzzy, python-brace-format
msgid "Lock: '{lockdef}' has no access_type (left-side of colon is empty)."
msgstr ""
"Verrou : '%s' n'a pas de 'access_type' (il n'y a rien avant les deux points)."
#: .\locks\lockhandler.py:336
#, fuzzy, python-brace-format
msgid "Lock: '{lockdef}' has mismatched parentheses."
msgstr "Verrou : '%s' a des parenthèses déséquilibrées."
#: .\locks\lockhandler.py:343
#, fuzzy, python-brace-format
msgid "Lock: '{lockdef}' has no valid lock functions."
msgstr "Verrou : '%s' n'a pas de lock-function valide."
#: .\objects\objects.py:729
#, python-format
msgid "Couldn't perform move ('%s'). Contact an admin."
msgstr "Impossible de se déplacer vers ('%s'). Veuillez contacter un administrateur."
#: .\objects\objects.py:739
msgid "The destination doesn't exist."
msgstr "La destination est inconnue."
#: .\objects\objects.py:830
#, python-format
msgid "Could not find default home '(#%d)'."
msgstr "Impossible de trouver la salle de départ (default home) par défaut : '#%d'."
#: .\objects\objects.py:846
msgid "Something went wrong! You are dumped into nowhere. Contact an admin."
msgstr ""
"Quelque chose a mal tourné ! Vous vous trouvez au milieu de nulle part. "
"Veuillez contacter un administrateur."
#: .\objects\objects.py:912
#, python-format
msgid "Your character %s has been destroyed."
msgstr "Votre personnage %s a été détruit."
#: .\scripts\scripthandler.py:53
#, python-format
msgid ""
"\n"
" '%(key)s' (%(next_repeat)s/%(interval)s, %(repeats)s repeats): %(desc)s"
msgstr ""
"\n"
" '%(key)s' (%(next_repeat)s/%(interval)s, %(repeats)s répète) : %(desc)s"
#: .\scripts\scripts.py:205
#, python-format
msgid ""
"Script %(key)s(#%(dbid)s) of type '%(cname)s': at_repeat() error '%(err)s'."
msgstr ""
"Le script %(key)s(#%(dbid)s) de type '%(cname)s' a rencontré une erreur "
"durant at_repeat() : '%(err)s'."
#: .\server\initial_setup.py:28
#, fuzzy
msgid ""
"\n"
"Welcome to your new |wEvennia|n-based game! Visit http://www.evennia.com if "
"you need\n"
"help, want to contribute, report issues or just join the community.\n"
"As Account #1 you can create a demo/tutorial area with |w@batchcommand "
"tutorial_world.build|n.\n"
" "
msgstr ""
"\n"
"Bienvenue dans votre nouveau jeu basé sur |wEvennia|n ! Visitez le site Web\n"
"http://www.evennia.com si vous avez besoin d'aide, pour contribuer au projet,\n"
"afin de rapporter des bugs ou faire partie de la communauté.\n"
"En tant que premier personnage (#1), vous pouvez créer une zone de\n"
"démo/tutoriel en entrant la commande |w@batchcommand tutorial_world.build|n.\n"
" "
#: .\server\initial_setup.py:92
msgid "This is User #1."
msgstr "C'est l'utilisateur #1."
#: .\server\initial_setup.py:105
msgid "Limbo"
msgstr "Limbes"
#: .\server\server.py:139
#, fuzzy
msgid "idle timeout exceeded"
msgstr "Délai d'inactivité dépassé, déconnexion."
#: .\server\sessionhandler.py:386
msgid " ... Server restarted."
msgstr " ... Serveur redémarré."
#: .\server\sessionhandler.py:606
msgid "Logged in from elsewhere. Disconnecting."
msgstr "Connexion d'une autre session. Déconnexion de celle-ci."
#: .\server\sessionhandler.py:634
msgid "Idle timeout exceeded, disconnecting."
msgstr "Délai d'inactivité dépassé, déconnexion."
#: .\server\validators.py:50
#, python-format
msgid ""
"%s From a terminal client, you can also use a phrase of multiple words if "
"you enclose the password in double quotes."
msgstr ""
"%s Depuis votre client, vous pouvez également préciser une phrase contenant "
"plusieurs mots séparés par un espace, dès lors que cette phrase est entourée de guillemets."
#: .\utils\evmenu.py:192
#, python-brace-format
msgid ""
"Menu node '{nodename}' is either not implemented or caused an error. Make "
"another choice."
msgstr ""
"Ce choix '{nodename}' n'est pas implémenté, ou bien a créé une erreur. "
"Faies un autre choix."
#: .\utils\evmenu.py:194
#, python-brace-format
msgid "Error in menu node '{nodename}'."
msgstr "Une erreur s'est produite dans le choix '{nodename}'."
#: .\utils\evmenu.py:195
msgid "No description."
msgstr "Description non renseignée."
#: .\utils\evmenu.py:196
msgid "Commands: <menu option>, help, quit"
msgstr "Utilisez une des commandes : <menu option>, help, quit"
#: .\utils\evmenu.py:197
msgid "Commands: <menu option>, help"
msgstr "Utilisez une des commandes : <menu option>, help"
#: .\utils\evmenu.py:198
msgid "Commands: help, quit"
msgstr "Utilisez une des commandes : help, quit"
#: .\utils\evmenu.py:199
msgid "Commands: help"
msgstr "Utilisez la commande : help"
#: .\utils\evmenu.py:200
msgid "Choose an option or try 'help'."
msgstr "Choisissez une option ou entrez la commande 'help'."
#: .\utils\utils.py:1866
#, python-format
msgid "Could not find '%s'."
msgstr "Impossible de trouver '%s'."
#: .\utils\utils.py:1873
#, python-format
msgid "More than one match for '%s' (please narrow target):\n"
msgstr "Plus d'une possibilité pour '%s' (veuillez préciser) :\n"

View file

@ -1217,7 +1217,7 @@ def evennia_version():
"git rev-parse --short HEAD",
shell=True, cwd=EVENNIA_ROOT, stderr=STDOUT).strip()
version = "%s (rev %s)" % (version, rev)
except (IOError, CalledProcessError, WindowsError):
except (IOError, CalledProcessError, OSError):
# move on if git is not answering
pass
return version

View file

@ -30,32 +30,31 @@ plugin_handler.add('hotbuttons', (function () {
// Add Buttons
var addButtonsUI = function () {
var buttons = $( [
'<div id="buttons" class="split split-vertical">',
' <div id="buttonsform" class="wrapper">',
' <div id="buttonscontrol" class="input-group">',
' <button class="btn" id="assign_button0" type="button" value="button0">unassigned</button>',
' <button class="btn" id="assign_button1" type="button" value="button1">unassigned</button>',
' <button class="btn" id="assign_button2" type="button" value="button2">unassigned</button>',
' <button class="btn" id="assign_button3" type="button" value="button3">unassigned</button>',
' <button class="btn" id="assign_button4" type="button" value="button4">unassigned</button>',
' <button class="btn" id="assign_button5" type="button" value="button5">unassigned</button>',
' <button class="btn" id="assign_button6" type="button" value="button6">unassigned</button>',
' <button class="btn" id="assign_button7" type="button" value="button7">unassigned</button>',
' <button class="btn" id="assign_button8" type="button" value="button8">unassigned</button>',
' </div>',
' </div>',
'</div>',
].join("\n") );
'<div id="buttons" class="split split-vertical">',
' <div id="buttonsform">',
' <div id="buttonscontrol" class="input-group">',
' <button class="btn" id="assign_button0" type="button" value="button0">unassigned</button>',
' <button class="btn" id="assign_button1" type="button" value="button1">unassigned</button>',
' <button class="btn" id="assign_button2" type="button" value="button2">unassigned</button>',
' <button class="btn" id="assign_button3" type="button" value="button3">unassigned</button>',
' <button class="btn" id="assign_button4" type="button" value="button4">unassigned</button>',
' <button class="btn" id="assign_button5" type="button" value="button5">unassigned</button>',
' <button class="btn" id="assign_button6" type="button" value="button6">unassigned</button>',
' <button class="btn" id="assign_button7" type="button" value="button7">unassigned</button>',
' <button class="btn" id="assign_button8" type="button" value="button8">unassigned</button>',
' </div>',
' </div>',
'</div>',
].join("\n") );
// Add buttons in front of the existing #inputform
buttons.insertBefore('#inputform');
$('#inputform').addClass('split split-vertical');
$('#input').prev().replaceWith(buttons);
Split(['#buttons','#inputform'], {
Split(['#main','#buttons','#input'], {
sizes: [85,5,10],
direction: 'vertical',
sizes: [50,50],
gutterSize: 4,
minSize: 150,
minSize: [150,20,50],
});
}

View file

@ -77,10 +77,12 @@ let options_plugin = (function () {
if (code === 27) { // Escape key
if ($('#helpdialog').is(':visible')) {
plugins['popups'].closePopup("#helpdialog");
} else {
plugins['popups'].closePopup("#optionsdialog");
return true;
}
if ($('#optionsdialog').is(':visible')) {
plugins['popups'].closePopup("#optionsdialog");
return true;
}
return true;
}
return false;
}
@ -129,6 +131,21 @@ let options_plugin = (function () {
plugins['popups'].closePopup("#helpdialog");
}
//
// Make sure to close any dialogs on connection lost
var onText = function (args, kwargs) {
// is helppopup set? and if so, does this Text have type 'help'?
if ('helppopup' in options && options['helppopup'] ) {
if (kwargs && ('type' in kwargs) && (kwargs['type'] == 'help') ) {
$('#helpdialogcontent').append('<div>'+ args + '</div>');
plugins['popups'].togglePopup("#helpdialog");
return true;
}
}
return false;
}
//
// Register and init plugin
var init = function () {
@ -155,6 +172,7 @@ let options_plugin = (function () {
onGotOptions: onGotOptions,
onPrompt: onPrompt,
onConnectionClose: onConnectionClose,
onText: onText,
}
})()
plugin_handler.add('options', options_plugin);

View file

@ -183,12 +183,12 @@ let splithandler_plugin = (function () {
var dialog = $("#splitdialogcontent");
dialog.empty();
var selection = '<select name="pane">';
var selection = '<select name="pane">';
for ( var pane in split_panes ) {
selection = selection + '<option value="' + pane + '">' + pane + '</option>';
selection = selection + '<option value="' + pane + '">' + pane + '</option>';
}
selection = "Pane to split: " + selection + "</select> ";
dialog.append(selection);
selection = "Pane to split: " + selection + "</select> ";
dialog.append(selection);
dialog.append('<input type="radio" name="direction" value="vertical" checked>top/bottom </>');
dialog.append('<input type="radio" name="direction" value="horizontal">side-by-side <hr />');
@ -203,7 +203,7 @@ let splithandler_plugin = (function () {
dialog.append('<input type="radio" name="flow2" value="replace">replace </>');
dialog.append('<input type="radio" name="flow2" value="append">append <hr />');
dialog.append('<div id="splitclose" class="btn btn-large btn-outline-primary float-right">Split</div>');
dialog.append('<div id="splitclose" class="btn btn-large btn-outline-primary float-right">Split</div>');
$("#splitclose").bind("click", onSplitDialogClose);
@ -251,21 +251,21 @@ let splithandler_plugin = (function () {
var dialog = $("#panedialogcontent");
dialog.empty();
var selection = '<select name="assign-pane">';
var selection = '<select name="assign-pane">';
for ( var pane in split_panes ) {
selection = selection + '<option value="' + pane + '">' + pane + '</option>';
selection = selection + '<option value="' + pane + '">' + pane + '</option>';
}
selection = "Assign to pane: " + selection + "</select> <hr />";
dialog.append(selection);
selection = "Assign to pane: " + selection + "</select> <hr />";
dialog.append(selection);
var multiple = '<select multiple name="assign-type">';
var multiple = '<select multiple name="assign-type">';
for ( var type in known_types ) {
multiple = multiple + '<option value="' + known_types[type] + '">' + known_types[type] + '</option>';
multiple = multiple + '<option value="' + known_types[type] + '">' + known_types[type] + '</option>';
}
multiple = "Content types: " + multiple + "</select> <hr />";
dialog.append(multiple);
multiple = "Content types: " + multiple + "</select> <hr />";
dialog.append(multiple);
dialog.append('<div id="paneclose" class="btn btn-large btn-outline-primary float-right">Assign</div>');
dialog.append('<div id="paneclose" class="btn btn-large btn-outline-primary float-right">Assign</div>');
$("#paneclose").bind("click", onPaneControlDialogClose);
@ -276,9 +276,9 @@ let splithandler_plugin = (function () {
// Close "Pane Controls" dialog
var onPaneControlDialogClose = function () {
var pane = $("select[name=assign-pane]").val();
var types = $("select[name=assign-type]").val();
var types = $("select[name=assign-type]").val();
// var types = new Array;
// var types = new Array;
// $('#splitdialogcontent input[type=checkbox]:checked').each(function() {
// types.push( $(this).attr('value') );
// });
@ -287,24 +287,24 @@ let splithandler_plugin = (function () {
plugins['popups'].closePopup("#panedialog");
}
//
// helper function sending text to a pane
var txtToPane = function (panekey, txt) {
var pane = split_panes[panekey];
var text_div = $('#' + panekey + '-sub');
var pane = split_panes[panekey];
var text_div = $('#' + panekey + '-sub');
if ( pane['update_method'] == 'replace' ) {
text_div.html(txt)
} else if ( pane['update_method'] == 'append' ) {
text_div.append(txt);
var scrollHeight = text_div.parent().prop("scrollHeight");
text_div.parent().animate({ scrollTop: scrollHeight }, 0);
} else { // line feed
text_div.append("<div class='out'>" + txt + "</div>");
var scrollHeight = text_div.parent().prop("scrollHeight");
text_div.parent().animate({ scrollTop: scrollHeight }, 0);
}
if ( pane['update_method'] == 'replace' ) {
text_div.html(txt)
} else if ( pane['update_method'] == 'append' ) {
text_div.append(txt);
var scrollHeight = text_div.parent().prop("scrollHeight");
text_div.parent().animate({ scrollTop: scrollHeight }, 0);
} else { // line feed
text_div.append("<div class='out'>" + txt + "</div>");
var scrollHeight = text_div.parent().prop("scrollHeight");
text_div.parent().animate({ scrollTop: scrollHeight }, 0);
}
}
@ -316,53 +316,76 @@ let splithandler_plugin = (function () {
//
// Accept plugin onText events
var onText = function (args, kwargs) {
// If the message is not itself tagged, we'll assume it
// should go into any panes with 'all' or 'rest' set
// If the message is not itself tagged, we'll assume it
// should go into any panes with 'all' or 'rest' set
var msgtype = "rest";
if ( kwargs && 'type' in kwargs ) {
msgtype = kwargs['type'];
msgtype = kwargs['type'];
if ( ! known_types.includes(msgtype) ) {
// this is a new output type that can be mapped to panes
console.log('detected new output type: ' + msgtype)
known_types.push(msgtype);
}
}
var target_panes = [];
var rest_panes = [];
for (var key in split_panes) {
var pane = split_panes[key];
// is this message type mapped to this pane (or does the pane has an 'all' type)?
if (pane['types'].length > 0) {
if (pane['types'].includes(msgtype) || pane['types'].includes('all')) {
target_panes.push(key);
} else if (pane['types'].includes('rest')) {
// store rest-panes in case we have no explicit to send to
rest_panes.push(key);
}
} else {
// unassigned panes are assumed to be rest-panes too
rest_panes.push(key);
}
}
var ntargets = target_panes.length;
var nrests = rest_panes.length;
if (ntargets > 0) {
// we have explicit target panes to send to
for (var i=0; i<ntargets; i++) {
txtToPane(target_panes[i], args[0]);
}
return true;
} else if (nrests > 0) {
// no targets, send remainder to rest-panes/unassigned
for (var i=0; i<nrests; i++) {
txtToPane(rest_panes[i], args[0]);
}
return true;
}
// unhandled message
}
var target_panes = [];
var rest_panes = [];
for (var key in split_panes) {
var pane = split_panes[key];
// is this message type mapped to this pane (or does the pane has an 'all' type)?
if (pane['types'].length > 0) {
if (pane['types'].includes(msgtype) || pane['types'].includes('all')) {
target_panes.push(key);
} else if (pane['types'].includes('rest')) {
// store rest-panes in case we have no explicit to send to
rest_panes.push(key);
}
} else {
// unassigned panes are assumed to be rest-panes too
rest_panes.push(key);
}
}
var ntargets = target_panes.length;
var nrests = rest_panes.length;
if (ntargets > 0) {
// we have explicit target panes to send to
for (var i=0; i<ntargets; i++) {
txtToPane(target_panes[i], args[0]);
}
return true;
} else if (nrests > 0) {
// no targets, send remainder to rest-panes/unassigned
for (var i=0; i<nrests; i++) {
txtToPane(rest_panes[i], args[0]);
}
return true;
}
// unhandled message
return false;
}
//
// onKeydown check for 'ESC' key.
var onKeydown = function (event) {
var code = event.which;
if (code === 27) { // Escape key
if ($('#splitdialog').is(':visible')) {
plugins['popups'].closePopup("#splitdialog");
return true;
}
if ($('#panedialog').is(':visible')) {
plugins['popups'].closePopup("#panedialog");
return true;
}
}
// capture all keys while one of our "modal" dialogs is open
if ($('#splitdialogcontent').is(':visible') || $('#panedialogcontent').is(':visible')) {
return true;
}
return false;
}
@ -409,6 +432,7 @@ let splithandler_plugin = (function () {
dynamic_split: dynamic_split,
undo_split: undo_split,
set_pane_types: set_pane_types,
onKeydown: onKeydown,
}
})()
plugin_handler.add('splithandler', splithandler_plugin);

View file

@ -73,10 +73,10 @@ JQuery available.
<script src={% static "webclient/js/plugins/popups.js" %} language="javascript" type="text/javascript"></script>
<script src={% static "webclient/js/plugins/options.js" %} language="javascript" type="text/javascript"></script>
<script src={% static "webclient/js/plugins/history.js" %} language="javascript" type="text/javascript"></script>
<script src={% static "webclient/js/plugins/splithandler.js" %} language="javascript" type="text/javascript"></script>
<script src={% static "webclient/js/plugins/default_in.js" %} language="javascript" type="text/javascript"></script>
<script src={% static "webclient/js/plugins/oob.js" %} language="javascript" type="text/javascript"></script>
<script src={% static "webclient/js/plugins/notifications.js" %} language="javascript" type="text/javascript"></script>
<script src={% static "webclient/js/plugins/splithandler.js" %} language="javascript" type="text/javascript"></script>
<script src={% static "webclient/js/plugins/default_out.js" %} language="javascript" type="text/javascript"></script>
{% endblock %}