PageRenderTime 108ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/fp10/src/com/furusystems/dconsole2/DConsole.as

http://doomsdayconsole.googlecode.com/
ActionScript | 1972 lines | 1521 code | 196 blank | 255 comment | 209 complexity | aa90f869e632fa7abbcb4c1b0c635b2a MD5 | raw file
  1. package com.furusystems.dconsole2
  2. {
  3. //{ imports
  4. import com.furusystems.dconsole2.core.commands.CommandManager;
  5. import com.furusystems.dconsole2.core.commands.ConsoleCommand;
  6. import com.furusystems.dconsole2.core.commands.FunctionCallCommand;
  7. import com.furusystems.dconsole2.core.commands.IntrospectionCommand;
  8. import com.furusystems.dconsole2.core.DSprite;
  9. import com.furusystems.dconsole2.core.errors.CommandError;
  10. import com.furusystems.dconsole2.core.errors.ConsoleAuthError;
  11. import com.furusystems.dconsole2.core.errors.ErrorStrings;
  12. import com.furusystems.dconsole2.core.gui.debugdraw.DebugDraw;
  13. import com.furusystems.dconsole2.core.gui.DockingGuides;
  14. import com.furusystems.dconsole2.core.gui.maindisplay.assistant.Assistant;
  15. import com.furusystems.dconsole2.core.gui.maindisplay.ConsoleView;
  16. import com.furusystems.dconsole2.core.gui.maindisplay.filtertabrow.FilterTabRow;
  17. import com.furusystems.dconsole2.core.gui.maindisplay.input.InputField;
  18. import com.furusystems.dconsole2.core.gui.maindisplay.output.OutputField;
  19. import com.furusystems.dconsole2.core.gui.maindisplay.toolbar.ConsoleToolbar;
  20. import com.furusystems.dconsole2.core.gui.ScaleHandle;
  21. import com.furusystems.dconsole2.core.gui.ToolTip;
  22. import com.furusystems.dconsole2.core.helpmanager.HelpManager;
  23. import com.furusystems.dconsole2.core.input.KeyBindings;
  24. import com.furusystems.dconsole2.core.input.KeyboardManager;
  25. import com.furusystems.dconsole2.core.input.KeyHandlerResult;
  26. import com.furusystems.dconsole2.core.introspection.InspectionUtils;
  27. import com.furusystems.dconsole2.core.introspection.IntrospectionScope;
  28. import com.furusystems.dconsole2.core.introspection.ScopeManager;
  29. import com.furusystems.dconsole2.core.logmanager.DConsoleLog;
  30. import com.furusystems.dconsole2.core.logmanager.DLogFilter;
  31. import com.furusystems.dconsole2.core.logmanager.DLogManager;
  32. import com.furusystems.dconsole2.core.Notifications;
  33. import com.furusystems.dconsole2.core.output.ConsoleMessage;
  34. import com.furusystems.dconsole2.core.output.ConsoleMessageRepeatMode;
  35. import com.furusystems.dconsole2.core.output.ConsoleMessageTypes;
  36. import com.furusystems.dconsole2.core.persistence.PersistenceManager;
  37. import com.furusystems.dconsole2.core.plugins.PluginManager;
  38. import com.furusystems.dconsole2.core.references.ReferenceManager;
  39. import com.furusystems.dconsole2.core.security.ConsoleLock;
  40. import com.furusystems.dconsole2.core.style.StyleManager;
  41. import com.furusystems.dconsole2.core.text.autocomplete.AutocompleteDictionary;
  42. import com.furusystems.dconsole2.core.text.autocomplete.AutocompleteManager;
  43. import com.furusystems.dconsole2.core.text.TextUtils;
  44. import com.furusystems.dconsole2.core.utils.StringUtil;
  45. import com.furusystems.dconsole2.core.Version;
  46. import com.furusystems.dconsole2.logging.ConsoleLogBinding;
  47. import com.furusystems.logging.slf4as.Logging;
  48. import com.furusystems.messaging.pimp.Message;
  49. import com.furusystems.messaging.pimp.MessageData;
  50. import com.furusystems.messaging.pimp.PimpCentral;
  51. import flash.desktop.Clipboard;
  52. import flash.desktop.ClipboardFormats;
  53. import flash.display.DisplayObject;
  54. import flash.display.Loader;
  55. import flash.display.Sprite;
  56. import flash.display.StageAlign;
  57. import flash.display.StageScaleMode;
  58. import flash.events.Event;
  59. import flash.events.KeyboardEvent;
  60. import flash.events.TextEvent;
  61. import flash.events.TimerEvent;
  62. import flash.geom.Rectangle;
  63. import flash.net.URLRequest;
  64. import flash.system.Capabilities;
  65. import flash.system.System;
  66. import flash.ui.Keyboard;
  67. import flash.utils.Timer;
  68. //}
  69. /**
  70. * ActionScript 3 logger, commandline interface and utility platform
  71. * @author Andreas Roenning
  72. * @author Cristobal Dabed
  73. * @author Furu systems
  74. */
  75. public class DConsole extends DSprite implements IConsole
  76. {
  77. //{ members
  78. public var ignoreBlankLines:Boolean = true;
  79. private var _initialized:Boolean = false;
  80. private var _autoCompleteManager:AutocompleteManager;
  81. private var _globalDictionary:AutocompleteDictionary = new AutocompleteDictionary();
  82. private var _styleManager:StyleManager;
  83. private var _referenceManager:ReferenceManager;
  84. private var _scopeManager:ScopeManager;
  85. private var _commandManager:CommandManager;
  86. private var _toolTip:ToolTip;
  87. private var _visible:Boolean = false;
  88. private var _isVisible:Boolean = true; //TODO: Fix naming ambiguity; _isVisible refers to the native visibility toggle
  89. private var _persistence:PersistenceManager;
  90. private var _callCommand:FunctionCallCommand;
  91. private var _getCommand:FunctionCallCommand;
  92. private var _setCommand:FunctionCallCommand;
  93. private var _selectCommand:FunctionCallCommand;
  94. private var _quickSearchEnabled:Boolean = true;
  95. private var _repeatMessageMode:int = ConsoleMessageRepeatMode.STACK;
  96. private var _bgLayer:Sprite = new Sprite();
  97. private var _topLayer:Sprite = new Sprite();
  98. private var _consoleBackground:Sprite = new Sprite();
  99. private var _keystroke:uint = KeyBindings.ENTER;
  100. private var _modifier:uint = KeyBindings.CTRL_SHIFT;
  101. private var _lock:ConsoleLock = new ConsoleLock();
  102. private var _plugManager:PluginManager;
  103. private var _logManager:DLogManager;
  104. private var _autoCreateTagLogs:Boolean = true; //If true, automatically create new logs when a new tag is encountered
  105. private var _dockingGuides:DockingGuides;
  106. private var _overrideCallback:Function = null;
  107. private var _cancelNextKey:Boolean = false;
  108. private var _defaultInputCallback:Function;
  109. private var _mainConsoleView:ConsoleView;
  110. private var _debugDraw:DebugDraw;
  111. private var _consoleContainer:Sprite;
  112. private var _messaging:PimpCentral = new PimpCentral();
  113. private var _trigger:uint = Keyboard.TAB;
  114. private var _helpManager:HelpManager;
  115. private var _debugMode:Boolean = false; //Internal debugging flag
  116. static public const DOCK_TOP:int = 0;
  117. static public const DOCK_BOT:int = 1;
  118. static public const DOCK_WINDOWED:int = -1;
  119. static private const UPDATE_FROM_ENTER_FRAME:int = 0;
  120. static private const UPDATE_FROM_TIMER:int = 1;
  121. private var _updateSource:int = UPDATE_FROM_TIMER;
  122. private var _updateTimer:Timer = new Timer(33);
  123. //} end members
  124. //{ Instance
  125. /**
  126. * Creates a new DConsole instance.
  127. * This class is intended to always be on top of the stage of the application it is associated with.
  128. * Using the DConsole.instance getter is recommended
  129. */
  130. public function DConsole()
  131. {
  132. //Prepare logging
  133. _styleManager = new StyleManager(this);
  134. _persistence = new PersistenceManager(this);
  135. _updateTimer.addEventListener(TimerEvent.TIMER, frameUpdate);
  136. _logManager = new DLogManager(this);
  137. _mainConsoleView = new ConsoleView(this);
  138. _helpManager = new HelpManager(_messaging);
  139. output.currentLog = _logManager.currentLog;
  140. input.inputTextField.addEventListener(TextEvent.TEXT_INPUT, onTextInput);
  141. tabChildren = tabEnabled = false;
  142. _debugDraw = new DebugDraw(_messaging);
  143. _autoCompleteManager = new AutocompleteManager(input.inputTextField);
  144. _scopeManager = new ScopeManager(this, _autoCompleteManager);
  145. _autoCompleteManager.setDictionary(_globalDictionary);
  146. _referenceManager = new ReferenceManager(this, _scopeManager);
  147. _plugManager = new PluginManager(_scopeManager, _referenceManager, this, _topLayer, _bgLayer, _consoleBackground, _logManager);
  148. _commandManager = new CommandManager(this, _persistence, _referenceManager, _plugManager);
  149. _scopeManager.setCommandMgr(_commandManager);
  150. _consoleContainer = new Sprite();
  151. addChild(_consoleContainer);
  152. _consoleContainer.addChild(_debugDraw.shape);
  153. _consoleContainer.addChild(_bgLayer);
  154. _consoleContainer.addChild(_mainConsoleView);
  155. _consoleContainer.addChild(_topLayer);
  156. _dockingGuides = new DockingGuides();
  157. _consoleContainer.addChild(_dockingGuides);
  158. _toolTip = new ToolTip(this);
  159. _consoleContainer.addChild(_toolTip);
  160. input.addEventListener(Event.CHANGE, updateAssistantText);
  161. scaleHandle.addEventListener(Event.CHANGE, onScaleHandleDrag, false, 0, true);
  162. messaging.addCallback(Notifications.SCOPE_CHANGE_REQUEST, onScopeChangeRequest);
  163. messaging.addCallback(Notifications.EXECUTE_STATEMENT, onExecuteStatementNotification);
  164. messaging.addCallback(Notifications.CONSOLE_VIEW_TRANSITION_COMPLETE, onConsoleViewTransitionComplete);
  165. KeyboardManager.instance.addKeyboardShortcut(_keystroke, _modifier, toggleDisplay); // [CTRL+SHIFT, ENTER]); //default keystroke
  166. _callCommand = new FunctionCallCommand("call", _scopeManager.callMethodOnScope, "Introspection", "Calls a method with args within the current introspection scope");
  167. _setCommand = new IntrospectionCommand("set", _scopeManager.setPropertyOnObject, "Introspection", "Sets a variable within the current introspection scope");
  168. _getCommand = new IntrospectionCommand("get", _scopeManager.getPropertyOnObject, "Introspection", "Prints a variable within the current introspection scope");
  169. _selectCommand = new IntrospectionCommand("select", select, "Introspection", "Selects the specified object or reference by identifier as the current introspection scope");
  170. var basicHelp:String = "";
  171. basicHelp += "\tKeyboard commands\n";
  172. basicHelp += "\t\tControl+Shift+Enter (default) -> Show/hide console\n";
  173. basicHelp += "\t\tMaster key (Default TAB) -> (When out of focus) Set the keyboard focus to the input field\n";
  174. basicHelp += "\t\tMaster key (Default TAB) -> (While caret is on an unknown term) Context sensitive search\n";
  175. basicHelp += "\t\tEnter -> Execute line\n";
  176. basicHelp += "\t\tPage up/Page down -> Vertical scroll by page\n";
  177. basicHelp += "\t\tArrow up -> Recall the previous executed line\n";
  178. basicHelp += "\t\tArrow down -> Recall the more recent executed line\n";
  179. basicHelp += "\t\tShift + Arrow keys -> Scroll\n";
  180. basicHelp += "\t\tMouse functions\n";
  181. basicHelp += "\t\tMousewheel -> Vertical scroll line by line\n";
  182. basicHelp += "\t\tClick drag below the input line -> Change console height\n";
  183. basicHelp += "\t\tClick drag console header -> Move the console window\n";
  184. basicHelp += "\tMisc\n";
  185. basicHelp += "\t\tUse the 'commands' command to list available commmands";
  186. _helpManager.addTopic("Basic instructions", basicHelp);
  187. print("Welcome to Doomsday Console II - www.doomsday.no", ConsoleMessageTypes.SYSTEM);
  188. print("Today is " + new Date().toString(), ConsoleMessageTypes.SYSTEM);
  189. print("Console version " + Version.Major + "." + Version.Minor, ConsoleMessageTypes.SYSTEM);
  190. print("Player version " + Capabilities.version, ConsoleMessageTypes.SYSTEM);
  191. setupDefaultCommands();
  192. setRepeatFilter(ConsoleMessageRepeatMode.STACK);
  193. visible = false;
  194. print("Ready. Type help to get started.", ConsoleMessageTypes.SYSTEM);
  195. addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
  196. }
  197. private function onConsoleViewTransitionComplete(md:MessageData):void
  198. {
  199. //md.data will be true if the console is now visible, or false if it's now hidden
  200. if (!md.data)
  201. {
  202. _consoleContainer.visible = false;
  203. }
  204. }
  205. public static function get debugDraw():DebugDraw
  206. {
  207. return console.debugDraw;
  208. }
  209. private function onTextInput(e:TextEvent):void
  210. {
  211. //if (_cancelNextSpace && e.text==" ") {
  212. if (_cancelNextKey)
  213. {
  214. e.preventDefault();
  215. }
  216. _cancelNextKey = false;
  217. }
  218. public function get currentScope():IntrospectionScope
  219. {
  220. return _scopeManager.currentScope;
  221. }
  222. private function onExecuteStatementNotification(md:MessageData):void
  223. {
  224. executeStatement(String(md.data));
  225. }
  226. private function onScopeChangeRequest(md:MessageData):void
  227. {
  228. select(md.data);
  229. }
  230. private function ceaseFrameUpdates():void
  231. {
  232. if (_updateSource == UPDATE_FROM_ENTER_FRAME)
  233. {
  234. removeEventListener(Event.ENTER_FRAME, frameUpdate);
  235. }
  236. else
  237. {
  238. _updateTimer.stop();
  239. }
  240. }
  241. private function beginFrameUpdates():void
  242. {
  243. if (_updateSource == UPDATE_FROM_ENTER_FRAME)
  244. {
  245. addEventListener(Event.ENTER_FRAME, frameUpdate, false, -1000, false);
  246. }
  247. else
  248. {
  249. _updateTimer.start();
  250. }
  251. }
  252. private function frameUpdate(e:Event = null):void
  253. {
  254. _plugManager.update();
  255. view.inspector.onFrameUpdate(e);
  256. messaging.send(Notifications.FRAME_UPDATE, null, this);
  257. }
  258. /**
  259. * @readonly lock
  260. */
  261. public function get lock():ConsoleLock
  262. {
  263. return _lock;
  264. }
  265. /**
  266. * Change keyboard shortcut
  267. */
  268. public function changeKeyboardShortcut(keystroke:uint, modifier:uint):void
  269. {
  270. KeyboardManager.instance.addKeyboardShortcut(keystroke, modifier, this.toggleDisplay, true);
  271. }
  272. private function setupDefaultCommands():void
  273. {
  274. //addCommand(new FunctionCallCommand("consoleHeight", setHeight, "View", "Change the number of lines to display. Example: setHeight 5"));
  275. createCommand("about", about, "System", "Credits etc");
  276. createCommand("clear", clear, "View", "Clear the console");
  277. createCommand("showTimestamps", output.toggleTimestamp, "View", "Toggle or set display of message timestamp");
  278. createCommand("showTags", toggleTags, "View", "Toggle or set the display of message tags");
  279. createCommand("showLineNumbers", output.toggleLineNumbers, "View", "Toggles or sets the display of line numbers");
  280. createCommand("setQuicksearch", toggleQuickSearch, "System", "Toggles or sets trigger key to search commands and methods for the current word");
  281. createCommand("help", getHelp, "System", "Output instructions. Append an argument to read more about that topic.");
  282. createCommand("clearhistory", _persistence.clearHistory, "System", "Clears the stored command history");
  283. createCommand("dock", setDockVerbose, "System", "Docks the console to either 'top'(default) 'bottom'/'bot' or 'window'");
  284. createCommand("maximizeConsole", maximize, "System", "Sets console height to fill the screen");
  285. createCommand("minimizeConsole", minimize, "System", "Sets console height to 1");
  286. createCommand("setRepeatFilter", setRepeatFilter, "System", "Sets the repeat message filter; 0 - Stack, 1 - Ignore, 2 - Passthrough");
  287. createCommand("repeat", repeatCommand, "System", "Repeats command string X Y times");
  288. addCommand(new FunctionCallCommand("resetConsole", resetConsole, "System", "Resets and clears the console"), false);
  289. if (Capabilities.isDebugger)
  290. {
  291. print(" Debugplayer commands added", ConsoleMessageTypes.SYSTEM);
  292. createCommand("gc", System.gc, "Debugplayer", "Forces a garbage collection cycle");
  293. }
  294. if (Capabilities.playerType == "StandAlone" || Capabilities.playerType == "External")
  295. {
  296. print(" Projector commands added", ConsoleMessageTypes.SYSTEM);
  297. createCommand("quitapp", quitCommand, "Projector", "Quit the application");
  298. }
  299. createCommand("plugins", _plugManager.printPluginInfo, "Plugins", "Lists enabled plugin information");
  300. createCommand("commands", _commandManager.listCommands, "Utility", "Output a list of available commands. Add a second argument to search.");
  301. createCommand("search", searchCurrentLog, "Utility", "Searches the current log for a string and scrolls to the first matching line");
  302. createCommand("toClipboard", toClipBoard, "Utility", "Takes value X and puts it in the system clipboard (great for grabbing command XML output)");
  303. addCommand(_callCommand);
  304. addCommand(_getCommand);
  305. addCommand(_setCommand);
  306. addCommand(_selectCommand);
  307. createCommand("root", _scopeManager.selectBaseScope, "Introspection", "Selects the stage as the current introspection scope");
  308. createCommand("parent", _scopeManager.up, "Introspection", "(if the current scope is a display object) changes scope to the parent object");
  309. createCommand("children", _scopeManager.printChildren, "Introspection", "Get available children in the current scope");
  310. createCommand("variables", _scopeManager.printVariables, "Introspection", "Get available simple variables in the current scope");
  311. createCommand("complex", _scopeManager.printComplexObjects, "Introspection", "Get available complex variables in the current scope");
  312. createCommand("scopes", _scopeManager.printDownPath, "Introspection", "List available scopes in the current scope");
  313. createCommand("methods", _scopeManager.printMethods, "Introspection", "Get available methods in the current scope");
  314. createCommand("updateScope", _scopeManager.updateScope, "Introspection", "Gets changes to the current scope tree");
  315. createCommand("referenceThis", _referenceManager.getReference, "Referencing", "Stores a weak reference to the current scope in a specified id (referenceThis 1)");
  316. createCommand("getReference", _referenceManager.getReferenceByName, "Referencing", "Stores a weak reference to the specified scope in the specified id (getReference scopename 1)");
  317. createCommand("listReferences", _referenceManager.printReferences, "Referencing", "Lists all stored references and their IDs");
  318. createCommand("clearAllReferences", _referenceManager.clearReferences, "Referencing", "Clears all stored references");
  319. createCommand("clearReference", _referenceManager.clearReferenceByName, "Referencing", "Clears the specified reference");
  320. createCommand("loadTheme", _styleManager.load, "Theme", "Loads theme xml from urls; [x] theme [y] color table");
  321. }
  322. public function setMasterKey(key:uint):void
  323. {
  324. if (key == Keyboard.ENTER)
  325. {
  326. throw new Error("The master key can not be the enter key");
  327. }
  328. _trigger = key;
  329. }
  330. //private function switchMasterKey():void
  331. //{
  332. //_masterKeyMode = !_masterKeyMode;
  333. //if (_masterKeyMode) {
  334. //addSystemMessage("Current trigger is ctrl+space");
  335. //}else {
  336. //addSystemMessage("Current trigger is space, ctrl+space overrides");
  337. //}
  338. //}
  339. private function setDockVerbose(mode:String = "top"):void
  340. {
  341. mode = mode.toLowerCase();
  342. switch (mode)
  343. {
  344. case "bot":
  345. case "bottom":
  346. dock(DOCK_BOT);
  347. break;
  348. case "none":
  349. case "window":
  350. dock(DOCK_WINDOWED);
  351. break;
  352. case "top":
  353. default:
  354. dock(DOCK_TOP);
  355. }
  356. }
  357. private function get toolBar():ConsoleToolbar
  358. {
  359. return _mainConsoleView.toolbar;
  360. }
  361. private function get filterTabs():FilterTabRow
  362. {
  363. return _mainConsoleView.filtertabs;
  364. }
  365. private function get output():OutputField
  366. {
  367. return _mainConsoleView.output;
  368. }
  369. private function get scaleHandle():ScaleHandle
  370. {
  371. return _mainConsoleView.scaleHandle;
  372. }
  373. private function get assistant():Assistant
  374. {
  375. return _mainConsoleView.assistant;
  376. }
  377. private function get input():InputField
  378. {
  379. return _mainConsoleView.input;
  380. }
  381. private function selectTag(tag:String):void
  382. {
  383. }
  384. private function toggleTags(input:String = null):void
  385. {
  386. if (input == null)
  387. {
  388. view.output.showTag = !view.output.showTag;
  389. }
  390. else
  391. {
  392. view.output.showTag = StringUtil.verboseToBoolean(input);
  393. }
  394. view.output.update();
  395. }
  396. private function resetConsole():void
  397. {
  398. persistence.clearAll();
  399. view.splitRatio = persistence.verticalSplitRatio.value;
  400. onStageResize();
  401. _logManager.currentLog.clear();
  402. _logManager.clearFilters();
  403. addSystemMessage("GUI and history reset");
  404. }
  405. private function about():void
  406. {
  407. addSystemMessage("Doomsday Console II");
  408. addSystemMessage("\t\tversion " + Version.Major + "." + Version.Minor);
  409. addSystemMessage("\t\thttp://doomsdayconsole.googlecode.com");
  410. addSystemMessage("\t\tconcept and development by www.doomsday.no & www.furusystems.com");
  411. }
  412. private function addSearch(term:String):void
  413. {
  414. _logManager.addFilter(new DLogFilter(term));
  415. }
  416. public function searchCurrentLog(term:String):void
  417. {
  418. var idx:int = _logManager.searchCurrentLog(term);
  419. if (idx > -1)
  420. {
  421. output.scrollToLine(idx);
  422. //print("'" + term + "' found in log "+_logManager.currentLog+" at line " + idx);
  423. }
  424. else
  425. {
  426. addErrorMessage("Not found");
  427. }
  428. }
  429. public function get currentLog():DConsoleLog
  430. {
  431. return _logManager.currentLog;
  432. }
  433. private function toClipBoard(str:String):void
  434. {
  435. Clipboard.generalClipboard.setData(ClipboardFormats.TEXT_FORMAT, str);
  436. }
  437. private function getLoader(url:String):Loader
  438. {
  439. var l:Loader = new Loader();
  440. l.load(new URLRequest(url));
  441. return l;
  442. }
  443. private function repeatCommand(cmd:String, count:int = 1):void
  444. {
  445. for (var i:int = 0; i < count; i++)
  446. {
  447. executeStatement(cmd);
  448. }
  449. }
  450. public function select(target:*):void
  451. {
  452. if (_scopeManager.currentScope == target)
  453. return;
  454. try
  455. {
  456. _scopeManager.setScopeByName(String(target));
  457. }
  458. catch (e:Error)
  459. {
  460. try
  461. {
  462. _referenceManager.setScopeByReferenceKey(target);
  463. }
  464. catch (e:Error)
  465. {
  466. try
  467. {
  468. if (typeof target == "string")
  469. {
  470. throw new Error();
  471. }
  472. _scopeManager.setScope(target);
  473. }
  474. catch (e:Error)
  475. {
  476. print("No such scope", ConsoleMessageTypes.ERROR);
  477. }
  478. }
  479. }
  480. }
  481. private function toggleQuickSearch(input:String = null):void
  482. {
  483. if (input == null)
  484. {
  485. setQuickSearch(!_quickSearchEnabled);
  486. }
  487. else
  488. {
  489. setQuickSearch(StringUtil.verboseToBoolean(input));
  490. }
  491. }
  492. private function onScaleHandleDrag(e:Event):void
  493. {
  494. var my:Number;
  495. var eh:Number = 14;
  496. }
  497. private function quitCommand(code:int = 0):void
  498. {
  499. System.exit(code);
  500. }
  501. private function getHelp(topic:String = ""):void
  502. {
  503. if (topic == "")
  504. {
  505. addSystemMessage(_helpManager.getTopic("Basic instructions"));
  506. addSystemMessage(_helpManager.getToc());
  507. }
  508. else
  509. {
  510. addSystemMessage(_helpManager.getTopic(topic));
  511. }
  512. }
  513. public function executeStatement(statement:String, echo:Boolean = false):*
  514. {
  515. if (echo)
  516. print(statement, ConsoleMessageTypes.USER);
  517. return _commandManager.tryCommand(statement);
  518. }
  519. private function updateAssistantText(e:Event = null):void
  520. {
  521. if (_overrideCallback != null)
  522. return;
  523. var cmd:ConsoleCommand;
  524. var helpText:String;
  525. try
  526. {
  527. cmd = _commandManager.parseForCommand(input.text);
  528. helpText = cmd.helpText;
  529. }
  530. catch (e:Error)
  531. {
  532. helpText = "";
  533. }
  534. var secondElement:String = TextUtils.parseForSecondElement(input.text);
  535. if (secondElement)
  536. {
  537. if (cmd == _callCommand)
  538. {
  539. try
  540. {
  541. helpText = InspectionUtils.getMethodTooltip(_scopeManager.currentScope.targetObject, secondElement);
  542. }
  543. catch (e:Error)
  544. {
  545. helpText = cmd.helpText;
  546. }
  547. }
  548. else if (cmd == _setCommand || cmd == _getCommand)
  549. {
  550. try
  551. {
  552. helpText = InspectionUtils.getAccessorTooltip(_scopeManager.currentScope.targetObject, secondElement);
  553. }
  554. catch (e:Error)
  555. {
  556. helpText = cmd.helpText;
  557. }
  558. }
  559. }
  560. if (helpText != "")
  561. {
  562. assistant.text = "? " + cmd.trigger + ": " + helpText;
  563. }
  564. else
  565. {
  566. assistant.clear();
  567. }
  568. }
  569. public function setScope(o:Object):void
  570. {
  571. _scopeManager.setScope(o);
  572. }
  573. public function createCommand(triggerPhrase:String, func:Function, commandGroup:String = "Application", helpText:String = ""):void
  574. {
  575. addCommand(new FunctionCallCommand(triggerPhrase, func, commandGroup, helpText));
  576. }
  577. /**
  578. * Add a custom command to the console
  579. * @param command
  580. * An instance of FunctionCallCommand or ConsoleEventCommand
  581. */
  582. public function addCommand(command:ConsoleCommand, includeInHistory:Boolean = true):void
  583. {
  584. try
  585. {
  586. _commandManager.addCommand(command, includeInHistory);
  587. _globalDictionary.addToDictionary(command.trigger);
  588. }
  589. catch (e:ArgumentError)
  590. {
  591. print(e.message, ConsoleMessageTypes.ERROR);
  592. }
  593. }
  594. public function removeCommand(trigger:String):void
  595. {
  596. _commandManager.removeCommand(trigger);
  597. }
  598. /**
  599. * A generic function to add as listener to events you want logged
  600. * @param e
  601. */
  602. public function onEvent(e:Event):void
  603. {
  604. print("Event: " + e.toString(), ConsoleMessageTypes.INFO);
  605. }
  606. private function createMessages(str:String, type:String, tag:String):Vector.<ConsoleMessage>
  607. {
  608. var out:Vector.<ConsoleMessage> = new Vector.<ConsoleMessage>();
  609. var split:Array = str.split("\n").join("\r").split("\r");
  610. if (split.join("").length < 1 && ignoreBlankLines)
  611. return out;
  612. var date:String = String(new Date().getTime());
  613. var msg:ConsoleMessage;
  614. for (var i:int = 0; i < split.length; i++)
  615. {
  616. var txt:String = split[i];
  617. if (txt.length < 1 && ignoreBlankLines)
  618. continue;
  619. if (txt.indexOf("com.furusystems.dconsole2") > -1 || txt.indexOf("adobe.com/AS3") > -1)
  620. continue;
  621. msg = new ConsoleMessage(txt, date, type, tag);
  622. out.push(msg);
  623. }
  624. return out;
  625. }
  626. public function createTypeFilter(type:String):void
  627. {
  628. _logManager.addFilter(new DLogFilter("", type));
  629. }
  630. public function createSearchFilter(term:String):void
  631. {
  632. _logManager.addFilter(new DLogFilter(term));
  633. }
  634. public function printTo(targetLog:String, str:String, type:String = ConsoleMessageTypes.INFO, tag:String = ""):void
  635. {
  636. var log:DConsoleLog = _logManager.getLog(targetLog);
  637. var messages:Vector.<ConsoleMessage> = createMessages(str, type, tag);
  638. }
  639. /**
  640. * Add a message to the current console tab
  641. * @param str
  642. * The string to be added. A timestamp is automaticaly prefixed
  643. */
  644. public function print(str:String, type:String = ConsoleMessageTypes.INFO, tag:String = TAG):void
  645. {
  646. //TODO: Per message, examine filters and append relevant messages to the relevant logs
  647. var _tagLog:DConsoleLog;
  648. if (tag != TAG && _autoCreateTagLogs)
  649. {
  650. _tagLog = _logManager.getLog(tag);
  651. }
  652. var _rootLog:DConsoleLog = _logManager.rootLog;
  653. var messages:Vector.<ConsoleMessage> = createMessages(str, type, tag);
  654. var msg:ConsoleMessage;
  655. for (var i:int = 0; i < messages.length; i++)
  656. {
  657. //break;
  658. msg = messages[i];
  659. if (_rootLog.prevMessage)
  660. {
  661. if (_rootLog.prevMessage.text == msg.text && _rootLog.prevMessage.tag == msg.tag && _rootLog.prevMessage.type == msg.type)
  662. {
  663. switch (_repeatMessageMode)
  664. {
  665. case ConsoleMessageRepeatMode.STACK:
  666. _rootLog.prevMessage.repeatcount++;
  667. _rootLog.prevMessage.timestamp = msg.timestamp;
  668. _rootLog.setDirty();
  669. if (_tagLog)
  670. {
  671. _tagLog.setDirty();
  672. }
  673. continue;
  674. break;
  675. case ConsoleMessageRepeatMode.IGNORE:
  676. continue;
  677. break;
  678. }
  679. }
  680. }
  681. if (msg.type != ConsoleMessageTypes.USER)
  682. {
  683. var evt:Message;
  684. if (msg.type == ConsoleMessageTypes.ERROR)
  685. {
  686. evt = Notifications.ERROR;
  687. }
  688. else
  689. {
  690. evt = Notifications.NEW_CONSOLE_OUTPUT;
  691. }
  692. messaging.send(evt, msg, this);
  693. }
  694. _rootLog.addMessage(msg);
  695. if (_tagLog)
  696. _tagLog.addMessage(msg);
  697. }
  698. output.update();
  699. }
  700. /**
  701. * Clear the console
  702. */
  703. public function clear():void
  704. {
  705. _logManager.currentLog.clear();
  706. output.drawMessages();
  707. }
  708. private function setupStageAlignAndScale():void
  709. {
  710. stage.align = StageAlign.TOP_LEFT;
  711. stage.scaleMode = StageScaleMode.NO_SCALE;
  712. print("StageAlign set to TOP_LEFT, StageScaleMode set to NO_SCALE", ConsoleMessageTypes.SYSTEM);
  713. }
  714. private function onAddedToStage(e:Event):void
  715. {
  716. //branching for air
  717. is_air = Capabilities.playerType == "Desktop";
  718. Logging.logBinding = new ConsoleLogBinding();
  719. KeyboardManager.instance.setup(stage);
  720. if (stage.align != StageAlign.TOP_LEFT)
  721. {
  722. print("Warning: stage.align is not set to TOP_LEFT; This might cause scaling issues", ConsoleMessageTypes.ERROR);
  723. print("Fix: stage.align = StageAlign.TOP_LEFT;", ConsoleMessageTypes.DEBUG);
  724. }
  725. if (stage.scaleMode != StageScaleMode.NO_SCALE)
  726. {
  727. print("Warning: stage.scaleMode is not set to NO_SCALE; This might cause scaling issues", ConsoleMessageTypes.ERROR);
  728. print("Fix: stage.scaleMode = StageScaleMode.NO_SCALE;", ConsoleMessageTypes.DEBUG);
  729. }
  730. stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown, false, int.MAX_VALUE);
  731. stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp, false, int.MAX_VALUE);
  732. stage.addEventListener(Event.RESIZE, onStageResize);
  733. removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
  734. _scopeManager.selectBaseScope();
  735. view.setHeaderText("Doomsday Console " + Version.Major + "." + Version.Minor);
  736. onStageResize(e);
  737. }
  738. private function onStageResize(e:Event = null):void
  739. {
  740. _mainConsoleView.consolidateView();
  741. _dockingGuides.resize();
  742. }
  743. public function stackTrace():void
  744. {
  745. var e:Error = new Error();
  746. var s:String = e.getStackTrace();
  747. var split:Array = s.split("\n");
  748. split.shift();
  749. s = "Stack trace: \n\t" + split.join("\n\t");
  750. print(s, ConsoleMessageTypes.INFO);
  751. }
  752. private function doSearch(searchString:String, includeAccessors:Boolean = false, includeCommands:Boolean = true, includeScopeMethods:Boolean = false):Vector.<String>
  753. {
  754. var outResult:Vector.<String> = new Vector.<String>();
  755. if (searchString.length < 1)
  756. return outResult;
  757. var found:Boolean = false;
  758. var result:Vector.<String>;
  759. var maxrow:int = 4;
  760. if (includeScopeMethods)
  761. {
  762. result = _scopeManager.doSearch(searchString, ScopeManager.SEARCH_METHODS);
  763. outResult = outResult.concat(result);
  764. var out:String = "";
  765. var count:int = 0;
  766. if (result.length > 0)
  767. {
  768. print("Scope methods matching '" + searchString + "'", ConsoleMessageTypes.SYSTEM);
  769. for (var i:int = 0; i < result.length; i++)
  770. {
  771. out += result[i] + " ";
  772. count++;
  773. if (count > maxrow)
  774. {
  775. count = 0;
  776. print(out, ConsoleMessageTypes.INFO);
  777. out = "";
  778. }
  779. }
  780. if (out != "")
  781. print(out, ConsoleMessageTypes.INFO);
  782. found = true;
  783. }
  784. }
  785. if (includeCommands)
  786. {
  787. result = _commandManager.doSearch(searchString);
  788. outResult = outResult.concat(result);
  789. count = 0;
  790. out = "";
  791. if (result.length > 0)
  792. {
  793. print("Commands matching '" + searchString + "'", ConsoleMessageTypes.SYSTEM);
  794. for (i = 0; i < result.length; i++)
  795. {
  796. out += "\t" + result[i] + " ";
  797. count++;
  798. if (count > maxrow)
  799. {
  800. count = 0;
  801. print(out, ConsoleMessageTypes.INFO);
  802. out = "";
  803. }
  804. }
  805. if (out != "")
  806. print(out, ConsoleMessageTypes.INFO);
  807. found = true;
  808. }
  809. }
  810. if (includeAccessors)
  811. {
  812. result = _scopeManager.doSearch(searchString, ScopeManager.SEARCH_ACCESSORS);
  813. outResult = outResult.concat(result);
  814. count = 0;
  815. out = "";
  816. if (result.length > 0)
  817. {
  818. print("Scope accessors matching '" + searchString + "'", ConsoleMessageTypes.SYSTEM);
  819. for (i = 0; i < result.length; i++)
  820. {
  821. out += result[i] + " ";
  822. count++;
  823. if (count > maxrow)
  824. {
  825. count = 0;
  826. print(out, ConsoleMessageTypes.INFO);
  827. out = "";
  828. }
  829. }
  830. if (out != "")
  831. print(out, ConsoleMessageTypes.INFO);
  832. found = true;
  833. }
  834. }
  835. result = _scopeManager.doSearch(searchString, ScopeManager.SEARCH_CHILDREN);
  836. outResult = outResult.concat(result);
  837. count = 0;
  838. out = "";
  839. if (result.length > 0)
  840. {
  841. print("Children matching '" + searchString + "'", ConsoleMessageTypes.SYSTEM);
  842. for (i = 0; i < result.length; i++)
  843. {
  844. out += result[i] + " ";
  845. count++;
  846. if (count > maxrow)
  847. {
  848. count = 0;
  849. print(out, ConsoleMessageTypes.INFO);
  850. out = "";
  851. }
  852. }
  853. if (out != "")
  854. print(out, ConsoleMessageTypes.INFO);
  855. found = true;
  856. }
  857. //if (!found) {
  858. //TODO: Do we really need this junk feedback?
  859. //print("No matches for '" + searchString + "'",ConsoleMessageTypes.ERROR);
  860. //}
  861. return outResult;
  862. }
  863. private function get currentMessageLogVector():Vector.<ConsoleMessage>
  864. {
  865. return _logManager.currentLog.messages;
  866. }
  867. public static function refresh():void
  868. {
  869. console.refresh();
  870. }
  871. public function show():void
  872. {
  873. if (!stage)
  874. return;
  875. if (!visible)
  876. toggleDisplay();
  877. }
  878. public function hide():void
  879. {
  880. if (!stage)
  881. return;
  882. if (visible)
  883. toggleDisplay();
  884. }
  885. override public function get visible():Boolean
  886. {
  887. return _visible;
  888. }
  889. override public function set visible(value:Boolean):void
  890. {
  891. _visible = value;
  892. if (_visible)
  893. {
  894. _consoleContainer.visible = true;
  895. view.show();
  896. }
  897. else
  898. view.hide();
  899. }
  900. public function set isVisible(b:Boolean):void
  901. {
  902. _isVisible = b;
  903. super.visible = _isVisible;
  904. }
  905. public function get isVisible():Boolean
  906. {
  907. return _isVisible;
  908. }
  909. public function toggleDisplay():void
  910. {
  911. // Return if locked
  912. if (lock.locked)
  913. {
  914. return;
  915. }
  916. visible = !visible;
  917. var i:int;
  918. var bounds:Rectangle = _persistence.rect;
  919. if (visible)
  920. {
  921. if (!_initialized)
  922. {
  923. initialize();
  924. }
  925. if (parent)
  926. {
  927. parent.addChild(this);
  928. }
  929. tabOrderOff();
  930. input.focus();
  931. input.text = "";
  932. updateAssistantText();
  933. beginFrameUpdates();
  934. messaging.send(Notifications.CONSOLE_SHOW, null, this);
  935. }
  936. else
  937. {
  938. tabOrderOn();
  939. ceaseFrameUpdates();
  940. messaging.send(Notifications.CONSOLE_HIDE, null, this);
  941. }
  942. }
  943. private function tabOrderOn():void
  944. {
  945. if (parent)
  946. {
  947. parent.tabChildren = parent.tabEnabled = _prevTabSettings;
  948. }
  949. }
  950. private function tabOrderOff():void
  951. {
  952. if (parent)
  953. {
  954. _prevTabSettings = parent.tabChildren;
  955. parent.tabChildren = parent.tabEnabled = false;
  956. }
  957. }
  958. private function initialize():void
  959. {
  960. _initialized = true;
  961. if (!_styleManager.themeLoaded)
  962. {
  963. _styleManager.load();
  964. }
  965. _mainConsoleView.consolidateView();
  966. }
  967. override public function get height():Number
  968. {
  969. return _mainConsoleView.height;
  970. }
  971. override public function set height(value:Number):void
  972. {
  973. _mainConsoleView.height = value;
  974. }
  975. override public function get width():Number
  976. {
  977. return _mainConsoleView.rect.width;
  978. }
  979. override public function set width(value:Number):void
  980. {
  981. _mainConsoleView.width = value;
  982. }
  983. public function setQuickSearch(newvalue:Boolean = true):void
  984. {
  985. _quickSearchEnabled = newvalue;
  986. print("Quick-searching: " + _quickSearchEnabled, ConsoleMessageTypes.SYSTEM);
  987. }
  988. //minmaxing size
  989. public function maximize():void
  990. {
  991. if (!stage)
  992. return;
  993. _mainConsoleView.maximize();
  994. }
  995. public function minimize():void
  996. {
  997. _mainConsoleView.minimize();
  998. }
  999. //keyboard event handlers
  1000. private function onKeyUp(e:KeyboardEvent):void
  1001. {
  1002. KeyboardManager.instance.handleKeyUp(e);
  1003. if (visible)
  1004. {
  1005. var cmd:String = "";
  1006. var _testCmd:Boolean = false;
  1007. if (e.keyCode == Keyboard.UP)
  1008. {
  1009. if (!e.shiftKey)
  1010. {
  1011. cmd = _persistence.historyUp();
  1012. _testCmd = true;
  1013. }
  1014. else
  1015. {
  1016. return;
  1017. }
  1018. }
  1019. else if (e.keyCode == Keyboard.DOWN)
  1020. {
  1021. if (!e.shiftKey)
  1022. {
  1023. cmd = _persistence.historyDown();
  1024. _testCmd = true;
  1025. }
  1026. else
  1027. {
  1028. return;
  1029. }
  1030. }
  1031. if (_testCmd)
  1032. {
  1033. input.text = cmd;
  1034. input.focus();
  1035. var spaceIndex:int = input.text.indexOf(" ");
  1036. if (spaceIndex > -1)
  1037. {
  1038. input.inputTextField.setSelection(input.text.indexOf(" ") + 1, input.text.length);
  1039. }
  1040. else
  1041. {
  1042. input.inputTextField.setSelection(0, input.text.length);
  1043. }
  1044. updateAssistantText();
  1045. }
  1046. }
  1047. }
  1048. private function keyHandler(e:KeyboardEvent):KeyHandlerResult
  1049. {
  1050. var out:KeyHandlerResult = keyhandlerResult;
  1051. out.reset();
  1052. var triggered:Boolean = e.keyCode == _trigger;
  1053. if (stage.focus == input.inputTextField)
  1054. {
  1055. if (!e.shiftKey && triggered)
  1056. {
  1057. out.swallowEvent = true;
  1058. out.autoCompleted = doComplete();
  1059. if (out.autoCompleted)
  1060. {
  1061. if (shouldCancel(e.keyCode))
  1062. {
  1063. cancelKey(e);
  1064. }
  1065. }
  1066. return out;
  1067. }
  1068. }
  1069. else
  1070. {
  1071. if (triggered)
  1072. {
  1073. input.focus();
  1074. out.swallowEvent = true;
  1075. return out;
  1076. }
  1077. }
  1078. if (e.keyCode == Keyboard.ESCAPE)
  1079. {
  1080. if (_overrideCallback != null)
  1081. {
  1082. clearOverrideCallback();
  1083. }
  1084. messaging.send(Notifications.ESCAPE_KEY, null, this);
  1085. out.swallowEvent = true;
  1086. return out;
  1087. }
  1088. if (e.shiftKey)
  1089. {
  1090. switch (e.keyCode)
  1091. {
  1092. case Keyboard.UP:
  1093. output.scroll(1);
  1094. out.swallowEvent = true;
  1095. return out;
  1096. case Keyboard.DOWN:
  1097. output.scroll(-1);
  1098. out.swallowEvent = true;
  1099. return out;
  1100. case Keyboard.LEFT:
  1101. //TODO: previous tab
  1102. break;
  1103. case Keyboard.RIGHT:
  1104. //TODO: next tab
  1105. break;
  1106. }
  1107. }
  1108. if (e.keyCode == Keyboard.ENTER && stage.focus == input.inputTextField)
  1109. {
  1110. out.swallowEvent = true;
  1111. if (input.text.length < 1)
  1112. {
  1113. //input.focus();
  1114. return out;
  1115. }
  1116. var success:Boolean = false;
  1117. var passToDefault:Boolean = false;
  1118. var errorMessage:String = "";
  1119. print(input.text, ConsoleMessageTypes.USER);
  1120. if (_overrideCallback != null)
  1121. {
  1122. _overrideCallback(input.text);
  1123. success = true;
  1124. }
  1125. else
  1126. {
  1127. try
  1128. {
  1129. var attempt:* = executeStatement(input.text);
  1130. success = true;
  1131. }
  1132. catch (error:ConsoleAuthError)
  1133. {
  1134. //TODO: This needs a more graceful solution. Dual auth error prints = lame
  1135. }
  1136. catch (error:ArgumentError)
  1137. {
  1138. switch (error.message)
  1139. {
  1140. case ErrorStrings.STRING_PARSE_ERROR_TERMINATION:
  1141. passToDefault = true;
  1142. break;
  1143. }
  1144. errorMessage = error.message;
  1145. }
  1146. catch (error:CommandError)
  1147. {
  1148. passToDefault = true;
  1149. errorMessage = error.message;
  1150. }
  1151. catch (error:Error)
  1152. {
  1153. print(error.message, ConsoleMessageTypes.ERROR);
  1154. }
  1155. }
  1156. if (passToDefault && _defaultInputCallback != null)
  1157. {
  1158. var ret:* = _defaultInputCallback(input.text);
  1159. if (ret)
  1160. {
  1161. print(ret, ConsoleMessageTypes.INFO);
  1162. }
  1163. }
  1164. else
  1165. {
  1166. print(errorMessage, ConsoleMessageTypes.ERROR);
  1167. }
  1168. output.scrollToBottom();
  1169. input.clear();
  1170. updateAssistantText();
  1171. out.swallowEvent = true;
  1172. }
  1173. else if (e.keyCode == Keyboard.PAGE_DOWN)
  1174. {
  1175. output.scroll(-output.numLines);
  1176. out.swallowEvent = true;
  1177. }
  1178. else if (e.keyCode == Keyboard.PAGE_UP)
  1179. {
  1180. output.scroll(output.numLines);
  1181. out.swallowEvent = true;
  1182. }
  1183. else if (e.keyCode == Keyboard.HOME)
  1184. {
  1185. output.scrollIndex = 0;
  1186. out.swallowEvent = true;
  1187. }
  1188. else if (e.keyCode == Keyboard.END)
  1189. {
  1190. output.scrollIndex = output.maxScroll;
  1191. out.swallowEvent = true;
  1192. }
  1193. else if (e.keyCode == Keyboard.SPACE)
  1194. {
  1195. out.swallowEvent = true;
  1196. }
  1197. return out;
  1198. }
  1199. private function onKeyDown(e:KeyboardEvent):void
  1200. {
  1201. KeyboardManager.instance.handleKeyDown(e);
  1202. if (!visible)
  1203. return; //Ignore if invisible
  1204. if (e.keyCode == Keyboard.TAB)
  1205. stage.focus = input.inputTextField; //why?
  1206. var result:KeyHandlerResult = keyHandler(e);
  1207. if (result.swallowEvent)
  1208. {
  1209. if (is_air) {
  1210. if (!result.autoCompleted) {
  1211. if (e.keyCode == Keyboard.SPACE) {
  1212. view.input.insertAtCaret(" ");
  1213. }
  1214. }else {
  1215. input.moveCaretToEnd();
  1216. }
  1217. }
  1218. e.stopImmediatePropagation();
  1219. e.stopPropagation();
  1220. e.preventDefault();
  1221. }
  1222. }
  1223. private function shouldCancel(keyCode:uint):Boolean
  1224. {
  1225. return keyCode >= 13 || keyCode == Keyboard.SPACE;
  1226. }
  1227. private function cancelKey(e:KeyboardEvent):void
  1228. {
  1229. if (is_air) return;
  1230. _cancelNextKey = true;
  1231. e.stopPropagation();
  1232. }
  1233. /**
  1234. * Sets the handling method for repeated messages with identical values
  1235. * @param filter
  1236. * One of the 3 modes described in the no.doomsday.console.core.output.MessageRepeatMode enum
  1237. */
  1238. public function setRepeatFilter(filter:int):void
  1239. {
  1240. switch (filter)
  1241. {
  1242. case ConsoleMessageRepeatMode.IGNORE:
  1243. print("Repeat mode: Repeated messages are now ignored", ConsoleMessageTypes.SYSTEM);
  1244. break;
  1245. case ConsoleMessageRepeatMode.ALLOW:
  1246. print("Repeat mode: Repeated messages are now allowed", ConsoleMessageTypes.SYSTEM);
  1247. break;
  1248. case ConsoleMessageRepeatMode.STACK:
  1249. print("Repeat mode: Repeated messages are now stacked", ConsoleMessageTypes.SYSTEM);
  1250. break;
  1251. default:
  1252. throw new Error("Unknown filter type");
  1253. }
  1254. _repeatMessageMode = filter;
  1255. }
  1256. private function doComplete():Boolean
  1257. {
  1258. var flag:Boolean = false;
  1259. if (input.text.length < 1 || _overrideCallback != null)
  1260. return false;
  1261. var word:String = input.wordAtCaret;
  1262. var isFirstWord:Boolean = input.text.lastIndexOf(word) < 1;
  1263. var firstWord:String;
  1264. if (isFirstWord)
  1265. {
  1266. firstWord = word;
  1267. }
  1268. else
  1269. {
  1270. firstWord = input.firstWord;
  1271. }
  1272. var wordKnown:Boolean;
  1273. wordKnown = _autoCompleteManager.isKnown(word, !isFirstWord, isFirstWord);
  1274. if (wordKnown || !isNaN(Number(word)))
  1275. {
  1276. //this word is okay, so accept the completion
  1277. var wordIndex:int = input.firstIndexOfWordAtCaret;
  1278. //is there currently a selection?
  1279. if (input.inputTextField.selectedText.length > 0)
  1280. {
  1281. input.moveCaretToIndex(input.selectionBeginIndex);
  1282. wordIndex = input.selectionBeginIndex;
  1283. }
  1284. else if (input.text.charAt(input.caretIndex) == " " && input.caretIndex != input.text.length - 1)
  1285. {
  1286. //input.moveCaretToIndex(input.caretIndex - 1);
  1287. }
  1288. word = input.wordAtCaret;
  1289. wordIndex = input.caretIndex;
  1290. //case correction
  1291. var temp:String = input.text;
  1292. try
  1293. {
  1294. temp = temp.replace(word, _autoCompleteManager.correctCase(word));
  1295. input.text = temp;
  1296. }
  1297. catch (e:Error)
  1298. {
  1299. }
  1300. //is there a word after the current word?
  1301. if (wordIndex + word.length < input.text.length - 1)
  1302. {
  1303. input.moveCaretToIndex(wordIndex + word.length);
  1304. input.selectWordAtCaret();
  1305. }
  1306. else
  1307. {
  1308. //if it's the last word
  1309. if (input.text.charAt(input.text.length - 1) != " ")
  1310. {
  1311. input.inputTextField.appendText(" ");
  1312. }
  1313. input.moveCaretToEnd();
  1314. }
  1315. return true;
  1316. }
  1317. else
  1318. {
  1319. if (_quickSearchEnabled)
  1320. {
  1321. var getSet:Boolean = (firstWord == _getCommand.trigger || firstWord == _setCommand.trigger);
  1322. var call:Boolean = (firstWord == _callCommand.trigger);
  1323. var select:Boolean = (firstWord == _selectCommand.trigger);
  1324. var searchResult:Vector.<String> = doSearch(word, !isFirstWord || select, isFirstWord, call);
  1325. if (searchResult.length == 1)
  1326. {
  1327. if (searchResult[0].indexOf(word) == 0)
  1328. {
  1329. input.selectWordAtCaret();
  1330. input.inputTextField.replaceSelectedText(searchResult[0] + " ");
  1331. input.moveCaretToIndex(wordIndex + searchResult[0].length + 1);
  1332. return true;
  1333. }
  1334. }
  1335. else if (searchResult.length > 1)
  1336. {
  1337. input.moveCaretToEnd();
  1338. return true;
  1339. }
  1340. }
  1341. if (flag)
  1342. {
  1343. input.selectWordAtCaret();
  1344. }
  1345. else
  1346. {
  1347. //input.moveCaretToIndex(input.firstIndexOfWordAtCaret + input.wordAtCaret.length);
  1348. }
  1349. return false;
  1350. }
  1351. }
  1352. public function get view():ConsoleView
  1353. {
  1354. return _mainConsoleView;
  1355. }
  1356. public function get logs():DLogManager
  1357. {
  1358. return _logManager;
  1359. }
  1360. public function get defaultInputCallback():Function
  1361. {
  1362. return _defaultInputCallback;
  1363. }
  1364. public function set defaultInputCallback(value:Function):void
  1365. {
  1366. if (value == null)
  1367. {
  1368. _defaultInputCallback = null;
  1369. return;
  1370. }
  1371. if (value.length != 1)
  1372. throw new Error("Default input callback must take exactly one argument");
  1373. _defaultInputCallback = value;
  1374. }
  1375. public function lockOutput():void
  1376. {
  1377. output.lockOutput();
  1378. }
  1379. public function unlockOutput():void
  1380. {
  1381. output.unlockOutput();
  1382. }
  1383. public function loadStyle(themeURI:String = null, colorsURI:String = null):void
  1384. {
  1385. _styleManager.load(themeURI, colorsURI);
  1386. }
  1387. public function get scopeManager():ScopeManager
  1388. {
  1389. return _scopeManager;
  1390. }
  1391. public function get persistence():PersistenceManager
  1392. {
  1393. return _persistence;
  1394. }
  1395. public function get pluginManager():PluginManager
  1396. {
  1397. return _plugManager;
  1398. }
  1399. public function setHeaderText(title:String):void
  1400. {
  1401. _mainConsoleView.toolbar.setTitle(title);
  1402. }
  1403. public function setOverrideCallback(callback:Function):void
  1404. {
  1405. addSystemMessage("Override callback active, hit ESC to resume normal ops");
  1406. _overrideCallback = callback;
  1407. }
  1408. public function clearOverrideCallback():void
  1409. {
  1410. addSystemMessage("Override callback cleared");
  1411. _overrideCallback = null;
  1412. }
  1413. //}
  1414. //{ Statics
  1415. /**
  1416. * If true, the console instance cannot be selected by the console. The default is true, which is recommended.
  1417. */
  1418. public static var CONSOLE_SAFE_MODE:Boolean = true;
  1419. /**
  1420. * If true, the stage can't be selected by the console. The default is true, because Stage properties behave strangely when rapidly messed with.
  1421. * Need to examine this further.
  1422. */
  1423. public static var STAGE_SAFE_MODE:Boolean = true;
  1424. public static function stackTrace():void
  1425. {
  1426. console.stackTrace();
  1427. }
  1428. /**
  1429. * Removes the default input callback
  1430. * @see setDefaultInputCallback
  1431. */
  1432. public static function clearDefaultInputCallback():void
  1433. {
  1434. console.defaultInputCallback = null;
  1435. }
  1436. /**
  1437. * Declares a default input callback
  1438. * This callback will receive any input the console doesn't understand
  1439. * @param callback
  1440. */
  1441. public static function setDefaultInputCallback(callback:Function):void
  1442. {
  1443. if (callback.length != 1)
  1444. throw new Error("The default input callback must accept exactly 1 string argument");
  1445. console.defaultInputCallback = callback;
  1446. }
  1447. private static var _instance:DConsole;
  1448. private static var keyboardShortcut:Array = [];
  1449. private var _prevTabSettings:Boolean = false;
  1450. private var is_air:Boolean;
  1451. private var keyhandlerResult:KeyHandlerResult = new KeyHandlerResult(); //reuse same instance YESSss
  1452. /**
  1453. * The internal tag used as the defalt for logging
  1454. */
  1455. public static const TAG:String = "DConsole";
  1456. public static function get ignoreBlankLines():Boolean
  1457. {
  1458. return DConsole(console).ignoreBlankLines;
  1459. }
  1460. public static function set ignoreBlankLines(b:Boolean):void
  1461. {
  1462. DConsole(console).ignoreBlankLines = b;
  1463. }
  1464. /**
  1465. * Returns the object currently selected as the console scope
  1466. * @return An object
  1467. * @see select
  1468. */
  1469. public static function getCurrentTarget():Object
  1470. {
  1471. return (console as DConsole).scopeManager.currentScope.targetObject;
  1472. }
  1473. /**
  1474. * Get the singleton IConsole instance
  1475. */
  1476. public static function get console():IConsole
  1477. {
  1478. if (!_instance)
  1479. {
  1480. _instance = new DConsole();
  1481. if (keyboardShortcut.length > 0)
  1482. {
  1483. console.changeKeyboardShortcut(keyboardShortcut[0], keyboardShortcut[1]);
  1484. }
  1485. }
  1486. return _instance;
  1487. }
  1488. /**
  1489. * Sets the console title bar text
  1490. * @param title
  1491. */
  1492. public static function setTitle(title:String):void
  1493. {
  1494. console.setHeaderText(title);
  1495. }
  1496. /**
  1497. * Get the singleton console view display object
  1498. */
  1499. public static function get view():DisplayObject
  1500. {
  1501. return console as DisplayObject;
  1502. }
  1503. /**
  1504. * Adds a message
  1505. * @param msg
  1506. * The text to output
  1507. * @param type
  1508. * The message type, one of the options available in ConsoleMessageTypes
  1509. * @param tag
  1510. * The string tag for identifying the source or topic of this message
  1511. */
  1512. public static function print(msg:String, type:String = ConsoleMessageTypes.INFO, tag:String = TAG):void
  1513. {
  1514. console.print(msg, type, tag);
  1515. }
  1516. /**
  1517. * Add a message with system color coding
  1518. * @param msg
  1519. * @param tag
  1520. * The string tag for identifying the source or topic of this message
  1521. */
  1522. public static function addSystemMessage(msg:String, tag:String = TAG):void
  1523. {
  1524. console.print(msg, ConsoleMessageTypes.SYSTEM, tag);
  1525. }
  1526. /**
  1527. * Add a message with warning color coding
  1528. * @param msg
  1529. * @param tag
  1530. * The string tag for identifying the source or topic of this message
  1531. */
  1532. public static function addWarningMessage(msg:String, tag:String = TAG):void
  1533. {
  1534. console.print(msg, ConsoleMessageTypes.WARNING, tag);
  1535. }
  1536. /**
  1537. * Add a message with error color coding
  1538. * @param msg
  1539. * @param tag
  1540. * The string tag for identifying the source or topic of this message
  1541. */
  1542. public static function addErrorMessage(msg:String, tag:String = TAG):void
  1543. {
  1544. console.print(msg, ConsoleMessageTypes.ERROR, tag);
  1545. }
  1546. /**
  1547. * Add a message with ridiculous random color coding.
  1548. * For the love of god and all that is holy, use sparingly if at all!
  1549. * @param msg
  1550. * @param tag
  1551. * The string tag for identifying the source or topic of this message
  1552. */
  1553. public static function addHoorayMessage(msg:String, tag:String = TAG):void
  1554. {
  1555. console.print(msg, ConsoleMessageTypes.HOORAY, tag);
  1556. }
  1557. /**
  1558. * Add a message with fatal error color coding (incredibly vile)
  1559. * @param msg
  1560. * @param tag
  1561. * The string tag for identifying the source or topic of this message
  1562. */
  1563. public static function addFatalMessage(msg:String, tag:String = TAG):void
  1564. {
  1565. console.print(msg, ConsoleMessageTypes.FATAL, tag)
  1566. }
  1567. /**
  1568. * Create a command for calling a specific function
  1569. * @param triggerPhrase
  1570. * The trigger word for the command
  1571. * @param func
  1572. * The function to call
  1573. * @param category
  1574. * Optional: The group name you want the command sorted under
  1575. * @param helpText
  1576. * Optional: Any text you want displayed in the assistant when this command is being typed
  1577. */
  1578. public static function createCommand(triggerPhrase:String, func:Function, category:String = "Application", helpText:String = ""):void
  1579. {
  1580. console.createCommand(triggerPhrase, func, category, helpText);
  1581. }
  1582. /**
  1583. * Removes a command keyed by its trigger phrase
  1584. * @param triggerPhrase
  1585. */
  1586. public static function removeCommand(triggerPhrase:String):void
  1587. {
  1588. console.removeCommand(triggerPhrase);
  1589. }
  1590. /**
  1591. * Use this to print event messages on dispatch
  1592. * (addEventListener(Event.CHANGE, ConsoleUtil.onEvent))
  1593. */
  1594. public static function get onEvent():Function
  1595. {
  1596. return console.onEvent;
  1597. }
  1598. /**
  1599. * Clear the console log(s)
  1600. */
  1601. public static function get clear():Function
  1602. {
  1603. return console.clear;
  1604. }
  1605. public function get debugDraw():DebugDraw
  1606. {
  1607. return _debugDraw;
  1608. }
  1609. /**
  1610. * Registers plugins and plugin bundles by their class types
  1611. * A plugin is an implementor of any interface deriving from IDConsolePlugin
  1612. * A plugin bundle is an implementor of IPluginBundle
  1613. * @param ...args
  1614. * @example
  1615. * The following code shows the BasicPlugins bundle being registered, alongside the JSRouterUtil plugin
  1616. * <listing>
  1617. * DConsole.registerPlugins(AllPlugins,JSRouterUtil);
  1618. * </listing>
  1619. */
  1620. public static function registerPlugins(... args:Array):void
  1621. {
  1622. for (var i:int = 0; i < args.length; i++)
  1623. {
  1624. (console as DConsole).pluginManager.registerPlugin(args[i]);
  1625. }
  1626. }
  1627. /**
  1628. * Sets the specified object as the console's current scope
  1629. * @param object
  1630. * @see getCurrentTarget
  1631. */
  1632. public static function select(object:Object):void
  1633. {
  1634. console.select(object);
  1635. }
  1636. /**
  1637. * Show the console
  1638. * @see hide
  1639. */
  1640. public static function show():void
  1641. {
  1642. console.show();
  1643. }
  1644. /**
  1645. * Hide the console
  1646. * @see show
  1647. */
  1648. public static function hide():void
  1649. {
  1650. console.hide();
  1651. }
  1652. /**
  1653. * Execute a console command statement
  1654. * @param statement
  1655. * The statement, eg. "setFrameRate 60" etc
  1656. * @param echo
  1657. * Wether to echo this statement in the console (default false)
  1658. * @return
  1659. * The return value of the executed statement, if any.
  1660. */
  1661. public static function executeStatement(statement:String, echo:Boolean = false):*
  1662. {
  1663. return console.executeStatement(statement, echo);
  1664. }
  1665. /**
  1666. * Set keyboard shortcut
  1667. *
  1668. * @param keystroke The keystroke
  1669. * @param modifier The modifier
  1670. */
  1671. public static function setKeyboardShortcut(key:uint, modifier:uint):Boolean
  1672. {
  1673. var success:Boolean = false;
  1674. /*
  1675. * If is a valid keyboard shortcut
  1676. *
  1677. * 1. If the console is not initialized store for later, and modify after creation.
  1678. * 2. If the console is initialized call instance.changeKeyboardShortcut
  1679. */
  1680. if (KeyboardManager.instance.validateKeyboardShortcut(key, modifier))
  1681. {
  1682. if (!_instance)
  1683. {
  1684. keyboardShortcut = [key, modifier];
  1685. }
  1686. else
  1687. {
  1688. console.changeKeyboardShortcut(key, modifier);
  1689. }
  1690. success = true;
  1691. }
  1692. return success;
  1693. }
  1694. /**
  1695. * Change keyboard shortcut.
  1696. *
  1697. * @param keystroke The key
  1698. * @param modifier The modifier
  1699. */
  1700. private static function changeKeyboardShortcut(key:uint, modifier:uint):void
  1701. {
  1702. console.changeKeyboardShortcut(key, modifier);
  1703. }
  1704. /**
  1705. * Declares an overriding callback for all console input
  1706. * While active, regular console input behavior will cease, and all text input will be passed to the specified callback
  1707. * @param callback
  1708. */
  1709. static public function setOverrideCallback(callback:Function):void
  1710. {
  1711. console.setOverrideCallback(callback);
  1712. }
  1713. /**
  1714. * Removes the overriding callback set in setOverrideCallback
  1715. * @see setOverrideCallback
  1716. */
  1717. static public function clearOverrideCallback():void
  1718. {
  1719. console.clearOverrideCallback();
  1720. }
  1721. /**
  1722. * Resets all persistent data (command history, console position, docking etc)
  1723. */
  1724. static public function clearPersistentData():void
  1725. {
  1726. DConsole(console).persistence.clearAll();
  1727. }
  1728. /**
  1729. * Set the console's docking state
  1730. * @param mode one of the DOCK_* static constants on DConsole
  1731. */
  1732. public static function dock(mode:int):void
  1733. {
  1734. console.view.dockingMode = mode;
  1735. }
  1736. public function setTheme(colors:XML, theme:XML):void
  1737. {
  1738. _styleManager.setThemeXML(colors, theme);
  1739. }
  1740. public function getTheme():Array
  1741. {
  1742. return [_styleManager.colorXML, _styleManager.themeXML];
  1743. }
  1744. /**
  1745. * Lock
  1746. *
  1747. * @param secret The secret to lock the console with.
  1748. */
  1749. public static function setMagicWord(secret:String):void
  1750. {
  1751. DConsole(console)._lock.lockWithKeycodes(KeyBindings.toCharCodes(secret), DConsole(console).toggleDisplay);
  1752. }
  1753. /**
  1754. * Lock with keyCodes
  1755. *
  1756. * @param keyCodes The keyCodes to lock the console with.
  1757. */
  1758. public static function setMagicSequence(keyCodes:Array):void
  1759. {
  1760. DConsole(console)._lock.lockWithKeycodes(keyCodes, DConsole(console).toggleDisplay);
  1761. }
  1762. public static function setMasterKey(key:uint):void
  1763. {
  1764. DConsole(console).setMasterKey(key);
  1765. }
  1766. /* INTERFACE com.furusystems.dconsole2.IConsole */
  1767. public function refresh():void
  1768. {
  1769. scopeManager.updateScope();
  1770. }
  1771. public function get messaging():PimpCentral
  1772. {
  1773. return _messaging;
  1774. }
  1775. }
  1776. }