Skip to content
Snippets Groups Projects
Commit eef9b265 authored by Vadim ProductEngine's avatar Vadim ProductEngine
Browse files

STORM-1018 FIXED Improved error messaging for the External Editor feature.

Let the user know what's wrong with external editor.

Added meaningful messages for the following errors:
* Editor not specified.
* Error parsing command line.
* Specified binary not found.
* Editor failed to run.

All the messages are translatable.
parent 5cb2d639
Branches
Tags
No related merge requests found
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "llviewerprecompiledheaders.h" #include "llviewerprecompiledheaders.h"
#include "llexternaleditor.h" #include "llexternaleditor.h"
#include "lltrans.h"
#include "llui.h" #include "llui.h"
// static // static
...@@ -35,13 +36,13 @@ const std::string LLExternalEditor::sFilenameMarker = "%s"; ...@@ -35,13 +36,13 @@ const std::string LLExternalEditor::sFilenameMarker = "%s";
// static // static
const std::string LLExternalEditor::sSetting = "ExternalEditor"; const std::string LLExternalEditor::sSetting = "ExternalEditor";
bool LLExternalEditor::setCommand(const std::string& env_var, const std::string& override) LLExternalEditor::EErrorCode LLExternalEditor::setCommand(const std::string& env_var, const std::string& override)
{ {
std::string cmd = findCommand(env_var, override); std::string cmd = findCommand(env_var, override);
if (cmd.empty()) if (cmd.empty())
{ {
llwarns << "Empty editor command" << llendl; llwarns << "Editor command is empty or not set" << llendl;
return false; return EC_NOT_SPECIFIED;
} }
// Add the filename marker if missing. // Add the filename marker if missing.
...@@ -55,7 +56,7 @@ bool LLExternalEditor::setCommand(const std::string& env_var, const std::string& ...@@ -55,7 +56,7 @@ bool LLExternalEditor::setCommand(const std::string& env_var, const std::string&
if (tokenize(tokens, cmd) < 2) // 2 = bin + at least one arg (%s) if (tokenize(tokens, cmd) < 2) // 2 = bin + at least one arg (%s)
{ {
llwarns << "Error parsing editor command" << llendl; llwarns << "Error parsing editor command" << llendl;
return false; return EC_PARSE_ERROR;
} }
// Check executable for existence. // Check executable for existence.
...@@ -63,7 +64,7 @@ bool LLExternalEditor::setCommand(const std::string& env_var, const std::string& ...@@ -63,7 +64,7 @@ bool LLExternalEditor::setCommand(const std::string& env_var, const std::string&
if (!LLFile::isfile(bin_path)) if (!LLFile::isfile(bin_path))
{ {
llwarns << "Editor binary [" << bin_path << "] not found" << llendl; llwarns << "Editor binary [" << bin_path << "] not found" << llendl;
return false; return EC_BINARY_NOT_FOUND;
} }
// Save command. // Save command.
...@@ -76,16 +77,16 @@ bool LLExternalEditor::setCommand(const std::string& env_var, const std::string& ...@@ -76,16 +77,16 @@ bool LLExternalEditor::setCommand(const std::string& env_var, const std::string&
} }
llinfos << "Setting command [" << bin_path << " " << mArgs << "]" << llendl; llinfos << "Setting command [" << bin_path << " " << mArgs << "]" << llendl;
return true; return EC_SUCCESS;
} }
bool LLExternalEditor::run(const std::string& file_path) LLExternalEditor::EErrorCode LLExternalEditor::run(const std::string& file_path)
{ {
std::string args = mArgs; std::string args = mArgs;
if (mProcess.getExecutable().empty() || args.empty()) if (mProcess.getExecutable().empty() || args.empty())
{ {
llwarns << "Editor command not set" << llendl; llwarns << "Editor command not set" << llendl;
return false; return EC_NOT_SPECIFIED;
} }
// Substitute the filename marker in the command with the actual passed file name. // Substitute the filename marker in the command with the actual passed file name.
...@@ -111,7 +112,22 @@ bool LLExternalEditor::run(const std::string& file_path) ...@@ -111,7 +112,22 @@ bool LLExternalEditor::run(const std::string& file_path)
mProcess.orphan(); mProcess.orphan();
} }
return result == 0; return result == 0 ? EC_SUCCESS : EC_FAILED_TO_RUN;
}
// static
std::string LLExternalEditor::getErrorMessage(EErrorCode code)
{
switch (code)
{
case EC_SUCCESS: return LLTrans::getString("ok");
case EC_NOT_SPECIFIED: return LLTrans::getString("ExternalEditorNotSet");
case EC_PARSE_ERROR: return LLTrans::getString("ExternalEditorCommandParseError");
case EC_BINARY_NOT_FOUND: return LLTrans::getString("ExternalEditorNotFound");
case EC_FAILED_TO_RUN: return LLTrans::getString("ExternalEditorFailedToRun");
}
return LLTrans::getString("Unknown");
} }
// static // static
......
...@@ -42,6 +42,14 @@ class LLExternalEditor ...@@ -42,6 +42,14 @@ class LLExternalEditor
public: public:
typedef enum e_error_code {
EC_SUCCESS, /// No error.
EC_NOT_SPECIFIED, /// Editor path not specified.
EC_PARSE_ERROR, /// Editor command parsing error.
EC_BINARY_NOT_FOUND, /// Could find the editor binary (missing or not quoted).
EC_FAILED_TO_RUN, /// Could not execute the editor binary.
} EErrorCode;
/** /**
* Set editor command. * Set editor command.
* *
...@@ -51,19 +59,25 @@ class LLExternalEditor ...@@ -51,19 +59,25 @@ class LLExternalEditor
* First tries the override, then a predefined setting (sSetting), * First tries the override, then a predefined setting (sSetting),
* then the environment variable. * then the environment variable.
* *
* @return Command if found, empty string otherwise. * @return EC_SUCCESS if command is valid and refers to an existing executable,
* EC_NOT_SPECIFIED or EC_FAILED_TO_RUNan on error.
* *
* @see sSetting * @see sSetting
*/ */
bool setCommand(const std::string& env_var, const std::string& override = LLStringUtil::null); EErrorCode setCommand(const std::string& env_var, const std::string& override = LLStringUtil::null);
/** /**
* Run the editor with the given file. * Run the editor with the given file.
* *
* @param file_path File to edit. * @param file_path File to edit.
* @return true on success, false on error. * @return EC_SUCCESS on success, error code on error.
*/
EErrorCode run(const std::string& file_path);
/**
* Get a meaningful error message for the given status code.
*/ */
bool run(const std::string& file_path); static std::string getErrorMessage(EErrorCode code);
private: private:
......
...@@ -1037,18 +1037,29 @@ void LLFloaterUIPreview::onClickEditFloater() ...@@ -1037,18 +1037,29 @@ void LLFloaterUIPreview::onClickEditFloater()
cmd_override = bin + " " + args; cmd_override = bin + " " + args;
} }
} }
if (!mExternalEditor.setCommand("LL_XUI_EDITOR", cmd_override))
LLExternalEditor::EErrorCode status = mExternalEditor.setCommand("LL_XUI_EDITOR", cmd_override);
if (status != LLExternalEditor::EC_SUCCESS)
{
std::string warning;
if (status == LLExternalEditor::EC_NOT_SPECIFIED) // Use custom message for this error.
{
warning = getString("ExternalEditorNotSet");
}
else
{ {
std::string warning = "Select an editor by setting the environment variable LL_XUI_EDITOR " warning = LLExternalEditor::getErrorMessage(status);
"or the ExternalEditor setting or specifying its path in the \"Editor Path\" field."; }
popupAndPrintWarning(warning); popupAndPrintWarning(warning);
return; return;
} }
// Run the editor. // Run the editor.
if (!mExternalEditor.run(file_path)) if (mExternalEditor.run(file_path) != LLExternalEditor::EC_SUCCESS)
{ {
popupAndPrintWarning("Failed to run editor"); popupAndPrintWarning(LLExternalEditor::getErrorMessage(status));
return; return;
} }
} }
......
...@@ -956,16 +956,31 @@ void LLScriptEdCore::openInExternalEditor() ...@@ -956,16 +956,31 @@ void LLScriptEdCore::openInExternalEditor()
// Open it in external editor. // Open it in external editor.
{ {
LLExternalEditor ed; LLExternalEditor ed;
LLExternalEditor::EErrorCode status;
std::string msg;
if (!ed.setCommand("LL_SCRIPT_EDITOR")) status = ed.setCommand("LL_SCRIPT_EDITOR");
if (status != LLExternalEditor::EC_SUCCESS)
{ {
std::string msg = "Select an editor by setting the environment variable LL_SCRIPT_EDITOR " if (status == LLExternalEditor::EC_NOT_SPECIFIED) // Use custom message for this error.
"or the ExternalEditor setting"; // *TODO: localize {
msg = getString("external_editor_not_set");
}
else
{
msg = LLExternalEditor::getErrorMessage(status);
}
LLNotificationsUtil::add("GenericAlert", LLSD().with("MESSAGE", msg)); LLNotificationsUtil::add("GenericAlert", LLSD().with("MESSAGE", msg));
return; return;
} }
ed.run(filename); status = ed.run(filename);
if (status != LLExternalEditor::EC_SUCCESS)
{
msg = LLExternalEditor::getErrorMessage(status);
LLNotificationsUtil::add("GenericAlert", LLSD().with("MESSAGE", msg));
}
} }
} }
......
...@@ -12,6 +12,10 @@ ...@@ -12,6 +12,10 @@
title="XUI PREVIEW TOOL" title="XUI PREVIEW TOOL"
translate="false" translate="false"
width="750"> width="750">
<string name="ExternalEditorNotSet">
Select an editor by setting the environment variable LL_XUI_EDITOR
or the ExternalEditor setting
or specifying its path in the "Editor Path" field.</string>
<panel <panel
bottom="640" bottom="640"
follows="left|top|right|bottom" follows="left|top|right|bottom"
......
...@@ -28,6 +28,10 @@ ...@@ -28,6 +28,10 @@
name="Title"> name="Title">
Script: [NAME] Script: [NAME]
</panel.string> </panel.string>
<panel.string
name="external_editor_not_set">
Select an editor by setting the environment variable LL_SCRIPT_EDITOR or the ExternalEditor setting.
</panel.string>
<menu_bar <menu_bar
bg_visible="false" bg_visible="false"
follows="left|top" follows="left|top"
......
...@@ -3311,6 +3311,14 @@ Abuse Report</string> ...@@ -3311,6 +3311,14 @@ Abuse Report</string>
<string name="EmptyOutfitText">There are no items in this outfit</string> <string name="EmptyOutfitText">There are no items in this outfit</string>
<!-- External editor status codes -->
<string name="ExternalEditorNotSet">Select an editor using the ExternalEditor setting.</string>
<string name="ExternalEditorNotFound">Cannot find the external editor you specified.
Try enclosing path to the editor with double quotes.
(e.g. "/path to my/editor" "%s")</string>
<string name="ExternalEditorCommandParseError">Error parsing the external editor command.</string>
<string name="ExternalEditorFailedToRun">External editor failed to run.</string>
<!-- Key names begin --> <!-- Key names begin -->
<string name="Esc">Esc</string> <string name="Esc">Esc</string>
<string name="Space">Space</string> <string name="Space">Space</string>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment