llfloaterscriptdebug.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. /**
  2. * @file llfloaterscriptdebug.cpp
  3. * @brief Chat window for showing script errors and warnings
  4. *
  5. * $LicenseInfo:firstyear=2006&license=viewergpl$
  6. *
  7. * Copyright (c) 2006-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 "llfloaterscriptdebug.h"
  34. #include "llfontgl.h"
  35. #include "lluictrlfactory.h"
  36. #include "llmessage.h"
  37. #include "llhudicon.h"
  38. #include "llviewercontrol.h"
  39. #include "llviewerobjectlist.h"
  40. #include "llviewertexteditor.h"
  41. #include "llviewertexturelist.h"
  42. #include "llvoavatarself.h"
  43. //
  44. // Statics
  45. //
  46. LLFloaterScriptDebug* LLFloaterScriptDebug::sInstance = NULL;
  47. LLFrameTimer LLFloaterScriptDebug::sLastErrorTimer;
  48. //
  49. // Member Functions
  50. //
  51. LLFloaterScriptDebug::LLFloaterScriptDebug()
  52. : LLMultiFloater()
  53. {
  54. // Avoid resizing of the window to match the initial size of the
  55. // tabbed-childs, whenever a tab is opened or closed.
  56. mAutoResize = false;
  57. }
  58. LLFloaterScriptDebug::~LLFloaterScriptDebug()
  59. {
  60. sInstance = NULL;
  61. }
  62. void LLFloaterScriptDebug::show(const LLUUID& object_id)
  63. {
  64. LLFloater* floaterp = addOutputWindow(object_id);
  65. if (sInstance)
  66. {
  67. sInstance->open();
  68. sInstance->showFloater(floaterp);
  69. }
  70. }
  71. void* getOutputWindow(void* data)
  72. {
  73. return new LLFloaterScriptDebugOutput();
  74. }
  75. LLFloater* LLFloaterScriptDebug::addOutputWindow(const LLUUID& object_id)
  76. {
  77. if (!sInstance)
  78. {
  79. sInstance = new LLFloaterScriptDebug();
  80. LLCallbackMap::map_t factory_map;
  81. factory_map["all_scripts"] = LLCallbackMap(getOutputWindow, NULL);
  82. LLUICtrlFactory::getInstance()->buildFloater(sInstance,
  83. "floater_script_debug.xml",
  84. &factory_map);
  85. sInstance->setVisible(false);
  86. }
  87. LLFloater* floaterp;
  88. {
  89. LLHostFloater host(sInstance);
  90. floaterp = LLFloaterScriptDebugOutput::show(object_id);
  91. }
  92. // Tabs sometimes overlap resize handle
  93. sInstance->moveResizeHandlesToFront();
  94. return floaterp;
  95. }
  96. void LLFloaterScriptDebug::addScriptLine(const std::string& utf8mesg,
  97. const std::string& user_name,
  98. const LLColor4& color,
  99. const LLUUID& source_id)
  100. {
  101. LLViewerObject* objectp = gObjectList.findObject(source_id);
  102. std::string floater_label;
  103. if (objectp)
  104. {
  105. if (objectp->isHUDAttachment() && isAgentAvatarValid())
  106. {
  107. objectp = gAgentAvatarp;
  108. }
  109. LLViewerFetchedTexture* tex =
  110. LLViewerTextureManager::getFetchedTextureFromFile("script_error.j2c");
  111. LLHUDIcon* hud_icon = objectp->setIcon(tex);
  112. hud_icon->setClickedCallback(LLFloaterScriptDebug::show);
  113. floater_label = llformat("%s (%.0f, %.0f, %.0f)", user_name.c_str(),
  114. objectp->getPositionRegion().mV[VX],
  115. objectp->getPositionRegion().mV[VY],
  116. objectp->getPositionRegion().mV[VZ]);
  117. }
  118. else
  119. {
  120. floater_label = user_name;
  121. }
  122. addOutputWindow(LLUUID::null);
  123. addOutputWindow(source_id);
  124. // Add to "All" floater
  125. LLFloaterScriptDebugOutput* floaterp =
  126. LLFloaterScriptDebugOutput::getFloaterByID(LLUUID::null);
  127. floaterp->addLine(utf8mesg, user_name, color);
  128. // Add to specific script instance floater
  129. floaterp = LLFloaterScriptDebugOutput::getFloaterByID(source_id);
  130. floaterp->addLine(utf8mesg, floater_label, color);
  131. sLastErrorTimer.resetWithExpiry(LLHUDIcon::MAX_VISIBLE_TIME);
  132. }
  133. //
  134. // LLFloaterScriptDebugOutput
  135. //
  136. LLFloaterScriptDebugOutput::instance_map_t LLFloaterScriptDebugOutput::sInstanceMap;
  137. LLFloaterScriptDebugOutput::LLFloaterScriptDebugOutput()
  138. : mObjectID(LLUUID::null)
  139. {
  140. sInstanceMap[mObjectID] = this;
  141. }
  142. LLFloaterScriptDebugOutput::LLFloaterScriptDebugOutput(const LLUUID& object_id)
  143. : LLFloater("script log", LLRect(0, 200, 200, 0), "Script", true),
  144. mObjectID(object_id)
  145. {
  146. S32 y = getRect().getHeight() - LLFLOATER_HEADER_SIZE - LLFLOATER_VPAD;
  147. S32 x = LLFLOATER_HPAD;
  148. // History editor. Give it a border on the top
  149. LLRect history_editor_rect(x, y, getRect().getWidth() - LLFLOATER_HPAD,
  150. LLFLOATER_VPAD);
  151. mHistoryEditor = new LLViewerTextEditor("log", history_editor_rect,
  152. S32_MAX, LLStringUtil::null,
  153. LLFontGL::getFontSansSerif());
  154. mHistoryEditor->setWordWrap(true);
  155. mHistoryEditor->setFollowsAll();
  156. mHistoryEditor->setEnabled(false);
  157. // We want to be able to cut or copy from the history:
  158. mHistoryEditor->setTabStop(true);
  159. addChild(mHistoryEditor);
  160. }
  161. void LLFloaterScriptDebugOutput::initFloater(const std::string& title,
  162. bool resizable,
  163. S32 min_width, S32 min_height,
  164. bool drag_on_left,
  165. bool minimizable, bool close_btn)
  166. {
  167. LLFloater::initFloater(title, resizable, min_width, min_height,
  168. drag_on_left, minimizable, close_btn);
  169. S32 y = getRect().getHeight() - LLFLOATER_HEADER_SIZE - LLFLOATER_VPAD;
  170. S32 x = LLFLOATER_HPAD;
  171. // History editor. Give it a border on the top
  172. LLRect history_editor_rect(x, y, getRect().getWidth() - LLFLOATER_HPAD,
  173. LLFLOATER_VPAD);
  174. mHistoryEditor = new LLViewerTextEditor("log", history_editor_rect,
  175. S32_MAX, LLStringUtil::null,
  176. LLFontGL::getFontSansSerif());
  177. mHistoryEditor->setWordWrap(true);
  178. mHistoryEditor->setFollowsAll();
  179. mHistoryEditor->setEnabled(false);
  180. // We want to be able to cut or copy from the history:
  181. mHistoryEditor->setTabStop(true);
  182. addChild(mHistoryEditor);
  183. }
  184. LLFloaterScriptDebugOutput::~LLFloaterScriptDebugOutput()
  185. {
  186. sInstanceMap.erase(mObjectID);
  187. }
  188. void LLFloaterScriptDebugOutput::addLine(const std::string& utf8mesg,
  189. const std::string& user_name,
  190. const LLColor4& color)
  191. {
  192. if (mObjectID.isNull())
  193. {
  194. //setTitle("[All scripts]");
  195. setCanTearOff(false);
  196. setCanClose(false);
  197. }
  198. else
  199. {
  200. setTitle(user_name);
  201. }
  202. mHistoryEditor->appendColoredText(utf8mesg, false, true, color);
  203. }
  204. //static
  205. LLFloaterScriptDebugOutput* LLFloaterScriptDebugOutput::show(const LLUUID& object_id)
  206. {
  207. LLFloaterScriptDebugOutput* floaterp = NULL;
  208. instance_map_t::iterator found_it = sInstanceMap.find(object_id);
  209. if (found_it == sInstanceMap.end())
  210. {
  211. floaterp = new LLFloaterScriptDebugOutput(object_id);
  212. sInstanceMap[object_id] = floaterp;
  213. floaterp->open();
  214. }
  215. else
  216. {
  217. floaterp = found_it->second;
  218. }
  219. return floaterp;
  220. }
  221. //static
  222. LLFloaterScriptDebugOutput* LLFloaterScriptDebugOutput::getFloaterByID(const LLUUID& object_id)
  223. {
  224. LLFloaterScriptDebugOutput* floaterp = NULL;
  225. instance_map_t::iterator found_it = sInstanceMap.find(object_id);
  226. if (found_it != sInstanceMap.end())
  227. {
  228. floaterp = found_it->second;
  229. }
  230. return floaterp;
  231. }