summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/newview/llfloatertranslationsettings.cpp214
-rw-r--r--indra/newview/llfloatertranslationsettings.h22
-rw-r--r--indra/newview/lltranslate.cpp107
-rw-r--r--indra/newview/lltranslate.h37
-rw-r--r--indra/newview/skins/default/xui/en/floater_translation_settings.xml52
5 files changed, 363 insertions, 69 deletions
diff --git a/indra/newview/llfloatertranslationsettings.cpp b/indra/newview/llfloatertranslationsettings.cpp
index 4079fdf482..ac3e7ac8fa 100644
--- a/indra/newview/llfloatertranslationsettings.cpp
+++ b/indra/newview/llfloatertranslationsettings.cpp
@@ -29,6 +29,7 @@
#include "llfloatertranslationsettings.h"
// Viewer includes
+#include "lltranslate.h"
#include "llviewercontrol.h" // for gSavedSettings
// Linden library includes
@@ -40,6 +41,41 @@
#include "llnotificationsutil.h"
#include "llradiogroup.h"
+class EnteredKeyVerifier : public LLTranslate::KeyVerificationReceiver
+{
+public:
+ EnteredKeyVerifier(LLTranslate::EService service, bool alert)
+ : LLTranslate::KeyVerificationReceiver(service)
+ , mAlert(alert)
+ {
+ }
+
+private:
+ /*virtual*/ void setVerificationStatus(bool ok)
+ {
+ LLFloaterTranslationSettings* floater =
+ LLFloaterReg::getTypedInstance<LLFloaterTranslationSettings>("prefs_translation");
+
+ if (!floater)
+ {
+ llwarns << "Cannot find translation settings floater" << llendl;
+ return;
+ }
+
+ switch (getService())
+ {
+ case LLTranslate::SERVICE_BING:
+ floater->setBingVerified(ok, mAlert);
+ break;
+ case LLTranslate::SERVICE_GOOGLE:
+ floater->setGoogleVerified(ok, mAlert);
+ break;
+ }
+ }
+
+ bool mAlert;
+};
+
LLFloaterTranslationSettings::LLFloaterTranslationSettings(const LLSD& key)
: LLFloater(key)
, mMachineTranslationCB(NULL)
@@ -47,6 +83,11 @@ LLFloaterTranslationSettings::LLFloaterTranslationSettings(const LLSD& key)
, mTranslationServiceRadioGroup(NULL)
, mBingAPIKeyEditor(NULL)
, mGoogleAPIKeyEditor(NULL)
+, mBingVerifyBtn(NULL)
+, mGoogleVerifyBtn(NULL)
+, mOKBtn(NULL)
+, mBingKeyVerified(false)
+, mGoogleKeyVerified(false)
{
}
@@ -58,11 +99,21 @@ BOOL LLFloaterTranslationSettings::postBuild()
mTranslationServiceRadioGroup = getChild<LLRadioGroup>("translation_service_rg");
mBingAPIKeyEditor = getChild<LLLineEditor>("bing_api_key");
mGoogleAPIKeyEditor = getChild<LLLineEditor>("google_api_key");
+ mBingVerifyBtn = getChild<LLButton>("verify_bing_api_key_btn");
+ mGoogleVerifyBtn = getChild<LLButton>("verify_google_api_key_btn");
+ mOKBtn = getChild<LLButton>("ok_btn");
mMachineTranslationCB->setCommitCallback(boost::bind(&LLFloaterTranslationSettings::updateControlsEnabledState, this));
mTranslationServiceRadioGroup->setCommitCallback(boost::bind(&LLFloaterTranslationSettings::updateControlsEnabledState, this));
- getChild<LLButton>("ok_btn")->setClickedCallback(boost::bind(&LLFloaterTranslationSettings::onBtnOK, this));
+ mOKBtn->setClickedCallback(boost::bind(&LLFloaterTranslationSettings::onBtnOK, this));
getChild<LLButton>("cancel_btn")->setClickedCallback(boost::bind(&LLFloater::closeFloater, this, false));
+ mBingVerifyBtn->setClickedCallback(boost::bind(&LLFloaterTranslationSettings::onBtnBingVerify, this));
+ mGoogleVerifyBtn->setClickedCallback(boost::bind(&LLFloaterTranslationSettings::onBtnGoogleVerify, this));
+
+ mBingAPIKeyEditor->setFocusReceivedCallback(boost::bind(&LLFloaterTranslationSettings::onEditorFocused, this, _1));
+ mBingAPIKeyEditor->setKeystrokeCallback(boost::bind(&LLFloaterTranslationSettings::onBingKeyEdited, this), NULL);
+ mGoogleAPIKeyEditor->setFocusReceivedCallback(boost::bind(&LLFloaterTranslationSettings::onEditorFocused, this, _1));
+ mGoogleAPIKeyEditor->setKeystrokeCallback(boost::bind(&LLFloaterTranslationSettings::onGoogleKeyEdited, this), NULL);
center();
return TRUE;
@@ -74,43 +125,78 @@ void LLFloaterTranslationSettings::onOpen(const LLSD& key)
mMachineTranslationCB->setValue(gSavedSettings.getBOOL("TranslateChat"));
mLanguageCombo->setSelectedByValue(gSavedSettings.getString("TranslateLanguage"), TRUE);
mTranslationServiceRadioGroup->setSelectedByValue(gSavedSettings.getString("TranslationService"), TRUE);
- mBingAPIKeyEditor->setText(gSavedSettings.getString("BingTranslateAPIKey"));
- mGoogleAPIKeyEditor->setText(gSavedSettings.getString("GoogleTranslateAPIKey"));
+
+ std::string bing_key = gSavedSettings.getString("BingTranslateAPIKey");
+ if (!bing_key.empty())
+ {
+ mBingAPIKeyEditor->setText(bing_key);
+ mBingAPIKeyEditor->setTentative(FALSE);
+ verifyKey(LLTranslate::SERVICE_BING, bing_key, false);
+ }
+ else
+ {
+ mBingAPIKeyEditor->setTentative(TRUE);
+ mBingKeyVerified = FALSE;
+ }
+
+ std::string google_key = gSavedSettings.getString("GoogleTranslateAPIKey");
+ if (!google_key.empty())
+ {
+ mGoogleAPIKeyEditor->setText(google_key);
+ mGoogleAPIKeyEditor->setTentative(FALSE);
+ verifyKey(LLTranslate::SERVICE_GOOGLE, google_key, false);
+ }
+ else
+ {
+ mGoogleAPIKeyEditor->setTentative(TRUE);
+ mGoogleKeyVerified = FALSE;
+ }
updateControlsEnabledState();
}
-std::string LLFloaterTranslationSettings::getSelectedService() const
+void LLFloaterTranslationSettings::setBingVerified(bool ok, bool alert)
{
- return mTranslationServiceRadioGroup->getSelectedValue().asString();
+ if (alert)
+ {
+ showAlert(ok ? "bing_api_key_verified" : "bing_api_key_not_verified");
+ }
+
+ mBingKeyVerified = ok;
+ updateControlsEnabledState();
}
-void LLFloaterTranslationSettings::showError(const std::string& err_name) const
+void LLFloaterTranslationSettings::setGoogleVerified(bool ok, bool alert)
{
- LLSD args;
- args["MESSAGE"] = getString(err_name);
- LLNotificationsUtil::add("GenericAlert", args);
+ if (alert)
+ {
+ showAlert(ok ? "google_api_key_verified" : "google_api_key_not_verified");
+ }
+
+ mGoogleKeyVerified = ok;
+ updateControlsEnabledState();
}
-bool LLFloaterTranslationSettings::validate() const
+std::string LLFloaterTranslationSettings::getSelectedService() const
{
- bool translate_chat = mMachineTranslationCB->getValue().asBoolean();
- if (!translate_chat) return true;
+ return mTranslationServiceRadioGroup->getSelectedValue().asString();
+}
- std::string service = getSelectedService();
- if (service == "bing" && mBingAPIKeyEditor->getText().empty())
- {
- showError("no_bing_api_key");
- return false;
- }
+std::string LLFloaterTranslationSettings::getEnteredBingKey() const
+{
+ return mBingAPIKeyEditor->getTentative() ? LLStringUtil::null : mBingAPIKeyEditor->getText();
+}
- if (service == "google" && mGoogleAPIKeyEditor->getText().empty())
- {
- showError("no_google_api_key");
- return false;
- }
+std::string LLFloaterTranslationSettings::getEnteredGoogleKey() const
+{
+ return mGoogleAPIKeyEditor->getTentative() ? LLStringUtil::null : mGoogleAPIKeyEditor->getText();
+}
- return true;
+void LLFloaterTranslationSettings::showAlert(const std::string& msg_name) const
+{
+ LLSD args;
+ args["MESSAGE"] = getString(msg_name);
+ LLNotificationsUtil::add("GenericAlert", args);
}
void LLFloaterTranslationSettings::updateControlsEnabledState()
@@ -118,6 +204,8 @@ void LLFloaterTranslationSettings::updateControlsEnabledState()
// Enable/disable controls based on the checkbox value.
bool on = mMachineTranslationCB->getValue().asBoolean();
std::string service = getSelectedService();
+ bool bing_selected = service == "bing";
+ bool google_selected = service == "google";
mTranslationServiceRadioGroup->setEnabled(on);
mLanguageCombo->setEnabled(on);
@@ -128,19 +216,77 @@ void LLFloaterTranslationSettings::updateControlsEnabledState()
getChild<LLTextBox>("google_api_key_label")->setEnabled(on);
mGoogleAPIKeyEditor->setEnabled(on);
- mBingAPIKeyEditor->setEnabled(on && service == "bing");
- mGoogleAPIKeyEditor->setEnabled(on && service == "google");
+ mBingAPIKeyEditor->setEnabled(on && bing_selected);
+ mGoogleAPIKeyEditor->setEnabled(on && google_selected);
+
+ mBingVerifyBtn->setEnabled(on && bing_selected &&
+ !mBingKeyVerified && !getEnteredBingKey().empty());
+ mGoogleVerifyBtn->setEnabled(on && google_selected &&
+ !mGoogleKeyVerified && !getEnteredGoogleKey().empty());
+
+ mOKBtn->setEnabled(
+ !on || (
+ (bing_selected && mBingKeyVerified) ||
+ (google_selected && mGoogleKeyVerified)
+ ));
}
-void LLFloaterTranslationSettings::onBtnOK()
+void LLFloaterTranslationSettings::verifyKey(int service, const std::string& key, bool alert)
{
- if (validate())
+ LLTranslate::KeyVerificationReceiverPtr receiver =
+ new EnteredKeyVerifier((LLTranslate::EService) service, alert);
+ LLTranslate::verifyKey(receiver, key);
+}
+
+void LLFloaterTranslationSettings::onEditorFocused(LLFocusableElement* control)
+{
+ LLLineEditor* editor = dynamic_cast<LLLineEditor*>(control);
+ if (editor)
{
- gSavedSettings.setBOOL("TranslateChat", mMachineTranslationCB->getValue().asBoolean());
- gSavedSettings.setString("TranslateLanguage", mLanguageCombo->getSelectedValue().asString());
- gSavedSettings.setString("TranslationService", getSelectedService());
- gSavedSettings.setString("BingTranslateAPIKey", mBingAPIKeyEditor->getText());
- gSavedSettings.setString("GoogleTranslateAPIKey", mGoogleAPIKeyEditor->getText());
- closeFloater(false);
+ if (editor->getTentative())
+ {
+ editor->setText(LLStringUtil::null);
+ editor->setTentative(FALSE);
+ }
}
}
+
+void LLFloaterTranslationSettings::onBingKeyEdited()
+{
+ mBingAPIKeyEditor->setTentative(FALSE);
+ setBingVerified(false, false);
+}
+
+void LLFloaterTranslationSettings::onGoogleKeyEdited()
+{
+ mGoogleAPIKeyEditor->setTentative(FALSE);
+ setGoogleVerified(false, false);
+}
+
+void LLFloaterTranslationSettings::onBtnBingVerify()
+{
+ std::string key = getEnteredBingKey();
+ if (!key.empty())
+ {
+ verifyKey(LLTranslate::SERVICE_BING, key);
+ }
+}
+
+void LLFloaterTranslationSettings::onBtnGoogleVerify()
+{
+ std::string key = getEnteredGoogleKey();
+ if (!key.empty())
+ {
+ verifyKey(LLTranslate::SERVICE_GOOGLE, key);
+ }
+}
+
+void LLFloaterTranslationSettings::onBtnOK()
+{
+ gSavedSettings.setBOOL("TranslateChat", mMachineTranslationCB->getValue().asBoolean());
+ gSavedSettings.setString("TranslateLanguage", mLanguageCombo->getSelectedValue().asString());
+ gSavedSettings.setString("TranslationService", getSelectedService());
+ gSavedSettings.setString("BingTranslateAPIKey", getEnteredBingKey());
+ gSavedSettings.setString("GoogleTranslateAPIKey", getEnteredGoogleKey());
+ closeFloater(false);
+}
diff --git a/indra/newview/llfloatertranslationsettings.h b/indra/newview/llfloatertranslationsettings.h
index 47e2fc80e6..9b47ad72ed 100644
--- a/indra/newview/llfloatertranslationsettings.h
+++ b/indra/newview/llfloatertranslationsettings.h
@@ -29,6 +29,7 @@
#include "llfloater.h"
+class LLButton;
class LLCheckBoxCtrl;
class LLComboBox;
class LLLineEditor;
@@ -41,11 +42,22 @@ public:
/*virtual*/ BOOL postBuild();
/*virtual*/ void onOpen(const LLSD& key);
+ void setBingVerified(bool ok, bool alert);
+ void setGoogleVerified(bool ok, bool alert);
+
private:
std::string getSelectedService() const;
- void showError(const std::string& err_name) const;
- bool validate() const;
+ std::string getEnteredBingKey() const;
+ std::string getEnteredGoogleKey() const;
+ void showAlert(const std::string& msg_name) const;
void updateControlsEnabledState();
+ void verifyKey(int service, const std::string& key, bool alert = true);
+
+ void onEditorFocused(LLFocusableElement* control);
+ void onBingKeyEdited();
+ void onGoogleKeyEdited();
+ void onBtnBingVerify();
+ void onBtnGoogleVerify();
void onBtnOK();
LLCheckBoxCtrl* mMachineTranslationCB;
@@ -53,6 +65,12 @@ private:
LLLineEditor* mBingAPIKeyEditor;
LLLineEditor* mGoogleAPIKeyEditor;
LLRadioGroup* mTranslationServiceRadioGroup;
+ LLButton* mBingVerifyBtn;
+ LLButton* mGoogleVerifyBtn;
+ LLButton* mOKBtn;
+
+ bool mBingKeyVerified;
+ bool mGoogleKeyVerified;
};
#endif // LL_LLFLOATERTRANSLATIONSETTINGS_H
diff --git a/indra/newview/lltranslate.cpp b/indra/newview/lltranslate.cpp
index a74b252c68..7b99c20a58 100644
--- a/indra/newview/lltranslate.cpp
+++ b/indra/newview/lltranslate.cpp
@@ -54,6 +54,15 @@ void LLGoogleTranslationHandler::getTranslateURL(
}
// virtual
+void LLGoogleTranslationHandler::getKeyVerificationURL(
+ std::string& url,
+ const std::string& key) const
+{
+ url = std::string("https://www.googleapis.com/language/translate/v2/languages?key=")
+ + key + "&target=en";
+}
+
+// virtual
bool LLGoogleTranslationHandler::parseResponse(
int& status,
const std::string& body,
@@ -153,6 +162,15 @@ void LLBingTranslarionHandler::getTranslateURL(
}
// virtual
+void LLBingTranslarionHandler::getKeyVerificationURL(
+ std::string& url,
+ const std::string& key) const
+{
+ url = std::string("http://api.microsofttranslator.com/v2/Http.svc/GetLanguagesForTranslate?appId=")
+ + key;
+}
+
+// virtual
bool LLBingTranslarionHandler::parseResponse(
int& status,
const std::string& body,
@@ -251,6 +269,27 @@ void LLTranslate::TranslationReceiver::completedRaw(
}
}
+LLTranslate::KeyVerificationReceiver::KeyVerificationReceiver(EService service)
+: mService(service)
+{
+}
+
+LLTranslate::EService LLTranslate::KeyVerificationReceiver::getService() const
+{
+ return mService;
+}
+
+// virtual
+void LLTranslate::KeyVerificationReceiver::completedRaw(
+ U32 http_status,
+ const std::string& reason,
+ const LLChannelDescriptors& channels,
+ const LLIOPipe::buffer_ptr_t& buffer)
+{
+ bool ok = (http_status == 200);
+ setVerificationStatus(ok);
+}
+
//static
void LLTranslate::translateMessage(
TranslationReceiverPtr &receiver,
@@ -261,24 +300,21 @@ void LLTranslate::translateMessage(
std::string url;
receiver->mHandler.getTranslateURL(url, from_lang, to_lang, mesg);
- static const float REQUEST_TIMEOUT = 5;
- static LLSD sHeader;
-
- if (!sHeader.size())
- {
- std::string user_agent = llformat("%s %d.%d.%d (%d)",
- LLVersionInfo::getChannel().c_str(),
- LLVersionInfo::getMajor(),
- LLVersionInfo::getMinor(),
- LLVersionInfo::getPatch(),
- LLVersionInfo::getBuild());
+ LL_DEBUGS("Translate") << "Sending translation request: " << url << LL_ENDL;
+ sendRequest(url, receiver);
+}
- sHeader.insert("Accept", "text/plain");
- sHeader.insert("User-Agent", user_agent);
- }
+// static
+void LLTranslate::verifyKey(
+ KeyVerificationReceiverPtr& receiver,
+ const std::string& key)
+{
+ std::string url;
+ const LLTranslationAPIHandler& handler = getHandler(receiver->getService());
+ handler.getKeyVerificationURL(url, key);
- LL_DEBUGS("Translate") << "Sending translation request: " << url << LL_ENDL;
- LLHTTPClient::get(url, receiver, sHeader, REQUEST_TIMEOUT);
+ LL_DEBUGS("Translate") << "Sending key verification request: " << url << LL_ENDL;
+ sendRequest(url, receiver);
}
//static
@@ -296,14 +332,49 @@ std::string LLTranslate::getTranslateLanguage()
// static
const LLTranslationAPIHandler& LLTranslate::getPreferredHandler()
{
+ EService service = SERVICE_BING;
+
+ std::string service_str = gSavedSettings.getString("TranslationService");
+ if (service_str == "google")
+ {
+ service = SERVICE_GOOGLE;
+ }
+
+ return getHandler(service);
+}
+
+// static
+const LLTranslationAPIHandler& LLTranslate::getHandler(EService service)
+{
static LLGoogleTranslationHandler google;
static LLBingTranslarionHandler bing;
- std::string service = gSavedSettings.getString("TranslationService");
- if (service == "google")
+ if (service == SERVICE_GOOGLE)
{
return google;
}
return bing;
}
+
+// static
+void LLTranslate::sendRequest(const std::string& url, LLHTTPClient::ResponderPtr responder)
+{
+ static const float REQUEST_TIMEOUT = 5;
+ static LLSD sHeader;
+
+ if (!sHeader.size())
+ {
+ std::string user_agent = llformat("%s %d.%d.%d (%d)",
+ LLVersionInfo::getChannel().c_str(),
+ LLVersionInfo::getMajor(),
+ LLVersionInfo::getMinor(),
+ LLVersionInfo::getPatch(),
+ LLVersionInfo::getBuild());
+
+ sHeader.insert("Accept", "text/plain");
+ sHeader.insert("User-Agent", user_agent);
+ }
+
+ LLHTTPClient::get(url, responder, sHeader, REQUEST_TIMEOUT);
+}
diff --git a/indra/newview/lltranslate.h b/indra/newview/lltranslate.h
index 1bf6965fd4..672a56af8b 100644
--- a/indra/newview/lltranslate.h
+++ b/indra/newview/lltranslate.h
@@ -44,6 +44,10 @@ public:
const std::string &to_lang,
const std::string &text) const = 0;
+ virtual void getKeyVerificationURL(
+ std::string &url,
+ const std::string &key) const = 0;
+
virtual bool parseResponse(
int& status,
const std::string& body,
@@ -67,6 +71,9 @@ public:
const std::string &from_lang,
const std::string &to_lang,
const std::string &text) const;
+ /*virtual*/ void getKeyVerificationURL(
+ std::string &url,
+ const std::string &key) const;
/*virtual*/ bool parseResponse(
int& status,
const std::string& body,
@@ -96,6 +103,9 @@ public:
const std::string &from_lang,
const std::string &to_lang,
const std::string &text) const;
+ /*virtual*/ void getKeyVerificationURL(
+ std::string &url,
+ const std::string &key) const;
/*virtual*/ bool parseResponse(
int& status,
const std::string& body,
@@ -112,6 +122,12 @@ class LLTranslate
LOG_CLASS(LLTranslate);
public :
+
+ typedef enum e_service {
+ SERVICE_BING,
+ SERVICE_GOOGLE,
+ } EService;
+
class TranslationReceiver: public LLHTTPClient::Responder
{
public:
@@ -134,13 +150,34 @@ public :
const LLTranslationAPIHandler& mHandler;
};
+ class KeyVerificationReceiver: public LLHTTPClient::Responder
+ {
+ public:
+ EService getService() const;
+
+ protected:
+ KeyVerificationReceiver(EService service);
+ /*virtual*/ void completedRaw(
+ U32 http_status,
+ const std::string& reason,
+ const LLChannelDescriptors& channels,
+ const LLIOPipe::buffer_ptr_t& buffer);
+ virtual void setVerificationStatus(bool ok) = 0;
+
+ EService mService;
+ };
+
typedef boost::intrusive_ptr<TranslationReceiver> TranslationReceiverPtr;
+ typedef boost::intrusive_ptr<KeyVerificationReceiver> KeyVerificationReceiverPtr;
static void translateMessage(TranslationReceiverPtr &receiver, const std::string &from_lang, const std::string &to_lang, const std::string &mesg);
+ static void verifyKey(KeyVerificationReceiverPtr& receiver, const std::string& key);
static std::string getTranslateLanguage();
private:
static const LLTranslationAPIHandler& getPreferredHandler();
+ static const LLTranslationAPIHandler& getHandler(EService service);
+ static void sendRequest(const std::string& url, LLHTTPClient::ResponderPtr responder);
};
#endif
diff --git a/indra/newview/skins/default/xui/en/floater_translation_settings.xml b/indra/newview/skins/default/xui/en/floater_translation_settings.xml
index f21f64fcf6..e13c810820 100644
--- a/indra/newview/skins/default/xui/en/floater_translation_settings.xml
+++ b/indra/newview/skins/default/xui/en/floater_translation_settings.xml
@@ -1,16 +1,19 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
legacy_header_height="18"
- height="320"
+ height="310"
layout="topleft"
name="floater_translation_settings"
help_topic="environment_editor_floater"
save_rect="true"
title="TRANSLATION SETTINGS"
- width="350">
+ width="480">
- <string name="no_bing_api_key">Bing Translator requires and appID to function.</string>
- <string name="no_google_api_key">Google Translate requires an API key to function.</string>
+ <string name="bing_api_key_not_verified">Bing appID not verified. Please try again.</string>
+ <string name="google_api_key_not_verified">Google API key not verified. Please try again.</string>
+
+ <string name="bing_api_key_verified">Bing appID verified.</string>
+ <string name="google_api_key_verified">Google API key verified.</string>
<check_box
height="16"
@@ -125,7 +128,7 @@
<radio_group
follows="top|left"
- height="55"
+ height="70"
layout="topleft"
left_delta="10"
name="translation_service_rg"
@@ -141,7 +144,7 @@
label="Google Translate"
layout="topleft"
name="google"
- top_pad="20" />
+ top_pad="55" />
</radio_group>
<text
@@ -150,13 +153,14 @@
follows="top|right"
height="20"
layout="topleft"
- left="10"
+ left="40"
name="bing_api_key_label"
- top_pad="20"
+ top_pad="-45"
width="100">
Bing [http://www.bing.com/developers/createapp.aspx AppID]:
</text>
<line_editor
+ default_text="Enter Bing AppID and click &quot;Verify&quot;"
follows="top|left"
height="20"
layout="topleft"
@@ -164,22 +168,31 @@
max_length_chars="50"
top_delta="-4"
name="bing_api_key"
- value=""
width="220" />
+ <button
+ follows="left|top"
+ height="23"
+ label="Verify"
+ layout="topleft"
+ left_pad="10"
+ name="verify_bing_api_key_btn"
+ top_delta="-2"
+ width="90" />
<text
follows="top|right"
height="20"
layout="topleft"
- left="10"
+ left="40"
length="1"
name="google_api_key_label"
- top_pad="20"
+ top_pad="50"
type="string"
width="100">
- Google [http://code.google.com/apis/language/translate/v2/pricing.html API key]:
+ Google [http://code.google.com/apis/language/translate/v2/getting_started.html#auth API key]:
</text>
<line_editor
+ default_text="Enter Google API key and click &quot;Verify&quot;"
follows="top|left"
height="20"
layout="topleft"
@@ -188,6 +201,15 @@
top_delta="-4"
name="google_api_key"
width="220" />
+ <button
+ follows="left|top"
+ height="23"
+ label="Verify"
+ layout="topleft"
+ left_pad="10"
+ name="verify_google_api_key_btn"
+ top_delta="-2"
+ width="90" />
<text
follows="top|right"
@@ -195,11 +217,11 @@
layout="topleft"
left="155"
length="1"
- name="google_pricing_link"
- top_delta="-80"
+ name="google_links_text"
+ top_delta="-23"
type="string"
width="100">
- ([http://code.google.com/apis/language/translate/v2/pricing.html pricing])
+ [http://code.google.com/apis/language/translate/v2/pricing.html Pricing] | [https://code.google.com/apis/console Stats]
</text>
<button