llfloaterurlentry.cpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. /**
  2. * @file llfloaterurlentry.cpp
  3. * @brief LLFloaterURLEntry class implementation
  4. *
  5. * $LicenseInfo:firstyear=2007&license=viewergpl$
  6. *
  7. * Copyright (c) 2007-2009, Linden Research, Inc.
  8. *
  9. * Second Life Viewer Source Code
  10. * The source code in this file ("Source Code") is provided by Linden Lab
  11. * to you under the terms of the GNU General Public License, version 2.0
  12. * ("GPL"), unless you have obtained a separate licensing agreement
  13. * ("Other License"), formally executed by you and Linden Lab. Terms of
  14. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16. *
  17. * There are special exceptions to the terms and conditions of the GPL as
  18. * it is applied to this Source Code. View the full text of the exception
  19. * in the file doc/FLOSS-exception.txt in this software distribution, or
  20. * online at
  21. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22. *
  23. * By copying, modifying or distributing this software, you acknowledge
  24. * that you have read and understood your obligations described above,
  25. * and agree to abide by those obligations.
  26. *
  27. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29. * COMPLETENESS OR PERFORMANCE.
  30. * $/LicenseInfo$
  31. */
  32. #include "llviewerprecompiledheaders.h"
  33. #include "llfloaterurlentry.h"
  34. #include "llcombobox.h"
  35. #include "llcorehttputil.h"
  36. #include "llmimetypes.h"
  37. #include "lluictrlfactory.h"
  38. #include "llurlhistory.h"
  39. #include "llwindow.h"
  40. #include "llpanelface.h"
  41. #include "llpanellandmedia.h"
  42. static LLFloaterURLEntry* sInstance = NULL;
  43. LLFloaterURLEntry::LLFloaterURLEntry(LLHandle<LLPanel> parent)
  44. : LLFloater(),
  45. mParentPanelHandle(parent)
  46. {
  47. LLUICtrlFactory::getInstance()->buildFloater(this, "floater_url_entry.xml");
  48. mMediaURLCombo = getChild<LLComboBox>("media_entry");
  49. // Cancel button
  50. childSetAction("cancel_btn", onBtnCancel, this);
  51. // Cancel button
  52. childSetAction("clear_btn", onBtnClear, this);
  53. // clear media list button
  54. LLSD parcel_history = LLURLHistory::getURLHistory("parcel");
  55. bool enable_clear_button = parcel_history.size() > 0 ? true : false;
  56. childSetEnabled("clear_btn", enable_clear_button);
  57. // OK button
  58. childSetAction("ok_btn", onBtnOK, this);
  59. setDefaultBtn("ok_btn");
  60. buildURLHistory();
  61. sInstance = this;
  62. }
  63. LLFloaterURLEntry::~LLFloaterURLEntry()
  64. {
  65. sInstance = NULL;
  66. }
  67. void LLFloaterURLEntry::buildURLHistory()
  68. {
  69. mMediaURLCombo->operateOnAll(LLComboBox::OP_DELETE);
  70. // Get all of the entries in the "parcel" collection
  71. LLSD parcel_history = LLURLHistory::getURLHistory("parcel");
  72. for (LLSD::array_iterator iter = parcel_history.beginArray(),
  73. end = parcel_history.endArray();
  74. iter != end; ++iter)
  75. {
  76. mMediaURLCombo->addSimpleElement(iter->asString());
  77. }
  78. }
  79. void LLFloaterURLEntry::headerFetchComplete(S32 status,
  80. const std::string& mime_type)
  81. {
  82. LLPanelLandMedia* panel_media =
  83. dynamic_cast<LLPanelLandMedia*>(mParentPanelHandle.get());
  84. if (panel_media)
  85. {
  86. // 'status' is ignored for now -- error = "none/none"
  87. panel_media->setMediaType(mime_type);
  88. panel_media->setMediaURL(mMediaURLCombo->getValue().asString());
  89. }
  90. else
  91. {
  92. LLPanelFace* panel_face =
  93. dynamic_cast<LLPanelFace*>(mParentPanelHandle.get());
  94. if (panel_face)
  95. {
  96. panel_face->setMediaType(mime_type);
  97. panel_face->setMediaURL(mMediaURLCombo->getValue().asString());
  98. }
  99. }
  100. // Decrement the cursor
  101. gWindowp->decBusyCount();
  102. childSetVisible("loading_label", false);
  103. close();
  104. }
  105. //static
  106. LLHandle<LLFloater> LLFloaterURLEntry::show(LLHandle<LLPanel> parent,
  107. const std::string media_url)
  108. {
  109. if (sInstance)
  110. {
  111. sInstance->open();
  112. }
  113. else
  114. {
  115. sInstance = new LLFloaterURLEntry(parent);
  116. }
  117. sInstance->addURLToCombobox(media_url);
  118. return sInstance->getHandle();
  119. }
  120. bool LLFloaterURLEntry::addURLToCombobox(const std::string& media_url)
  121. {
  122. if (!mMediaURLCombo->setSimple(media_url) && ! media_url.empty())
  123. {
  124. mMediaURLCombo->add(media_url);
  125. mMediaURLCombo->setSimple(media_url);
  126. return true;
  127. }
  128. // URL was not added for whatever reason (either it was empty or already
  129. // existed)
  130. return false;
  131. }
  132. //static
  133. void LLFloaterURLEntry::onBtnOK(void* userdata)
  134. {
  135. LLFloaterURLEntry* self =(LLFloaterURLEntry*)userdata;
  136. if (!self) return;
  137. std::string media_url = self->mMediaURLCombo->getValue().asString();
  138. self->mMediaURLCombo->remove(media_url);
  139. LLURLHistory::removeURL("parcel", media_url);
  140. if (self->addURLToCombobox(media_url))
  141. {
  142. // Add this url to the parcel collection
  143. LLURLHistory::addURL("parcel", media_url);
  144. }
  145. // show progress bar here?
  146. gWindowp->incBusyCount();
  147. self->childSetVisible("loading_label", true);
  148. // Leading whitespace causes problems with the MIME-type detection so strip
  149. // it
  150. LLStringUtil::trim(media_url);
  151. // First check the URL scheme
  152. LLURI url(media_url);
  153. std::string scheme = url.scheme();
  154. // We assume that an empty scheme is an http url, as this is how we will
  155. // treat it.
  156. if (scheme == "")
  157. {
  158. scheme = "http";
  159. }
  160. // Discover the MIME type only for "http" scheme.
  161. if (scheme == "http" || scheme == "https")
  162. {
  163. gCoros.launch("LLFloaterURLEntry::getMediaTypeCoro",
  164. boost::bind(&LLFloaterURLEntry::getMediaTypeCoro,
  165. media_url, self->getHandle()));
  166. }
  167. else
  168. {
  169. self->headerFetchComplete(0, scheme);
  170. }
  171. // Grey the buttons until we get the header response
  172. self->childSetEnabled("ok_btn", false);
  173. self->childSetEnabled("cancel_btn", false);
  174. self->mMediaURLCombo->setEnabled(false);
  175. }
  176. //static
  177. void LLFloaterURLEntry::getMediaTypeCoro(const std::string& url,
  178. LLHandle<LLFloater> handle)
  179. {
  180. LLCore::HttpOptions::ptr_t options(new LLCore::HttpOptions);
  181. options->setHeadersOnly(true);
  182. LLCoreHttpUtil::HttpCoroutineAdapter adapter("getMediaTypeCoro");
  183. LLSD result = adapter.getAndSuspend(url, options);
  184. LLFloaterURLEntry* self;
  185. self = handle.isDead() ? NULL
  186. : dynamic_cast<LLFloaterURLEntry*>(handle.get());
  187. if (!self)
  188. {
  189. llwarns << "Floater closed before response." << llendl;
  190. return;
  191. }
  192. std::string resolved_mime_type = LLMIMETypes::getDefaultMimeType();
  193. const LLSD& http_results =
  194. result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
  195. LLCore::HttpStatus status =
  196. LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(http_results);
  197. if (status)
  198. {
  199. const LLSD& headers =
  200. http_results[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS];
  201. if (headers.has(HTTP_IN_HEADER_CONTENT_TYPE))
  202. {
  203. std::string media_type = headers[HTTP_IN_HEADER_CONTENT_TYPE];
  204. size_t idx = media_type.find_first_of(";");
  205. if (idx != std::string::npos)
  206. {
  207. media_type = media_type.substr(0, idx);
  208. }
  209. if (!media_type.empty())
  210. {
  211. resolved_mime_type = media_type;
  212. }
  213. }
  214. }
  215. self->headerFetchComplete(status.getType(), resolved_mime_type);
  216. }
  217. //static
  218. void LLFloaterURLEntry::onBtnCancel(void* userdata)
  219. {
  220. LLFloaterURLEntry* self = (LLFloaterURLEntry*)userdata;
  221. if (self)
  222. {
  223. self->close();
  224. }
  225. }
  226. //static
  227. void LLFloaterURLEntry::onBtnClear(void* userdata)
  228. {
  229. gNotifications.add("ConfirmClearMediaUrlList", LLSD(), LLSD(),
  230. boost::bind(&LLFloaterURLEntry::callback_clear_url_list,
  231. (LLFloaterURLEntry*)userdata, _1, _2));
  232. }
  233. bool LLFloaterURLEntry::callback_clear_url_list(const LLSD& notification,
  234. const LLSD& response)
  235. {
  236. if (LLNotification::getSelectedOption(notification, response) == 0) // YES
  237. {
  238. // Clear saved list
  239. mMediaURLCombo->operateOnAll(LLComboBox::OP_DELETE);
  240. // Clear current contents of combo box
  241. mMediaURLCombo->clear();
  242. // Clear stored version of list
  243. LLURLHistory::clear("parcel");
  244. // Cleared the list so disable Clear button
  245. childSetEnabled("clear_btn", false);
  246. }
  247. return false;
  248. }