From eef9b265b951337d0633d18186dad2b734b30d5a Mon Sep 17 00:00:00 2001
From: Vadim ProductEngine <vsavchuk@productengine.com>
Date: Mon, 7 Mar 2011 19:18:31 +0200
Subject: [PATCH] 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.
---
 indra/newview/llexternaleditor.cpp            | 34 ++++++++++++++-----
 indra/newview/llexternaleditor.h              | 22 +++++++++---
 indra/newview/llfloateruipreview.cpp          | 21 +++++++++---
 indra/newview/llpreviewscript.cpp             | 23 ++++++++++---
 .../default/xui/en/floater_ui_preview.xml     |  4 +++
 .../skins/default/xui/en/panel_script_ed.xml  |  4 +++
 .../newview/skins/default/xui/en/strings.xml  |  8 +++++
 7 files changed, 94 insertions(+), 22 deletions(-)

diff --git a/indra/newview/llexternaleditor.cpp b/indra/newview/llexternaleditor.cpp
index 54968841ab..ed1d7e860a 100644
--- a/indra/newview/llexternaleditor.cpp
+++ b/indra/newview/llexternaleditor.cpp
@@ -27,6 +27,7 @@
 #include "llviewerprecompiledheaders.h"
 #include "llexternaleditor.h"
 
+#include "lltrans.h"
 #include "llui.h"
 
 // static
@@ -35,13 +36,13 @@ const std::string LLExternalEditor::sFilenameMarker = "%s";
 // static
 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);
 	if (cmd.empty())
 	{
-		llwarns << "Empty editor command" << llendl;
-		return false;
+		llwarns << "Editor command is empty or not set" << llendl;
+		return EC_NOT_SPECIFIED;
 	}
 
 	// Add the filename marker if missing.
@@ -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)
 	{
 		llwarns << "Error parsing editor command" << llendl;
-		return false;
+		return EC_PARSE_ERROR;
 	}
 
 	// Check executable for existence.
@@ -63,7 +64,7 @@ bool LLExternalEditor::setCommand(const std::string& env_var, const std::string&
 	if (!LLFile::isfile(bin_path))
 	{
 		llwarns << "Editor binary [" << bin_path << "] not found" << llendl;
-		return false;
+		return EC_BINARY_NOT_FOUND;
 	}
 
 	// Save command.
@@ -76,16 +77,16 @@ bool LLExternalEditor::setCommand(const std::string& env_var, const std::string&
 	}
 	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;
 	if (mProcess.getExecutable().empty() || args.empty())
 	{
 		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.
@@ -111,7 +112,22 @@ bool LLExternalEditor::run(const std::string& file_path)
 		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
diff --git a/indra/newview/llexternaleditor.h b/indra/newview/llexternaleditor.h
index 6ea210d5e2..ef5db56c6e 100644
--- a/indra/newview/llexternaleditor.h
+++ b/indra/newview/llexternaleditor.h
@@ -42,6 +42,14 @@ class LLExternalEditor
 
 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.
 	 *
@@ -51,19 +59,25 @@ public:
 	 * First tries the override, then a predefined setting (sSetting),
 	 * 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
 	 */
-	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.
 	 *
 	 * @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:
 
diff --git a/indra/newview/llfloateruipreview.cpp b/indra/newview/llfloateruipreview.cpp
index 11b3379814..0d8601410a 100644
--- a/indra/newview/llfloateruipreview.cpp
+++ b/indra/newview/llfloateruipreview.cpp
@@ -1037,18 +1037,29 @@ void LLFloaterUIPreview::onClickEditFloater()
 			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 = "Select an editor by setting the environment variable LL_XUI_EDITOR "
-			"or the ExternalEditor setting or specifying its path in the \"Editor Path\" field.";
+		std::string warning;
+
+		if (status == LLExternalEditor::EC_NOT_SPECIFIED) // Use custom message for this error.
+		{
+			warning = getString("ExternalEditorNotSet");
+		}
+		else
+		{
+			warning = LLExternalEditor::getErrorMessage(status);
+		}
+
 		popupAndPrintWarning(warning);
 		return;
 	}
 
 	// 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;
 	}
 }
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index 22ff362b5a..b19bf5d234 100644
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -956,16 +956,31 @@ void LLScriptEdCore::openInExternalEditor()
 	// Open it in external editor.
 	{
 		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 "
-				"or the ExternalEditor setting"; // *TODO: localize
+			if (status == LLExternalEditor::EC_NOT_SPECIFIED) // Use custom message for this error.
+			{
+				msg = getString("external_editor_not_set");
+			}
+			else
+			{
+				msg = LLExternalEditor::getErrorMessage(status);
+			}
+
 			LLNotificationsUtil::add("GenericAlert", LLSD().with("MESSAGE", msg));
 			return;
 		}
 
-		ed.run(filename);
+		status = ed.run(filename);
+		if (status != LLExternalEditor::EC_SUCCESS)
+		{
+			msg = LLExternalEditor::getErrorMessage(status);
+			LLNotificationsUtil::add("GenericAlert", LLSD().with("MESSAGE", msg));
+		}
 	}
 }
 
diff --git a/indra/newview/skins/default/xui/en/floater_ui_preview.xml b/indra/newview/skins/default/xui/en/floater_ui_preview.xml
index 12c4561753..3921cfcd2c 100644
--- a/indra/newview/skins/default/xui/en/floater_ui_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_ui_preview.xml
@@ -12,6 +12,10 @@
  title="XUI PREVIEW TOOL"
  translate="false"
  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
      bottom="640"
      follows="left|top|right|bottom"
diff --git a/indra/newview/skins/default/xui/en/panel_script_ed.xml b/indra/newview/skins/default/xui/en/panel_script_ed.xml
index 627b12cfe1..8d42024386 100644
--- a/indra/newview/skins/default/xui/en/panel_script_ed.xml
+++ b/indra/newview/skins/default/xui/en/panel_script_ed.xml
@@ -28,6 +28,10 @@
      name="Title">
         Script: [NAME]
     </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
      bg_visible="false"
      follows="left|top"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index c0d5f93f83..6a140f4b21 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -3310,6 +3310,14 @@ Abuse Report</string>
   <string name="DeleteItem">Delete selected item?</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 -->
   <string name="Esc">Esc</string>
-- 
GitLab