<?xml version="1.0" encoding="UTF-8"?>
<leo_file>
<leo_header file_format="2" tnodes="0" max_tnode_index="1514" clone_windows="0"/>
<globals body_outline_ratio="0.42888165038002174">
	<global_window_position top="42" left="186" height="921" width="957"/>
	<global_log_window_position top="0" left="0" height="0" width="0"/>
</globals>
<preferences>
</preferences>
<find_panel_settings>
	<find_string></find_string>
	<change_string></change_string>
</find_panel_settings>
<vnodes>
<v t="edream.110203113231"><vh>Diary</vh>
<v t="ekr.20040119102021"><vh>2004</vh>
<v t="ekr.20040201061422"><vh>February 2004</vh>
<v t="ekr.20040201061422.1" a="E"><vh>2/1/2004</vh>
<v t="ekr.20040201061422.2"><vh>Created status_line.py plugin</vh></v>
</v>
</v>
<v t="ekr.20040130165735"><vh>1/30 Fixed crashers in open_shell.py</vh></v>
<v t="ekr.20040129151121"><vh>1/29 Activate xemacs plugin only on double-clicks</vh></v>
<v t="ekr.20040119102021.1"><vh>1/19 Added http plugin</vh></v>
</v>
<v t="ekr.20040119102021.2"><vh>2003</vh>
<v t="edream.031217094146"><vh>12/17</vh>
<v t="edream.031216103123"><vh>Fix problems in plugins</vh></v>
</v>
<v t="edream.120603100522"><vh>12/6/03 Removed compile-time enable/disable code</vh></v>
<v t="edream.112103192146"><vh>11/21</vh>
<v t="edream.112303075625"><vh>Added wxVersion to signon</vh></v>
<v t="edream.112103192146.1"><vh>Fixed and test vim plugin</vh></v>
</v>
<v t="edream.111903190444"><vh>11/19</vh>
<v t="edream.111903190444.1"><vh>Fixed reorg bugs in plugin_menu and spelli checking plugins</vh></v>
<v t="edream.111903105454"><vh>Moved all "protected" @others inside "if tkinter" statement</vh></v>
</v>
<v t="edream.111803100856"><vh>11/18 Added new version of rst plugin from Timo Honkasalo</vh></v>
<v t="edream.111603130528"><vh>11/17</vh></v>
<v t="edream.110703035301"><vh>11/7</vh></v>
<v t="edream.110203113231.1"><vh>10/27/02</vh></v>
<v t="edream.110203113231.2"><vh>10/26/03</vh></v>
</v>
</v>
<v t="edream.110203113231.3"><vh>Documentation and security warnings</vh>
<v t="edream.110203113231.4"><vh>Overview of plugins and hooks</vh></v>
<v t="edream.110203113231.5"><vh>Intro to scripts</vh></v>
<v t="edream.110203113231.6"><vh>About hooks</vh></v>
<v t="edream.110203113231.7"><vh>Hooks should never blindly Python scripts</vh></v>
<v t="edream.110203113231.8"><vh>NEVER use this kind of code in a hook!!</vh></v>
</v>
<v t="ekr.20040126115840"><vh>Other</vh>
<v t="edream.110203113231.9"><vh>Unfinished projects</vh>
<v t="edream.110203113231.10"><vh>(Settings menu)</vh>
<v t="edream.110203113231.11"><vh>To do</vh></v>
<v t="edream.110203113231.12"><vh>Design of Settings menu</vh></v>
<v t="edream.110203113231.13" tnodeList="edream.110203113231.13,edream.110203113231.14"><vh>@file settings_menu.py</vh>
<v t="edream.110203113231.14"><vh>createSettingsMenu</vh></v>
</v>
</v>
<v t="edream.110203113231.15"><vh>Study code for EKR</vh>
<v t="edream.110203113231.16"><vh>pymacs</vh>
<v t="edream.110203113231.17"><vh>@file pymacs.el</vh>
<v t="edream.110203113231.18"><vh>Intro</vh>
<v t="edream.110203113231.19"><vh>&lt;&lt; free software stuff &gt;&gt;</vh></v>
</v>
<v t="edream.110203113231.20"><vh>Published functions...</vh>
<v t="edream.110203113231.21"><vh>vars...</vh>
<v t="edream.110203113231.22"><vh>var pymacs-load-path</vh></v>
<v t="edream.110203113231.23"><vh>var pymacs-trace-transit</vh></v>
<v t="edream.110203113231.24"><vh>var pymacs-forget-mutability</vh></v>
<v t="edream.110203113231.25"><vh>var pymacs-mutable-strings</vh></v>
<v t="edream.110203113231.26"><vh>var pymacs-timeout-at-start</vh></v>
<v t="edream.110203113231.27"><vh>var pymacs-timeout-at-reply</vh></v>
<v t="edream.110203113231.28"><vh>var pymacs-timeout-at-line</vh></v>
</v>
<v t="edream.110203113231.29"><vh>pymacs-load</vh></v>
<v t="edream.110203113231.30"><vh>pymacs-eval</vh></v>
<v t="edream.110203113231.31"><vh>pymacs-exec</vh></v>
<v t="edream.110203113231.32"><vh>pymacs-call</vh></v>
<v t="edream.110203113231.33"><vh>pymacs-apply</vh></v>
</v>
<v t="edream.110203113231.34"><vh>Integration details...</vh>
<v t="edream.110203113231.35"><vh>defadvice</vh></v>
<v t="edream.110203113231.36"><vh>pymacs-python-reference</vh></v>
</v>
<v t="edream.110203113231.37"><vh>experimental...</vh>
<v t="edream.110203113231.38"><vh>pymacs-file-handler</vh></v>
<v t="edream.110203113231.39"><vh>pymacs-file-force</vh></v>
</v>
<v t="edream.110203113231.40"><vh>Gargabe collection of Python IDs...</vh>
<v t="edream.110203113231.41"><vh>vars...</vh>
<v t="edream.110203113231.42"><vh>var pymacs-use-hash-tables</vh></v>
<v t="edream.110203113231.43"><vh>var pymacs-used-ids</vh></v>
<v t="edream.110203113231.44"><vh>var pymacs-weak-hash</vh></v>
<v t="edream.110203113231.45"><vh>var pymacs-gc-wanted</vh></v>
<v t="edream.110203113231.46"><vh>var pymacs-gc-running</vh></v>
<v t="edream.110203113231.47"><vh>var pymacs-gc-timer</vh></v>
</v>
<v t="edream.110203113231.48"><vh>pymacs-schedule-gc</vh></v>
<v t="edream.110203113231.49"><vh>pymacs-garbage-collect</vh></v>
<v t="edream.110203113231.50"><vh>pymacs-defuns</vh></v>
<v t="edream.110203113231.51"><vh>pymacs-defun</vh></v>
<v t="edream.110203113231.52"><vh>pymacs-python</vh></v>
</v>
<v t="edream.110203113231.53"><vh>Generating Python code...</vh>
<v t="edream.110203113231.54"><vh>var pymacs-lisp</vh></v>
<v t="edream.110203113231.55"><vh>var pymacs-freed-list</vh></v>
<v t="edream.110203113231.56"><vh>pymacs-allocate-lisp</vh></v>
<v t="edream.110203113231.57"><vh>pymacs-free-lisp</vh></v>
<v t="edream.110203113231.58"><vh>pymacs-print-for-apply-expanded</vh></v>
<v t="edream.110203113231.59"><vh>pymacs-print-for-apply</vh></v>
<v t="edream.110203113231.60"><vh>pymacs-print-for-eval</vh></v>
</v>
<v t="edream.110203113231.61"><vh>Communication protocol...</vh>
<v t="edream.110203113231.62"><vh>pymacs-start-services</vh></v>
<v t="edream.110203113231.63"><vh>pymacs-terminate-services</vh></v>
<v t="edream.110203113231.64"><vh>pymacs-reply</vh></v>
<v t="edream.110203113231.65"><vh>pymacs-error</vh></v>
<v t="edream.110203113231.66"><vh>pymacs-expand</vh></v>
<v t="edream.110203113231.67"><vh>pymacs-serve-until-reply</vh></v>
<v t="edream.110203113231.68"><vh>pymacs-round-trip</vh></v>
<v t="edream.110203113231.69"><vh>pymacs-proper-list-p</vh></v>
</v>
</v>
</v>
<v t="edream.110203113231.70"><vh>wxPython stuff</vh>
<v t="edream.110203113231.71"><vh>wxPython demo...</vh>
<v t="edream.110203113231.72"><vh>@file Main.py</vh>
<v t="edream.110203113231.73"><vh>&lt;&lt; version &gt;&gt;</vh></v>
<v t="edream.110203113231.74"><vh>&lt;&lt; define the tree of demo elements &gt;&gt;</vh></v>
<v t="edream.110203113231.75"><vh>class MyLog</vh>
<v t="edream.110203113231.76"><vh>__init__</vh></v>
<v t="edream.110203113231.77"><vh>DoLogString</vh></v>
</v>
<v t="edream.110203113231.78"><vh>class MyTP (Tooltips)</vh>
<v t="edream.110203113231.79"><vh>GetTip</vh></v>
</v>
<v t="edream.110203113231.80"><vh>opj</vh></v>
<v t="edream.110203113231.81"><vh>class wxPythonDemo  (tree, notebook, log, text...)</vh>
<v t="edream.110203113231.82"><vh>__init__</vh>
<v t="edream.110203113231.83"><vh>&lt;&lt; create menus &gt;&gt;</vh></v>
<v t="edream.110203113231.84"><vh>&lt;&lt; Create a TreeCtrl &gt;&gt;</vh></v>
<v t="edream.110203113231.85"><vh>&lt;&lt; Create a Notebook &gt;&gt; (HtmlWindow for over page)</vh></v>
<v t="edream.110203113231.86"><vh>&lt;&lt; Set up a TextCtrl on the Demo Code Notebook page &gt;&gt;</vh></v>
<v t="edream.110203113231.87"><vh>&lt;&lt; Set up a log on the View Log Notebook page &gt;&gt;</vh></v>
<v t="edream.110203113231.88"><vh>&lt;&lt; add the windows to the splitter and split it &gt;&gt;</vh></v>
<v t="edream.110203113231.89"><vh>&lt;&lt; create accelerators &gt;&gt;</vh></v>
<v t="edream.110203113231.90"><vh>&lt;&lt; setup a taskbar icon, and catch some events from it &gt;&gt;</vh></v>
<v t="edream.110203113231.91"><vh>&lt;&lt; handle sys.argv args &gt;&gt;</vh></v>
</v>
<v t="edream.110203113231.92"><vh>WriteText</vh></v>
<v t="edream.110203113231.93"><vh>write</vh></v>
<v t="edream.110203113231.94"><vh>Tree event handlers</vh>
<v t="edream.110203113231.95"><vh>OnItemExpanded</vh></v>
<v t="edream.110203113231.96"><vh>OnItemCollapsed</vh></v>
<v t="edream.110203113231.97"><vh>OnTreeLeftDown</vh></v>
<v t="edream.110203113231.98"><vh>OnSelChanged</vh></v>
</v>
<v t="edream.110203113231.99"><vh>RunDemo</vh></v>
<v t="edream.110203113231.100"><vh>GetDemoFile</vh></v>
<v t="edream.110203113231.101"><vh>SetOverview</vh></v>
<v t="edream.110203113231.102"><vh>OnFileExit</vh></v>
<v t="edream.110203113231.103"><vh>OnHelpAbout</vh></v>
<v t="edream.110203113231.104"><vh>OnHelpFind</vh></v>
<v t="edream.110203113231.105"><vh>OnFind</vh></v>
<v t="edream.110203113231.106"><vh>OnFindNext</vh></v>
<v t="edream.110203113231.107"><vh>OnFindClose</vh></v>
<v t="edream.110203113231.108"><vh>OnCloseWindow</vh></v>
<v t="edream.110203113231.109"><vh>OnIdle</vh></v>
<v t="edream.110203113231.110"><vh>ShowTip</vh></v>
<v t="edream.110203113231.111"><vh>OnDemoMenu</vh></v>
<v t="edream.110203113231.112"><vh>OnTaskBarActivate</vh></v>
<v t="edream.110203113231.113"><vh>OnTaskBarMenu</vh></v>
<v t="edream.110203113231.114"><vh>OnTaskBarClose</vh></v>
<v t="edream.110203113231.115"><vh>OnIconfiy</vh></v>
<v t="edream.110203113231.116"><vh>OnMaximize</vh></v>
</v>
<v t="edream.110203113231.117"><vh>class MySplashScreen</vh>
<v t="edream.110203113231.118"><vh>__init__</vh></v>
<v t="edream.110203113231.119"><vh>OnClose</vh></v>
</v>
<v t="edream.110203113231.120"><vh>class MyApp</vh>
<v t="edream.110203113231.121"><vh>OnInit (Create splash screen)</vh></v>
</v>
<v t="edream.110203113231.122"><vh>main</vh></v>
<v t="edream.110203113231.123"><vh>&lt;&lt; overview of demo &gt;&gt;</vh></v>
</v>
</v>
<v t="edream.110203113231.124"><vh>Tree...</vh>
<v t="edream.110203113231.125"><vh>@file wxTreeListCtrl.py</vh>
<v t="edream.110203113231.126"><vh>class TestPanel</vh>
<v t="edream.110203113231.127"><vh>__init__</vh></v>
<v t="edream.110203113231.128"><vh>OnSize</vh></v>
</v>
<v t="edream.110203113231.129"><vh>runTest</vh></v>
</v>
<v t="edream.110203113231.130"><vh>@file wxTreeCtrl.py</vh>
<v t="edream.110203113231.131"><vh>class MyTreeCtrl</vh>
<v t="edream.110203113231.132"><vh>__init__</vh></v>
<v t="edream.110203113231.133"><vh>OnCompareItems</vh></v>
</v>
<v t="edream.110203113231.134"><vh>class TestTreeCtrlPanel</vh>
<v t="edream.110203113231.135"><vh>__init__</vh></v>
<v t="edream.110203113231.136"><vh>OnRightClick</vh></v>
<v t="edream.110203113231.137"><vh>OnRightUp</vh></v>
<v t="edream.110203113231.138"><vh>OnBeginEdit</vh></v>
<v t="edream.110203113231.139"><vh>OnEndEdit</vh></v>
<v t="edream.110203113231.140"><vh>OnLeftDClick</vh></v>
<v t="edream.110203113231.141"><vh>OnSize</vh></v>
<v t="edream.110203113231.142"><vh>OnItemExpanded</vh></v>
<v t="edream.110203113231.143"><vh>OnItemCollapsed</vh></v>
<v t="edream.110203113231.144"><vh>OnSelChanged</vh></v>
<v t="edream.110203113231.145"><vh>OnActivate</vh></v>
</v>
<v t="edream.110203113231.146"><vh>runTest</vh></v>
</v>
</v>
<v t="edream.110203113231.147"><vh>Text...</vh>
<v t="edream.110203113231.148"><vh>@file wxStyledTextCtrl_1.py</vh>
<v t="edream.110203113231.149"><vh>&lt;&lt; wxStyledTextCtrl_1 declarations &gt;&gt;</vh></v>
<v t="edream.110203113231.150"><vh>class MySTC</vh>
<v t="edream.110203113231.151"><vh>__init__</vh></v>
<v t="edream.110203113231.152"><vh>OnDestroy</vh></v>
<v t="edream.110203113231.153"><vh>OnStartDrag</vh></v>
<v t="edream.110203113231.154"><vh>OnDragOver</vh></v>
<v t="edream.110203113231.155"><vh>OnDoDrop</vh></v>
<v t="edream.110203113231.156"><vh>OnModified</vh></v>
<v t="edream.110203113231.157"><vh>transModType</vh></v>
</v>
<v t="edream.110203113231.158"><vh>runTest</vh></v>
</v>
<v t="edream.110203113231.159"><vh>@file wxStyledTextCtrl_2.py</vh>
<v t="edream.110203113231.160"><vh>&lt;&lt; wxStyledTextCtrl_2 declarations &gt;&gt;</vh></v>
<v t="edream.110203113231.161"><vh>class PythonSTC</vh>
<v t="edream.110203113231.162"><vh>__init__</vh></v>
<v t="edream.110203113231.163"><vh>OnKeyPressed</vh></v>
<v t="edream.110203113231.164"><vh>OnUpdateUI</vh></v>
<v t="edream.110203113231.165"><vh>OnMarginClick</vh></v>
<v t="edream.110203113231.166"><vh>FoldAll</vh></v>
<v t="edream.110203113231.167"><vh>Expand</vh></v>
</v>
<v t="edream.110203113231.168"><vh>runTest</vh></v>
</v>
<v t="edream.110203113231.169"><vh>@file wxTextCtrl.py</vh>
<v t="edream.110203113231.170"><vh>&lt;&lt; wxTextCtrl declarations &gt;&gt;</vh></v>
<v t="edream.110203113231.171"><vh>class TestPanel</vh>
<v t="edream.110203113231.172"><vh>OnSetFocus</vh></v>
<v t="edream.110203113231.173"><vh>OnKillFocus</vh></v>
<v t="edream.110203113231.174"><vh>OnWindowDestroy</vh></v>
<v t="edream.110203113231.175"><vh>__init__</vh></v>
<v t="edream.110203113231.176"><vh>EvtText</vh></v>
<v t="edream.110203113231.177"><vh>EvtChar</vh></v>
<v t="edream.110203113231.178"><vh>OnTestReplace</vh></v>
<v t="edream.110203113231.179"><vh>OnTestWriteText</vh></v>
<v t="edream.110203113231.180"><vh>OnTestGetSelection</vh></v>
<v t="edream.110203113231.181"><vh>OnT5LeftDown</vh></v>
<v t="edream.110203113231.182"><vh>LogT5Position</vh></v>
<v t="edream.110203113231.183"><vh>OnTestEvent</vh></v>
</v>
<v t="edream.110203113231.184"><vh>runTest</vh></v>
</v>
</v>
<v t="edream.110203113231.185"><vh>HTML</vh>
<v t="edream.110203113231.186"><vh>@file wxHtmlWindow.py</vh>
<v t="edream.110203113231.187"><vh>class MyHtmlWindow</vh>
<v t="edream.110203113231.188"><vh>__init__</vh></v>
<v t="edream.110203113231.189"><vh>OnScroll</vh></v>
<v t="edream.110203113231.190"><vh>OnLinkClicked</vh></v>
<v t="edream.110203113231.191"><vh>OnSetTitle</vh></v>
<v t="edream.110203113231.192"><vh>OnCellMouseHover</vh></v>
<v t="edream.110203113231.193"><vh>OnCellClicked</vh></v>
</v>
<v t="edream.110203113231.194"><vh>class MyHtmlFilter</vh>
<v t="edream.110203113231.195"><vh>__init__</vh></v>
<v t="edream.110203113231.196"><vh>CanRead</vh></v>
<v t="edream.110203113231.197"><vh>ReadFile</vh></v>
</v>
<v t="edream.110203113231.198"><vh>class TestHtmlPanel</vh>
<v t="edream.110203113231.199"><vh>__init__</vh></v>
<v t="edream.110203113231.200"><vh>ShutdownDemo</vh></v>
<v t="edream.110203113231.201"><vh>OnShowDefault</vh></v>
<v t="edream.110203113231.202"><vh>OnLoadFile</vh></v>
<v t="edream.110203113231.203"><vh>OnLoadURL</vh></v>
<v t="edream.110203113231.204"><vh>OnWithWidgets</vh></v>
<v t="edream.110203113231.205"><vh>OnOk</vh></v>
<v t="edream.110203113231.206"><vh>OnBack</vh></v>
<v t="edream.110203113231.207"><vh>OnForward</vh></v>
<v t="edream.110203113231.208"><vh>OnViewSource</vh></v>
<v t="edream.110203113231.209"><vh>OnPrint</vh></v>
</v>
<v t="edream.110203113231.210"><vh>runTest</vh></v>
</v>
<v t="edream.110203113231.211"><vh>@file wxIEHtmlWin.py</vh>
<v t="edream.110203113231.212"><vh>class TestPanel</vh>
<v t="edream.110203113231.213"><vh>__init__</vh></v>
<v t="edream.110203113231.214"><vh>ShutdownDemo</vh></v>
<v t="edream.110203113231.215"><vh>OnSize</vh></v>
<v t="edream.110203113231.216"><vh>OnLocationSelect</vh></v>
<v t="edream.110203113231.217"><vh>OnLocationKey</vh></v>
<v t="edream.110203113231.218"><vh>IgnoreReturn</vh></v>
<v t="edream.110203113231.219"><vh>OnOpenButton</vh></v>
<v t="edream.110203113231.220"><vh>OnHomeButton</vh></v>
<v t="edream.110203113231.221"><vh>OnPrevPageButton</vh></v>
<v t="edream.110203113231.222"><vh>OnNextPageButton</vh></v>
<v t="edream.110203113231.223"><vh>OnStopButton</vh></v>
<v t="edream.110203113231.224"><vh>OnSearchPageButton</vh></v>
<v t="edream.110203113231.225"><vh>OnRefreshPageButton</vh></v>
<v t="edream.110203113231.226"><vh>logEvt</vh></v>
<v t="edream.110203113231.227"><vh>OnBeforeNavigate2</vh></v>
<v t="edream.110203113231.228"><vh>OnNewWindow2</vh></v>
<v t="edream.110203113231.229"><vh>OnDocumentComplete</vh></v>
<v t="edream.110203113231.230"><vh>OnTitleChange</vh></v>
<v t="edream.110203113231.231"><vh>OnStatusTextChange</vh></v>
</v>
<v t="edream.110203113231.232"><vh>runTest</vh></v>
</v>
</v>
</v>
</v>
<v t="edream.110603185221"><vh>Python debugger code for study</vh>
<v t="edream.110603185221.1"><vh>In python23\Lib</vh>
<v t="edream.110603185221.2"><vh>bdb.py</vh>
<v t="edream.110603185221.3"><vh>class BdbQuit (Exception)</vh></v>
<v t="edream.110603185221.4"><vh>class Bdb</vh>
<v t="edream.110603185221.5"><vh>__init__</vh></v>
<v t="edream.110603185221.6"><vh>canonic</vh></v>
<v t="edream.110603185221.7"><vh>reset</vh></v>
<v t="edream.110603185221.8"><vh>trace_dispatch</vh></v>
<v t="edream.110603185221.9"><vh>dispatch_line</vh></v>
<v t="edream.110603185221.10"><vh>dispatch_call</vh></v>
<v t="edream.110603185221.11"><vh>dispatch_return</vh></v>
<v t="edream.110603185221.12"><vh>dispatch_exception</vh></v>
<v t="edream.110603185221.13"><vh>stop_here</vh></v>
<v t="edream.110603185221.14"><vh>break_here</vh></v>
<v t="edream.110603185221.15"><vh>do_clear</vh></v>
<v t="edream.110603185221.16"><vh>break_anywhere</vh></v>
<v t="edream.110603185221.17"><vh>user_xxx (overridden in subclasses)</vh>
<v t="edream.110603185221.18"><vh>user_call</vh></v>
<v t="edream.110603185221.19"><vh>user_line</vh></v>
<v t="edream.110603185221.20"><vh>user_return</vh></v>
<v t="edream.110603185221.21"><vh>user_exception</vh></v>
</v>
<v t="edream.110603185221.22"><vh>set_xxx (called by subclasses)</vh>
<v t="edream.110603185221.23"><vh>set_step</vh></v>
<v t="edream.110603185221.24"><vh>set_next</vh></v>
<v t="edream.110603185221.25"><vh>set_return</vh></v>
<v t="edream.110603185221.26"><vh>set_trace</vh></v>
<v t="edream.110603185221.27"><vh>set_continue</vh></v>
<v t="edream.110603185221.28"><vh>set_quit</vh></v>
</v>
<v t="edream.110603185221.29"><vh>breakpoint methods (called by subclasses)</vh>
<v t="edream.110603185221.30"><vh>set_break</vh></v>
<v t="edream.110603185221.31"><vh>clear_break</vh></v>
<v t="edream.110603185221.32"><vh>clear_bpbynumber</vh></v>
<v t="edream.110603185221.33"><vh>clear_all_file_breaks</vh></v>
<v t="edream.110603185221.34"><vh>clear_all_breaks</vh></v>
<v t="edream.110603185221.35"><vh>get_break</vh></v>
<v t="edream.110603185221.36"><vh>get_breaks</vh></v>
<v t="edream.110603185221.37"><vh>get_file_breaks</vh></v>
<v t="edream.110603185221.38"><vh>get_all_breaks</vh></v>
</v>
<v t="edream.110603185221.39"><vh>stack methods (called by subclasses)</vh>
<v t="edream.110603185221.40"><vh>get_stack</vh></v>
<v t="edream.110603185221.41"><vh>format_stack_entry</vh></v>
</v>
<v t="edream.110603185221.42"><vh>run methods</vh>
<v t="edream.110603185221.43"><vh>run</vh></v>
<v t="edream.110603185221.44"><vh>runeval</vh></v>
<v t="edream.110603185221.45"><vh>runctx</vh></v>
<v t="edream.110603185221.46"><vh>runcall</vh></v>
</v>
</v>
<v t="edream.110603185221.47"><vh>set_trace</vh></v>
<v t="edream.110603185221.48"><vh>class Breakpoint</vh>
<v t="edream.110603185221.49"><vh>&lt;&lt; class Breakpoint declarations &gt;&gt;</vh></v>
<v t="edream.110603185221.50"><vh>__init__</vh></v>
<v t="edream.110603185221.51"><vh>deleteMe</vh></v>
<v t="edream.110603185221.52"><vh>enable</vh></v>
<v t="edream.110603185221.53"><vh>disable</vh></v>
<v t="edream.110603185221.54"><vh>bpprint</vh></v>
</v>
<v t="edream.110603185221.55"><vh>effective</vh>
<v t="edream.110603185221.56"><vh>&lt;&lt; handle unconditional breakpoint &gt;&gt;</vh></v>
<v t="edream.110603185221.57"><vh>&lt;&lt; handle conditional breakpoint &gt;&gt;</vh></v>
</v>
<v t="edream.110603185221.58"><vh>Testing...</vh>
<v t="edream.110603185221.59"><vh>class Tdb</vh>
<v t="edream.110603185221.60"><vh>user_call</vh></v>
<v t="edream.110603185221.61"><vh>user_line</vh></v>
<v t="edream.110603185221.62"><vh>user_return</vh></v>
<v t="edream.110603185221.63"><vh>user_exception</vh></v>
</v>
<v t="edream.110603185221.64"><vh>foo</vh></v>
<v t="edream.110603185221.65"><vh>bar</vh></v>
<v t="edream.110603185221.66"><vh>test</vh></v>
</v>
</v>
<v t="edream.110603185221.67"><vh>pdb.py</vh>
<v t="edream.110603185221.68"><vh>&lt;&lt; pdb declarations &gt;&gt;</vh></v>
<v t="edream.110603185221.69"><vh>find_function</vh></v>
<v t="edream.110603185221.70"><vh>class Pdb</vh>
<v t="edream.110603185221.71"><vh>__init__</vh></v>
<v t="edream.110603185221.72"><vh>reset</vh></v>
<v t="edream.110603185221.73"><vh>forget</vh></v>
<v t="edream.110603185221.74"><vh>setup</vh></v>
<v t="edream.110603185221.75"><vh>execRcLines</vh></v>
<v t="edream.110603185221.76"><vh>user_call</vh></v>
<v t="edream.110603185221.77"><vh>user_line</vh></v>
<v t="edream.110603185221.78"><vh>user_return</vh></v>
<v t="edream.110603185221.79"><vh>user_exception</vh></v>
<v t="edream.110603185221.80"><vh>interaction</vh></v>
<v t="edream.110603185221.81"><vh>default</vh></v>
<v t="edream.110603185221.82"><vh>precmd</vh></v>
<v t="edream.110603185221.83"><vh>do_break</vh></v>
<v t="edream.110603185221.84"><vh>defaultFile</vh></v>
<v t="edream.110603185221.85"><vh>do_tbreak</vh></v>
<v t="edream.110603185221.86"><vh>lineinfo</vh></v>
<v t="edream.110603185221.87"><vh>checkline</vh></v>
<v t="edream.110603185221.88"><vh>do_enable</vh></v>
<v t="edream.110603185221.89"><vh>do_disable</vh></v>
<v t="edream.110603185221.90"><vh>do_condition</vh></v>
<v t="edream.110603185221.91"><vh>do_ignore</vh></v>
<v t="edream.110603185221.92"><vh>do_clear</vh></v>
<v t="edream.110603185221.93"><vh>do_where</vh></v>
<v t="edream.110603185221.94"><vh>do_up</vh></v>
<v t="edream.110603185221.95"><vh>do_down</vh></v>
<v t="edream.110603185221.96"><vh>do_step</vh></v>
<v t="edream.110603185221.97"><vh>do_next</vh></v>
<v t="edream.110603185221.98"><vh>do_return</vh></v>
<v t="edream.110603185221.99"><vh>do_continue</vh></v>
<v t="edream.110603185221.100"><vh>do_jump</vh></v>
<v t="edream.110603185221.101"><vh>do_debug</vh></v>
<v t="edream.110603185221.102"><vh>do_quit</vh></v>
<v t="edream.110603185221.103"><vh>do_EOF</vh></v>
<v t="edream.110603185221.104"><vh>do_args</vh></v>
<v t="edream.110603185221.105"><vh>do_retval</vh></v>
<v t="edream.110603185221.106"><vh>_getval</vh></v>
<v t="edream.110603185221.107"><vh>do_p</vh></v>
<v t="edream.110603185221.108"><vh>do_pp</vh></v>
<v t="edream.110603185221.109"><vh>do_list</vh></v>
<v t="edream.110603185221.110"><vh>do_whatis</vh></v>
<v t="edream.110603185221.111"><vh>do_alias</vh></v>
<v t="edream.110603185221.112"><vh>do_unalias</vh></v>
<v t="edream.110603185221.113"><vh>print_stack_trace</vh></v>
<v t="edream.110603185221.114"><vh>print_stack_entry</vh></v>
<v t="edream.110603185221.115"><vh>help_help</vh></v>
<v t="edream.110603185221.116"><vh>help_h</vh></v>
<v t="edream.110603185221.117"><vh>help_where</vh></v>
<v t="edream.110603185221.118"><vh>help_w</vh></v>
<v t="edream.110603185221.119"><vh>help_down</vh></v>
<v t="edream.110603185221.120"><vh>help_d</vh></v>
<v t="edream.110603185221.121"><vh>help_up</vh></v>
<v t="edream.110603185221.122"><vh>help_u</vh></v>
<v t="edream.110603185221.123"><vh>help_break</vh></v>
<v t="edream.110603185221.124"><vh>help_b</vh></v>
<v t="edream.110603185221.125"><vh>help_clear</vh></v>
<v t="edream.110603185221.126"><vh>help_cl</vh></v>
<v t="edream.110603185221.127"><vh>help_tbreak</vh></v>
<v t="edream.110603185221.128"><vh>help_enable</vh></v>
<v t="edream.110603185221.129"><vh>help_disable</vh></v>
<v t="edream.110603185221.130"><vh>help_ignore</vh></v>
<v t="edream.110603185221.131"><vh>help_condition</vh></v>
<v t="edream.110603185221.132"><vh>help_step</vh></v>
<v t="edream.110603185221.133"><vh>help_s</vh></v>
<v t="edream.110603185221.134"><vh>help_next</vh></v>
<v t="edream.110603185221.135"><vh>help_n</vh></v>
<v t="edream.110603185221.136"><vh>help_return</vh></v>
<v t="edream.110603185221.137"><vh>help_r</vh></v>
<v t="edream.110603185221.138"><vh>help_continue</vh></v>
<v t="edream.110603185221.139"><vh>help_cont</vh></v>
<v t="edream.110603185221.140"><vh>help_c</vh></v>
<v t="edream.110603185221.141"><vh>help_jump</vh></v>
<v t="edream.110603185221.142"><vh>help_j</vh></v>
<v t="edream.110603185221.143"><vh>help_debug</vh></v>
<v t="edream.110603185221.144"><vh>help_list</vh></v>
<v t="edream.110603185221.145"><vh>help_l</vh></v>
<v t="edream.110603185221.146"><vh>help_args</vh></v>
<v t="edream.110603185221.147"><vh>help_a</vh></v>
<v t="edream.110603185221.148"><vh>help_p</vh></v>
<v t="edream.110603185221.149"><vh>help_pp</vh></v>
<v t="edream.110603185221.150"><vh>help_exec</vh></v>
<v t="edream.110603185221.151"><vh>help_quit</vh></v>
<v t="edream.110603185221.152"><vh>help_q</vh></v>
<v t="edream.110603185221.153"><vh>help_whatis</vh></v>
<v t="edream.110603185221.154"><vh>help_EOF</vh></v>
<v t="edream.110603185221.155"><vh>help_alias</vh></v>
<v t="edream.110603185221.156"><vh>help_unalias</vh></v>
<v t="edream.110603185221.157"><vh>help_pdb</vh></v>
<v t="edream.110603185221.158"><vh>lookupmodule</vh></v>
</v>
<v t="edream.110603185221.159"><vh>Interface functions...</vh>
<v t="edream.110603185221.160"><vh>run</vh></v>
<v t="edream.110603185221.161"><vh>runeval</vh></v>
<v t="edream.110603185221.162"><vh>runctx</vh></v>
<v t="edream.110603185221.163"><vh>runcall</vh></v>
<v t="edream.110603185221.164"><vh>set_trace</vh></v>
<v t="edream.110603185221.165"><vh>post_mortem</vh></v>
<v t="edream.110603185221.166"><vh>pm</vh></v>
<v t="edream.110603185221.167"><vh>test</vh></v>
<v t="edream.110603185221.168"><vh>help</vh></v>
</v>
</v>
</v>
<v t="edream.110603185221.169"><vh>python23\Lib\idlelib\Debugger.py</vh>
<v t="edream.110603185221.170"><vh>class Idb (Bdb)</vh>
<v t="edream.110603185221.171"><vh>__init__</vh></v>
<v t="edream.110603185221.172"><vh>user_line</vh></v>
<v t="edream.110603185221.173"><vh>Idb.user_exception</vh></v>
<v t="edream.110603185221.174"><vh>Idb.in_rpc_code</vh></v>
<v t="edream.110603185221.175"><vh>Idb.__frame2message</vh></v>
</v>
<v t="edream.110603185221.176"><vh>class Debugger </vh>
<v t="edream.110603185221.177"><vh>__init__</vh></v>
<v t="edream.110603185221.178"><vh>run</vh></v>
<v t="edream.110603185221.179"><vh>close</vh></v>
<v t="edream.110603185221.180"><vh>make_gui (creates frame &amp; binds buttons.</vh>
<v t="edream.110603185221.181"><vh>&lt;&lt; create the buttons &gt;&gt;</vh></v>
<v t="edream.110603185221.182"><vh>&lt;&lt; create top widget &amp; bindings &gt;&gt;</vh></v>
</v>
<v t="edream.110603185221.183"><vh>interaction</vh></v>
<v t="edream.110603185221.184"><vh>Debugger.sync_source_line</vh></v>
<v t="edream.110603185221.185"><vh>Debugger.__frame2fileline</vh></v>
<v t="edream.110603185221.186"><vh>Button handlers: these call the corresponding idb functions</vh>
<v t="edream.110603185221.187"><vh>cont</vh></v>
<v t="edream.110603185221.188"><vh>step</vh></v>
<v t="edream.110603185221.189"><vh>next</vh></v>
<v t="edream.110603185221.190"><vh>ret</vh></v>
<v t="edream.110603185221.191"><vh>quit</vh></v>
</v>
<v t="edream.110603185221.192"><vh>Checkbox handlers</vh>
<v t="edream.110603185221.193"><vh>show_stack</vh></v>
<v t="edream.110603185221.194"><vh>show_source</vh></v>
<v t="edream.110603185221.195"><vh>show_frame</vh></v>
<v t="edream.110603185221.196"><vh>show_locals</vh></v>
<v t="edream.110603185221.197"><vh>show_globals</vh></v>
<v t="edream.110603185221.198"><vh>show_variables</vh></v>
</v>
<v t="edream.110603185221.199"><vh>Breakpoint handlers</vh>
<v t="edream.110603185221.200"><vh>set_breakpoint_here</vh></v>
<v t="edream.110603185221.201"><vh>clear_breakpoint_here</vh></v>
<v t="edream.110603185221.202"><vh>clear_file_breaks</vh></v>
<v t="edream.110603185221.203"><vh>load_breakpoints</vh></v>
</v>
</v>
<v t="edream.110603185221.204"><vh>class StackViewer</vh>
<v t="edream.110603185221.205"><vh>__init__</vh></v>
<v t="edream.110603185221.206"><vh>load_stack</vh></v>
<v t="edream.110603185221.207"><vh>popup_event</vh></v>
<v t="edream.110603185221.208"><vh>fill_menu</vh></v>
<v t="edream.110603185221.209"><vh>on_select</vh></v>
<v t="edream.110603185221.210"><vh>on_double</vh></v>
<v t="edream.110603185221.211"><vh>goto_source_line</vh></v>
<v t="edream.110603185221.212"><vh>show_stack_frame</vh></v>
<v t="edream.110603185221.213"><vh>show_source</vh></v>
</v>
<v t="edream.110603185221.214"><vh>class NamespaceViewer</vh>
<v t="edream.110603185221.215"><vh>__init__</vh></v>
<v t="edream.110603185221.216"><vh>load_dict</vh></v>
<v t="edream.110603185221.217"><vh>close</vh></v>
</v>
</v>
<v t="edream.110603185221.218"><vh>Most important routines</vh>
<v t="edream.110603185221.170"><vh>class Idb (Bdb)</vh>
<v t="edream.110603185221.171"><vh>__init__</vh></v>
<v t="edream.110603185221.172"><vh>user_line</vh></v>
<v t="edream.110603185221.173"><vh>Idb.user_exception</vh></v>
<v t="edream.110603185221.174"><vh>Idb.in_rpc_code</vh></v>
<v t="edream.110603185221.175"><vh>Idb.__frame2message</vh></v>
</v>
<v t="edream.110603185221.184"><vh>Debugger.sync_source_line</vh></v>
<v t="edream.110603185221.185"><vh>Debugger.__frame2fileline</vh></v>
</v>
</v>
<v t="edream.110803170600"><vh>Count pages</vh></v>
<v t="edream.112003032318"><vh>About html plugin</vh></v>
</v>
<v t="edream.110203113231.233"><vh>wxPython plugin (alpha quality)</vh>
<v t="edream.110203113231.234"><vh> Diary</vh>
<v t="edream.111503110300"><vh>11/15/03  Leo becomes usuable (!)</vh></v>
<v t="edream.111403093253"><vh>11/13 &amp; 11/14</vh></v>
<v t="edream.110203113231.235"><vh>10/26 Code works with reorganized core</vh></v>
<v t="edream.110203113231.236"><vh>10/13/03: Added icons (Windows only)</vh></v>
<v t="edream.110203113231.237"><vh>10/12/03: Houston, we have ignition</vh></v>
<v t="edream.110203113231.238"><vh>10/11/03: converted code using c2py, then hand converted code</vh></v>
</v>
<v t="edream.111403093253.1"><vh>Projects</vh>
<v t="edream.110203113231.243"><vh>invoke c2py</vh></v>
<v t="edream.111503111146"><vh>Finished or mostly finished</vh>
<v t="edream.111303205442"><vh>(colorizing) (demo only)</vh>
<v t="edream.111303204025"><vh>Indices</vh>
<v t="edream.111303204025.1"><vh>adjustIndex</vh></v>
<v t="edream.111303204025.2"><vh>compareIndices</vh></v>
<v t="edream.111303204025.3"><vh>convertRowColumnToIndex</vh></v>
<v t="edream.111303204025.4"><vh>convertIndexToRowColumn</vh></v>
<v t="edream.111303204025.5"><vh>getImageIndex</vh></v>
<v t="edream.111403080609"><vh>maxWxIndex (internal use)</vh></v>
</v>
<v t="edream.111303204517"><vh>Color tags (hacks for styles)</vh>
<v t="edream.111403082513"><vh>tkColorToWxColor (internal use)</vh></v>
<v t="edream.111303205611"><vh>tag_add</vh></v>
<v t="edream.111303205611.1"><vh>tag_bind</vh></v>
<v t="edream.111303205611.2"><vh>tag_configure (hack for wxStyles)</vh></v>
<v t="edream.111303205611.3"><vh>tag_delete</vh></v>
<v t="edream.111303205611.4"><vh>tag_remove</vh></v>
</v>
</v>
</v>
<v t="edream.111503111350"><vh>Unfinished</vh>
<v t="edream.111303184347"><vh>(delete_range) doesn't work</vh>
<v t="edream.111303103141.3"><vh>delete_range</vh></v>
</v>
<v t="edream.111303100039"><vh>Gui-dependent commands (to do)</vh>
<v t="edream.111303100039.1"><vh>Edit Menu...</vh>
<v t="edream.111303101257"><vh>abortEditLabelCommand</vh></v>
<v t="edream.111303101257.1"><vh>endEditLabelCommand</vh></v>
<v t="edream.111303100039.6"><vh>insertHeadlineTime</vh></v>
</v>
<v t="edream.111303100039.7"><vh>Window Menu</vh>
<v t="edream.111303100039.8"><vh>cascade</vh></v>
<v t="edream.111303100039.9"><vh>equalSizedPanes</vh></v>
<v t="edream.111303100039.10"><vh>hideLogWindow</vh></v>
<v t="edream.111303100039.11"><vh>minimizeAll</vh></v>
<v t="edream.111303101709"><vh>toggleActivePane</vh></v>
<v t="edream.111303100039.12"><vh>toggleSplitDirection</vh></v>
</v>
<v t="edream.111703103908"><vh>Help Menu...</vh>
<v t="edream.111703103908.2"><vh>leoHelp</vh>
<v t="edream.111703103908.3"><vh>showProgressBar</vh>
<v t="edream.111703103908.4"><vh>&lt;&lt; create the scale widget &gt;&gt;</vh></v>
</v>
</v>
</v>
</v>
</v>
</v>
<v t="edream.110203113231.242"><vh>Unused code</vh>
<v t="edream.110203113231.257"><vh>updateJoinedHeadlines</vh></v>
<v t="edream.111303202917.1"><vh>Syntax coloring REMOVED: now in base body class</vh></v>
</v>
<v t="edream.110203113231.302" tnodeList="edream.110203113231.302,edream.110203113231.303,edream.110203113231.259,edream.110203113231.305,edream.110203113231.307,edream.110203113231.308,edream.110203113231.309,edream.110203113231.310,edream.110203113231.311,edream.110203113231.312,edream.111303085447.1,edream.110203113231.317,edream.110203113231.314,edream.110203113231.315,edream.110203113231.316,edream.110203113231.322,edream.110203113231.323,edream.110203113231.324,edream.110203113231.325,edream.110203113231.326,edream.110203113231.327,edream.110203113231.328,edream.111403104835,edream.111303092328,edream.111303092328.1,edream.111303092328.2,edream.111303092328.3,edream.111303092328.4,edream.111303092328.5,edream.110203113231.333,edream.110203113231.320,edream.111403151611,edream.110203113231.343,edream.110203113231.344,edream.110203113231.336,edream.110203113231.337,edream.110203113231.319,edream.110203113231.340,edream.110203113231.341,edream.110203113231.342,edream.111303093843,edream.111303093843.1,edream.111303093953.2,edream.111303093953.3,edream.111303093953.4,edream.111303093953.5,edream.111303093953.6,edream.111303093953.7,edream.111303093953.9,edream.111303093953.10,edream.111303093953.12,edream.111303093953.13,edream.111303093953.14,edream.111303093953.15,edream.111303093953.16,edream.111303093953.18,edream.111303093953.19,edream.111303093953.20,edream.111303093953.21,edream.111303093953.22,edream.111303093953.23,edream.111303093953.25,edream.110203113231.346,edream.110203113231.347,edream.110203113231.348,edream.110203113231.539,edream.110203113231.541,edream.110203113231.542,edream.110203113231.543,edream.111403082513,edream.111303205611,edream.111303205611.1,edream.111303205611.2,edream.111303205611.3,edream.111303205611.4,edream.110203113231.544,edream.110203113231.545,edream.111303204025.1,edream.111303204025.2,edream.111303204025.3,edream.111303204025.4,edream.111303204025.5,edream.111403080609,edream.110203113231.548,edream.110203113231.549,edream.111303171218,edream.111603222048,edream.111303171218.1,edream.111303171238,edream.111303171238.1,edream.111303171238.2,edream.111303171238.3,edream.111303171238.4,edream.110203113231.552,edream.110203113231.275,edream.111303201144.6,edream.111303201144.7,edream.110203113231.349,edream.110203113231.266,edream.110203113231.351,edream.110203113231.260,edream.110203113231.261,edream.110203113231.265,edream.110203113231.264,edream.111403141810,edream.111503105816,edream.111303141147,edream.111503213533,edream.110203113231.269,edream.110203113231.270,edream.110203113231.273,edream.110203113231.379,edream.110203113231.380,edream.110203113231.381,edream.111303135410,edream.111303101257,edream.111303101257.1,edream.111303100039.6,edream.111303100039.8,edream.111303100039.9,edream.111303100039.10,edream.111303100039.11,edream.111303101709,edream.111303100039.12,edream.111703103908.2,edream.111703103908.3,edream.111703103908.4,edream.110203113231.384,edream.110203113231.553,edream.110203113231.554,edream.110203113231.555,edream.110203113231.556,edream.110203113231.557,edream.110203113231.558,edream.110203113231.559,edream.111303095242,edream.111303095242.3,edream.111303111942.1,edream.111303103141,edream.111303121150,edream.111303103141.1,edream.111303103141.2,edream.111303103141.3,edream.111303103141.4,edream.111303111942,edream.111303110018,edream.111303103457.2,edream.111603112846.1,edream.111303103254,edream.111303095242.6,edream.111303163727.2,edream.111303163727.1,edream.111303163727.3,edream.110203113231.598,edream.110203113231.599,edream.110203113231.600,edream.110203113231.601,edream.110203113231.602,edream.110203113231.603,edream.110203113231.605,edream.110203113231.606,edream.110203113231.607,edream.110203113231.608,edream.110203113231.609,edream.110203113231.610,edream.110203113231.611,edream.110203113231.612,edream.110203113231.613,edream.110203113231.614,edream.110203113231.615,edream.110203113231.616,edream.110203113231.617,edream.111603213219,edream.111603213219.1,edream.111603213329,edream.111603221005,edream.111403090242,edream.111403090242.1,edream.111403093559,edream.111403093559.1,edream.110203113231.295,edream.110203113231.296,edream.110203113231.298,edream.110203113231.299,edream.110203113231.300,edream.111603221343.1,edream.111603221343.3,edream.111603221343.4,edream.111603221343.5,edream.111603221343.6,edream.111603221343.7,edream.110203113231.280,edream.110203113231.281,edream.110203113231.283,edream.110203113231.284,edream.110203113231.286,edream.110203113231.287,edream.110203113231.288,edream.110203113231.289,edream.110203113231.290,edream.110203113231.291,edream.110203113231.292,edream.110203113231.293,edream.111503093140,edream.111503094014,edream.111503094322,edream.111503094014.1,edream.110203113231.561,edream.110203113231.563,edream.111503074302,edream.110203113231.564,edream.111503085739,edream.111503085739.1,edream.111403151611.1,edream.111503213733,edream.111503211508,edream.111403135745,edream.111503091617,edream.111503093522,edream.111503204508,edream.110203113231.588,edream.110203113231.589,edream.110203113231.590,edream.110203113231.591,edream.110203113231.592,edream.110203113231.593,edream.110203113231.594,edream.111503133933.2,edream.111503133933.3,edream.110203113231.595,edream.110203113231.596,edream.110203113231.597,edream.110203113231.304"><vh>@file __wx_gui.py</vh>
<v t="edream.110203113231.259"><vh>&lt;&lt; constants for wx plugin &gt;&gt;</vh></v>
<v t="edream.110203113231.303"><vh>&lt;&lt; imports for wx plugin &gt;&gt;</vh></v>
<v t="edream.110203113231.304"><vh>&lt;&lt; set app.gui &gt;&gt;</vh></v>
<v t="edream.110203113231.305"><vh>wxGui class</vh>
<v t="edream.110203113231.307"><vh> wxGui.__init__</vh></v>
<v t="edream.111303091300"><vh>app.gui.wx birth &amp; death</vh>
<v t="edream.110203113231.308"><vh>createRootWindow &amp; allies</vh>
<v t="edream.110203113231.309"><vh>setDefaultIcon</vh></v>
<v t="edream.110203113231.310"><vh>setEncoding</vh></v>
<v t="edream.110203113231.311"><vh>getDefaultConfigFont</vh></v>
<v t="edream.110203113231.312"><vh>createGlobalWindows</vh></v>
</v>
<v t="edream.111303085447.1"><vh>destroySelf</vh></v>
<v t="edream.110203113231.317"><vh>runMainLoop</vh></v>
<v t="edream.110203113231.306"><vh>stubs</vh>
<v t="edream.110203113231.314"><vh>finishCreate</vh></v>
<v t="edream.110203113231.315"><vh>killGui</vh></v>
<v t="edream.110203113231.316"><vh>recreateRootWindow</vh></v>
</v>
</v>
<v t="edream.110203113231.321"><vh>app.gui wx dialogs</vh>
<v t="edream.110203113231.322"><vh>runAboutLeoDialog</vh></v>
<v t="edream.110203113231.323"><vh>runAskOkDialog</vh></v>
<v t="edream.110203113231.324"><vh>runAskOkCancelNumberDialog TODO</vh></v>
<v t="edream.110203113231.325"><vh>runAskYesNoDialog</vh></v>
<v t="edream.110203113231.326"><vh>runAskYesNoCancelDialog</vh></v>
<v t="edream.110203113231.327"><vh>runOpenFileDialog</vh></v>
<v t="edream.110203113231.328"><vh>runSaveFileDialog</vh></v>
<v t="edream.111403104835"><vh>getWildcardList</vh></v>
</v>
<v t="edream.111303091857"><vh>app.gui wx panels</vh>
<v t="edream.111303092328"><vh>createColorPanel</vh></v>
<v t="edream.111303092328.1"><vh>createComparePanel</vh></v>
<v t="edream.111303092328.2"><vh>createFindPanel</vh></v>
<v t="edream.111303092328.3"><vh>createFontPanel</vh></v>
<v t="edream.111303092328.4"><vh>createLeoFrame</vh></v>
<v t="edream.111303092328.5"><vh>createPrefsPanel</vh></v>
<v t="edream.110203113231.333"><vh>destroyLeoFrame (used??)</vh></v>
</v>
<v t="edream.111303090930"><vh>app.gui.wx utils</vh>
<v t="edream.110203113231.320"><vh>Clipboard</vh></v>
<v t="edream.110203113231.339"><vh>Dialog</vh>
<v t="edream.111403151611"><vh>bringToFront</vh></v>
<v t="edream.110203113231.343"><vh>get_window_info</vh></v>
<v t="edream.110203113231.344"><vh>center_dialog</vh></v>
</v>
<v t="edream.110203113231.335"><vh>Focus </vh>
<v t="edream.110203113231.336"><vh>get_focus</vh></v>
<v t="edream.110203113231.337"><vh>set_focus</vh></v>
</v>
<v t="edream.110203113231.318"><vh>Font</vh>
<v t="edream.110203113231.319"><vh>getFontFromParams</vh></v>
</v>
<v t="edream.111303092854"><vh>Icons</vh>
<v t="edream.110203113231.340"><vh>attachLeoIcon</vh>
<v t="edream.110203113231.341"><vh>&lt;&lt; try to use the PIL and tkIcon packages to draw the icon &gt;&gt;</vh></v>
</v>
<v t="edream.110203113231.342"><vh>createLeoIcon</vh></v>
</v>
<v t="edream.110203113231.329"><vh>Idle time</vh>
<v t="edream.111303093843"><vh>setIdleTimeHook</vh></v>
<v t="edream.111303093843.1"><vh>setIdleTimeHookAfterDelay</vh></v>
</v>
<v t="edream.111303093953.1"><vh>Indices</vh>
<v t="edream.111303093953.2"><vh>firstIndex</vh></v>
<v t="edream.111303093953.3"><vh>lastIndex</vh></v>
<v t="edream.111303093953.4"><vh>moveIndexBackward</vh></v>
<v t="edream.111303093953.5"><vh>moveIndexForward</vh></v>
<v t="edream.111303093953.6"><vh>compareIndices</vh></v>
<v t="edream.111303093953.7"><vh>getindex</vh></v>
</v>
<v t="edream.111303093953.8"><vh>Insert Point</vh>
<v t="edream.111303093953.9"><vh>getInsertPoint</vh></v>
<v t="edream.111303093953.10"><vh>setInsertPoint</vh></v>
</v>
<v t="edream.111303093953.11"><vh>Selection</vh>
<v t="edream.111303093953.12"><vh>getSelectionRange</vh></v>
<v t="edream.111303093953.13"><vh>getTextSelection</vh></v>
<v t="edream.111303093953.14"><vh>setSelectionRange</vh></v>
<v t="edream.111303093953.15"><vh>setSelectionRangeWithLength</vh></v>
<v t="edream.111303093953.16"><vh>setTextSelection</vh></v>
</v>
<v t="edream.111303093953.17"><vh>Text</vh>
<v t="edream.111303093953.18"><vh>getAllText</vh></v>
<v t="edream.111303093953.19"><vh>getCharAfterIndex</vh></v>
<v t="edream.111303093953.20"><vh>getCharAtIndex</vh></v>
<v t="edream.111303093953.21"><vh>getCharBeforeIndex</vh></v>
<v t="edream.111303093953.22"><vh>getLineContainingIndex</vh></v>
<v t="edream.111303093953.23"><vh>replaceSelectionRangeWithText</vh></v>
</v>
<v t="edream.111303093953.24"><vh>Visibility</vh>
<v t="edream.111303093953.25"><vh>makeIndexVisible</vh></v>
</v>
</v>
</v>
<v t="edream.110203113231.346"><vh>wxLeoApp class</vh>
<v t="edream.110203113231.347"><vh>OnInit</vh></v>
<v t="edream.110203113231.348"><vh>OnExit</vh></v>
</v>
<v t="edream.110203113231.539"><vh>wxLeoBody class</vh>
<v t="edream.110203113231.540"><vh>Birth &amp; death</vh>
<v t="edream.110203113231.541"><vh>wxLeoBody.__init__</vh></v>
<v t="edream.110203113231.542"><vh>wxLeoBody.createControl</vh></v>
</v>
<v t="edream.111303204836"><vh>Tk wrappers wxLeoBody TO DO</vh>
<v t="edream.110203113231.543"><vh>Bounding box...</vh></v>
<v t="edream.111303204517"><vh>Color tags (hacks for styles)</vh>
<v t="edream.111403082513"><vh>tkColorToWxColor (internal use)</vh></v>
<v t="edream.111303205611"><vh>tag_add</vh></v>
<v t="edream.111303205611.1"><vh>tag_bind</vh></v>
<v t="edream.111303205611.2"><vh>tag_configure (hack for wxStyles)</vh></v>
<v t="edream.111303205611.3"><vh>tag_delete</vh></v>
<v t="edream.111303205611.4"><vh>tag_remove</vh></v>
</v>
<v t="edream.110203113231.544"><vh>Config... TO DO</vh></v>
<v t="edream.110203113231.545"><vh>Focus...</vh></v>
<v t="edream.111303204025"><vh>Indices</vh>
<v t="edream.111303204025.1"><vh>adjustIndex</vh></v>
<v t="edream.111303204025.2"><vh>compareIndices</vh></v>
<v t="edream.111303204025.3"><vh>convertRowColumnToIndex</vh></v>
<v t="edream.111303204025.4"><vh>convertIndexToRowColumn</vh></v>
<v t="edream.111303204025.5"><vh>getImageIndex</vh></v>
<v t="edream.111403080609"><vh>maxWxIndex (internal use)</vh></v>
</v>
<v t="edream.110203113231.548"><vh>Idle-time callback...</vh></v>
<v t="edream.110203113231.549"><vh>Height &amp; width info...</vh></v>
<v t="edream.111303171218"><vh>Insert point</vh></v>
<v t="edream.111603222048"><vh>Menu</vh></v>
<v t="edream.111303171218.1"><vh>Selection</vh></v>
<v t="edream.111303171238"><vh>Text</vh>
<v t="edream.111303171238.1"><vh>delete... (untested)</vh></v>
<v t="edream.111303171238.2"><vh>get... TO DO</vh></v>
<v t="edream.111303171238.3"><vh>insert...</vh></v>
<v t="edream.111303171238.4"><vh>setSelectionAreas</vh></v>
</v>
<v t="edream.110203113231.552"><vh>Visibility &amp; scrolling...</vh></v>
</v>
<v t="edream.110203113231.275"><vh>onBodyTextUpdated MORE WORK NEEDED</vh>
<v t="edream.111303201144.6"><vh>&lt;&lt; recolor the body &gt;&gt;</vh></v>
<v t="edream.111303201144.7"><vh>&lt;&lt; redraw the screen if necessary &gt;&gt;</vh></v>
</v>
</v>
<v t="edream.110203113231.349"><vh>wxLeoFrame class</vh>
<v t="edream.110203113231.350"><vh>Birth &amp; death</vh>
<v t="edream.110203113231.266"><vh>__init__</vh></v>
<v t="edream.110203113231.351"><vh>__repr__</vh></v>
<v t="edream.110203113231.260"><vh>finishCreate</vh>
<v t="edream.110203113231.261"><vh>&lt;&lt; create the splitters &gt;&gt;</vh></v>
<v t="edream.110203113231.264"><vh>&lt;&lt; declare event handlers for frame &gt;&gt;</vh></v>
<v t="edream.110203113231.265"><vh>&lt;&lt; set the window icon &gt;&gt;</vh></v>
</v>
<v t="edream.111403141810"><vh>initialRatios</vh></v>
<v t="edream.111503105816"><vh>injectCallbacks</vh></v>
<v t="edream.111303141147"><vh>signOnWithVersion</vh></v>
<v t="edream.111503213533"><vh>destroySelf</vh></v>
</v>
<v t="edream.110203113231.267"><vh>event handlers</vh>
<v t="edream.110203113231.268"><vh>Frame events</vh>
<v t="edream.110203113231.269"><vh>onActivate &amp; OnSetFocus</vh></v>
<v t="edream.110203113231.270"><vh>onCloseLeoFrame</vh></v>
<v t="edream.110203113231.273"><vh>onResize</vh></v>
</v>
</v>
<v t="edream.110203113231.379"><vh>wxFrame dummy routines: (to do: minor)</vh></v>
<v t="edream.110203113231.378"><vh>Externally visible routines...</vh>
<v t="edream.110203113231.380"><vh>deiconify</vh></v>
<v t="edream.110203113231.381"><vh>getTitle</vh></v>
<v t="edream.111303135410"><vh>setTitle</vh></v>
</v>
<v t="edream.111303100039"><vh>Gui-dependent commands (to do)</vh>
<v t="edream.111303100039.1"><vh>Edit Menu...</vh>
<v t="edream.111303101257"><vh>abortEditLabelCommand</vh></v>
<v t="edream.111303101257.1"><vh>endEditLabelCommand</vh></v>
<v t="edream.111303100039.6"><vh>insertHeadlineTime</vh></v>
</v>
<v t="edream.111303100039.7"><vh>Window Menu</vh>
<v t="edream.111303100039.8"><vh>cascade</vh></v>
<v t="edream.111303100039.9"><vh>equalSizedPanes</vh></v>
<v t="edream.111303100039.10"><vh>hideLogWindow</vh></v>
<v t="edream.111303100039.11"><vh>minimizeAll</vh></v>
<v t="edream.111303101709"><vh>toggleActivePane</vh></v>
<v t="edream.111303100039.12"><vh>toggleSplitDirection</vh></v>
</v>
<v t="edream.111703103908"><vh>Help Menu...</vh>
<v t="edream.111703103908.2"><vh>leoHelp</vh>
<v t="edream.111703103908.3"><vh>showProgressBar</vh>
<v t="edream.111703103908.4"><vh>&lt;&lt; create the scale widget &gt;&gt;</vh></v>
</v>
</v>
</v>
</v>
<v t="edream.110203113231.384"><vh>updateAllMenus (wxFrame)</vh></v>
</v>
<v t="edream.110203113231.553"><vh>wxLeoLog class</vh>
<v t="edream.110203113231.554"><vh>leoLog.__init__</vh></v>
<v t="edream.110203113231.555"><vh>leoLog.configure</vh></v>
<v t="edream.110203113231.556"><vh>leoLog.configureBorder</vh></v>
<v t="edream.110203113231.557"><vh>leoLog.createControl</vh></v>
<v t="edream.110203113231.558"><vh>leoLog.setLogFontFromConfig</vh></v>
<v t="edream.110203113231.559"><vh>wxLeoLog.put &amp; putnl</vh></v>
</v>
<v t="edream.111303095242"><vh>wxLeoMenu class</vh>
<v t="edream.111303095242.3"><vh>  wxLeoMenu.__init__</vh></v>
<v t="edream.111303103457"><vh>wx menu bindings</vh>
<v t="edream.111603104327"><vh>9 Routines with Tk names</vh>
<v t="edream.111303111942.1"><vh>add_cascade</vh></v>
<v t="edream.111303103141"><vh>add_command</vh></v>
<v t="edream.111303121150"><vh>add_separator</vh></v>
<v t="edream.111303103141.1"><vh>bind (wx has a different key model than tk)</vh></v>
<v t="edream.111303103141.2"><vh>delete (not called?)</vh></v>
<v t="edream.111303103141.3"><vh>delete_range</vh></v>
<v t="edream.111303103141.4"><vh>destroy (not called ?)</vh></v>
<v t="edream.111303111942"><vh>insert_cascade</vh></v>
<v t="edream.111303110018"><vh>new_menu</vh></v>
</v>
<v t="edream.111603112846"><vh>7 Routines with other names...</vh>
<v t="edream.111303103457.2"><vh>createMenuBar</vh></v>
<v t="edream.111603112846.1"><vh>createOpenWithMenuFromTable (not ready yet)</vh></v>
<v t="edream.111303103254"><vh>defineMenuCallback</vh></v>
<v t="edream.111303095242.6"><vh>defineOpenWithMenuCallback</vh></v>
<v t="edream.111303163727.2"><vh>disableMenu</vh></v>
<v t="edream.111303163727.1"><vh>enableMenu</vh></v>
<v t="edream.111303163727.3"><vh>setMenuLabel</vh></v>
</v>
</v>
</v>
<v t="edream.110203113231.598"><vh>wxLeoPrefs class</vh>
<v t="edream.110203113231.599"><vh>wxLeoPrefs.__init__</vh>
<v t="edream.110203113231.600"><vh>&lt;&lt; define event handlers for wxLeoPrefsFrame &gt;&gt;</vh></v>
</v>
<v t="edream.110203113231.601"><vh>initialize</vh></v>
<v t="edream.110203113231.602"><vh>targetToLanguage (should be in Leo's core)</vh></v>
<v t="edream.110203113231.603"><vh>languageToTarget (should be in Leo's core)</vh></v>
<v t="edream.110203113231.604"><vh>Event handlers</vh>
<v t="edream.110203113231.605"><vh>OnActivatePrefsFrame</vh></v>
<v t="edream.110203113231.606"><vh>OnClosePrefsFrame</vh></v>
<v t="edream.110203113231.607"><vh>OnPageWidthText</vh></v>
<v t="edream.110203113231.608"><vh>OnDoneBatCheckBox</vh></v>
<v t="edream.110203113231.609"><vh>OnUnBatCheckBox</vh></v>
<v t="edream.110203113231.610"><vh>OnTangleDirectoryText</vh></v>
<v t="edream.110203113231.611"><vh>OnHeaderCheckBox</vh></v>
<v t="edream.110203113231.612"><vh>OnDocChunksCheckBox</vh></v>
<v t="edream.110203113231.613"><vh>OnTargetLanguageRadioBox</vh></v>
</v>
<v t="edream.110203113231.614"><vh>PrefsPanel.__init__</vh>
<v t="edream.110203113231.615"><vh>&lt;&lt; Create the Global Options static box &gt;&gt;</vh></v>
<v t="edream.110203113231.616"><vh>&lt;&lt; Create the Default Tangle Options static box &gt;&gt;</vh></v>
<v t="edream.110203113231.617"><vh>&lt;&lt; Create the Default Target Language radio buttons &gt;&gt;</vh></v>
</v>
</v>
<v t="edream.111603213219"><vh>wxLeoTree class</vh>
<v t="edream.111603213219.1"><vh>__init__</vh>
<v t="edream.111603213329"><vh>&lt;&lt; declare event handlers &gt;&gt;</vh></v>
</v>
<v t="edream.111603221005"><vh>expandAllAncestors</vh></v>
<v t="edream.111403090242"><vh>Drawing  &amp; scrolling TO DO</vh></v>
<v t="edream.111403090242.1"><vh>Editing TO DO</vh></v>
<v t="edream.111403093559"><vh>Focus</vh></v>
<v t="edream.111403093559.1"><vh>Fonts TO DO</vh></v>
<v t="edream.111303202917"><vh>Tree refresh</vh>
<v t="edream.110203113231.295"><vh>beginUpdate</vh></v>
<v t="edream.110203113231.296"><vh>endUpdate</vh></v>
<v t="edream.110203113231.298"><vh>redraw &amp; redraw_now</vh></v>
<v t="edream.110203113231.299"><vh>redraw_node</vh></v>
<v t="edream.110203113231.300"><vh>redraw_subtree</vh></v>
</v>
<v t="edream.111603221343.1"><vh>select</vh>
<v t="edream.111603221343.3"><vh>&lt;&lt; unselect the old node &gt;&gt;</vh></v>
<v t="edream.111603221343.4"><vh>&lt;&lt; select the new node &gt;&gt;</vh></v>
<v t="edream.111603221343.5"><vh>&lt;&lt; update c.beadList or c.beadPointer &gt;&gt;</vh></v>
<v t="edream.111603221343.6"><vh>&lt;&lt; update c.visitedList &gt;&gt;</vh></v>
<v t="edream.111603221343.7"><vh>&lt;&lt; set the current node and redraw &gt;&gt;</vh></v>
</v>
<v t="edream.110203113231.278"><vh>Event handlers</vh>
<v t="edream.110203113231.279"><vh>Expand/contract</vh>
<v t="edream.110203113231.280"><vh>onTreeCollapsed &amp; onTreeExpanded</vh></v>
<v t="edream.110203113231.281"><vh>onTreeCollapsing &amp; onTreeExpanding</vh></v>
</v>
<v t="edream.110203113231.282"><vh>Selecting</vh>
<v t="edream.110203113231.283"><vh>onTreeChanged</vh></v>
<v t="edream.110203113231.284"><vh>onTreeChanging</vh></v>
</v>
<v t="edream.110203113231.285"><vh>Editing labels</vh>
<v t="edream.110203113231.286"><vh>onTreeBeginLabelEdit</vh></v>
<v t="edream.110203113231.287"><vh>onTreeEndLabelEdit</vh></v>
<v t="edream.110203113231.288"><vh>onTreeKeyDown</vh></v>
</v>
<v t="edream.110203113231.289"><vh>onTreeBeginDrag</vh></v>
<v t="edream.110203113231.290"><vh>onTreeEndDrag (NOT READY YET)</vh>
<v t="edream.110203113231.291"><vh>&lt;&lt; Define onTreeEndDrag vars &gt;&gt;</vh></v>
<v t="edream.110203113231.292"><vh>&lt;&lt; Insert src as the first child of dst &gt;&gt;</vh></v>
<v t="edream.110203113231.293"><vh>&lt;&lt; Insert src after dst &gt;&gt;</vh></v>
</v>
</v>
</v>
<v t="edream.110203113231.560"><vh>Find...</vh>
<v t="edream.111503093140"><vh>wxSearchWidget</vh>
<v t="edream.111503094014"><vh>wxSearchWidget.__init__</vh></v>
<v t="edream.111503094322"><vh>Insert point</vh></v>
<v t="edream.111503094014.1"><vh>Selection</vh></v>
</v>
<v t="edream.110203113231.561"><vh>wxFindFrame class</vh>
<v t="edream.110203113231.563"><vh>FindFrame.__init__</vh>
<v t="edream.110203113231.564"><vh>&lt;&lt; define event handlers &gt;&gt;</vh>
<v t="edream.111503085739"><vh>&lt;&lt; create event handlers for buttons &gt;&gt;</vh></v>
<v t="edream.111503085739.1"><vh>&lt;&lt; create event handlers for check boxes and text &gt;&gt;</vh></v>
</v>
<v t="edream.111503074302"><vh>&lt;&lt; resize the frame to fit the panel &gt;&gt;</vh></v>
</v>
<v t="edream.111403151611.1"><vh>bringToFront</vh></v>
<v t="edream.111503213733"><vh>destroySelf</vh></v>
<v t="edream.111503211508"><vh>onCloseFindFrame</vh></v>
<v t="edream.111403135745"><vh>set_ivars</vh></v>
<v t="edream.111503091617"><vh>init_s_text</vh></v>
<v t="edream.111503093522"><vh>gui_search</vh></v>
<v t="edream.111503204508"><vh>init</vh></v>
</v>
<v t="edream.110203113231.588"><vh>wxFindPanel class</vh>
<v t="edream.110203113231.589"><vh>FindPanel.__init__</vh>
<v t="edream.110203113231.590"><vh>&lt;&lt; Create the find text box &gt;&gt;</vh></v>
<v t="edream.110203113231.591"><vh>&lt;&lt; Create the change text box &gt;&gt;</vh></v>
<v t="edream.110203113231.592"><vh>&lt;&lt; Create all the find check boxes &gt;&gt;</vh>
<v t="edream.110203113231.593"><vh>&lt;&lt; Create the first column of widgets &gt;&gt;</vh></v>
<v t="edream.110203113231.594"><vh>&lt;&lt; Create the second column of widgets &gt;&gt;</vh></v>
<v t="edream.111503133933.2"><vh>&lt;&lt; Create the third column of widgets &gt;&gt;</vh></v>
<v t="edream.111503133933.3"><vh>&lt;&lt; Create the fourth column of widgets &gt;&gt;</vh></v>
</v>
<v t="edream.110203113231.595"><vh>&lt;&lt; Create all the find buttons &gt;&gt;</vh>
<v t="edream.110203113231.596"><vh>&lt;&lt; Create the first row of buttons &gt;&gt;</vh></v>
<v t="edream.110203113231.597"><vh>&lt;&lt; Create the second row of buttons &gt;&gt;</vh></v>
</v>
</v>
</v>
</v>
</v>
</v>
<v t="edream.120203141341"><vh>(Scripts to debug font problem)</vh>
<v t="edream.120203141341.1"><vh>Show font</vh></v>
<v t="edream.120203140328.1"><vh>Show settings</vh>
<v t="edream.120203140328.2"><vh>getFontSettings</vh></v>
</v>
<v t="edream.120203141927"><vh>Print default font</vh></v>
</v>
</v>
<v t="edream.120103084310"><vh>(Load plugins only from plugins menu)</vh>
<v t="edream.120103084310.1"><vh>Report</vh></v>
</v>
<v t="edream.110203113231.618" a="E"><vh>Plugins &amp; scripts</vh>
<v t="edream.031217101015"><vh>Contributed scripts</vh>
<v t="edream.110203113231.619"><vh>From Bernhard Mulder</vh>
<v t="edream.110203113231.620" tnodeList="edream.110203113231.620,edream.110203113231.621,edream.110203113231.622,edream.110203113231.623,edream.110203113231.624,edream.110203113231.625,edream.110203113231.626,edream.110203113231.627,edream.110203113231.628,edream.110203113231.629"><vh>@file ../scripts/foldersize_leo.py</vh>
<v t="edream.110203113231.621"><vh>normalize</vh></v>
<v t="edream.110203113231.622"><vh>filesize</vh></v>
<v t="edream.110203113231.623"><vh>format</vh></v>
<v t="edream.110203113231.624"><vh>class TreeItem</vh>
<v t="edream.110203113231.625"><vh>__init__</vh></v>
<v t="edream.110203113231.626"><vh>format_directory</vh></v>
<v t="edream.110203113231.627"><vh>format_file</vh></v>
<v t="edream.110203113231.628"><vh>GetSubList</vh></v>
</v>
<v t="edream.110203113231.629"><vh>test</vh></v>
</v>
<v t="edream.110203113231.630" tnodeList="edream.110203113231.630,edream.110203113231.631,edream.110203113231.632,edream.110203113231.633,edream.110203113231.634,edream.110203113231.635,edream.110203113231.636,edream.110203113231.637,edream.110203113231.638,edream.110203113231.639,edream.110203113231.640,edream.110203113231.641,edream.110203113231.642,edream.110203113231.643,edream.110203113231.644,edream.110203113231.645,edream.110203113231.646,edream.110203113231.647,edream.110203113231.648,edream.110203113231.649,edream.110203113231.650,edream.110203113231.651,edream.110203113231.652,edream.110203113231.653,edream.110203113231.654,edream.110203113231.655,edream.110203113231.656,edream.110203113231.657,edream.110203113231.658,edream.110203113231.659,edream.110203113231.660,edream.110203113231.661,edream.110203113231.662,edream.110203113231.663,edream.110203113231.664,edream.110203113231.665,edream.110203113231.666"><vh>@file ../scripts/leo_interface.py</vh>
<v t="edream.110203113231.631"><vh>escape</vh></v>
<v t="edream.110203113231.632"><vh>class node</vh>
<v t="edream.110203113231.633"><vh>__init__</vh></v>
<v t="edream.110203113231.634"><vh>gen</vh></v>
<v t="edream.110203113231.635"><vh>add_child</vh></v>
<v t="edream.110203113231.636"><vh>mark</vh></v>
<v t="edream.110203113231.637"><vh>mark_with_attributes</vh></v>
<v t="edream.110203113231.638"><vh>mark_with_attributes_short</vh></v>
<v t="edream.110203113231.639"><vh>gen_children</vh></v>
</v>
<v t="edream.110203113231.640"><vh>class file</vh>
<v t="edream.110203113231.641"><vh>header</vh></v>
<v t="edream.110203113231.642"><vh>sss</vh></v>
<v t="edream.110203113231.643"><vh>preferences</vh></v>
<v t="edream.110203113231.644"><vh>empty</vh></v>
<v t="edream.110203113231.645"><vh>find_panel_settings</vh></v>
<v t="edream.110203113231.646"><vh>gen</vh></v>
<v t="edream.110203113231.647"><vh>gen1</vh></v>
<v t="edream.110203113231.648"><vh>gen_vnodes</vh></v>
<v t="edream.110203113231.649"><vh>gen_tnodes</vh></v>
<v t="edream.110203113231.650"><vh>nr_tnodes</vh></v>
<v t="edream.110203113231.651"><vh>max_tnode_index</vh></v>
</v>
<v t="edream.110203113231.652"><vh>class leo_node</vh>
<v t="edream.110203113231.653"><vh>__init__</vh></v>
<v t="edream.110203113231.654"><vh>set_headline</vh></v>
<v t="edream.110203113231.655"><vh>set_body</vh></v>
<v t="edream.110203113231.656"><vh>get_headline</vh></v>
<v t="edream.110203113231.657"><vh>get_body</vh></v>
<v t="edream.110203113231.658"><vh>gen_vnodes</vh></v>
<v t="edream.110203113231.659"><vh>gen_vnodes1</vh></v>
<v t="edream.110203113231.660"><vh>write_headline</vh></v>
<v t="edream.110203113231.661"><vh>gen_tnodes</vh></v>
<v t="edream.110203113231.662"><vh>gen_tnodes1</vh></v>
<v t="edream.110203113231.663"><vh>write_body</vh></v>
<v t="edream.110203113231.664"><vh>write_headline_escaped</vh></v>
<v t="edream.110203113231.665"><vh>write_body_escaped</vh></v>
</v>
<v t="edream.110203113231.666"><vh>leotree</vh></v>
</v>
</v>
<v t="edream.031217101015.1"><vh>From RodrigoB</vh>
<v t="edream.120703082844" tnodeList="edream.120703082844,edream.120703082844.1,edream.120703082844.2"><vh>@file mod_updown.py</vh>
<v t="edream.120703082844.1"><vh>0nStart2</vh></v>
<v t="edream.120703082844.2"><vh>OnBodyKey</vh></v>
</v>
</v>
</v>
<v t="edream.110203113231.667"><vh>Commands</vh>
<v t="edream.110203113231.668"><vh> Importing Cisco configuration files</vh>
<v t="edream.110203113231.669" tnodeList="edream.110203113231.669,edream.110203113231.670,edream.110203113231.671,edream.110203113231.672,edream.110203113231.673,edream.110203113231.674,edream.110203113231.675,edream.110203113231.676"><vh>@file import_cisco_config.py</vh>
<v t="edream.110203113231.670"><vh>&lt;&lt; about this plugin &gt;&gt;</vh></v>
<v t="edream.110203113231.671"><vh>create_import_cisco_menu</vh></v>
<v t="edream.110203113231.672"><vh>importCiscoConfig</vh>
<v t="edream.110203113231.673"><vh>&lt;&lt; open file &gt;&gt;</vh></v>
<v t="edream.110203113231.674"><vh>&lt;&lt; process custom line &gt;&gt;</vh></v>
<v t="edream.110203113231.675"><vh>&lt;&lt; process indented block &gt;&gt;</vh></v>
<v t="edream.110203113231.676"><vh>&lt;&lt; complete outline &gt;&gt;</vh></v>
</v>
</v>
<v t="edream.110203113231.677"><vh> Example of an imported config</vh>
<v t="edream.110203113231.678"><vh>plain configuration</vh></v>
<v t="edream.110203113231.679"><vh>cisco config: C:/Davide/Leo/CVS Version/example_conf.txt</vh>
<v t="edream.110203113231.680"><vh>&lt;&lt;access-list&gt;&gt;</vh></v>
<v t="edream.110203113231.681"><vh>&lt;&lt;boot&gt;&gt;</vh></v>
<v t="edream.110203113231.682"><vh>&lt;&lt;controller&gt;&gt;</vh>
<v t="edream.110203113231.683"><vh>controller E1 5/0/0</vh></v>
<v t="edream.110203113231.684"><vh>controller E1 5/0/1</vh></v>
<v t="edream.110203113231.685"><vh>controller SONET 1/0/0</vh></v>
</v>
<v t="edream.110203113231.686"><vh>&lt;&lt;interface&gt;&gt;</vh>
<v t="edream.110203113231.687"><vh>interface Async1</vh></v>
<v t="edream.110203113231.688"><vh>interface Dialer0</vh></v>
<v t="edream.110203113231.689"><vh>interface FastEthernet0/0/0</vh></v>
<v t="edream.110203113231.690"><vh>interface FastEthernet0/0/1</vh></v>
<v t="edream.110203113231.691"><vh>interface FastEthernet0/0/1.1</vh></v>
<v t="edream.110203113231.692"><vh>interface FastEthernet0/0/1.2</vh></v>
<v t="edream.110203113231.693"><vh>interface FastEthernet0/0/1.3</vh></v>
<v t="edream.110203113231.694"><vh>interface FastEthernet0/0/1.5</vh></v>
<v t="edream.110203113231.695"><vh>interface FastEthernet0/0/1.50</vh></v>
<v t="edream.110203113231.696"><vh>interface Loopback0</vh></v>
<v t="edream.110203113231.697"><vh>interface POS4/1/0</vh></v>
<v t="edream.110203113231.698"><vh>interface Serial5/0/0:1</vh></v>
<v t="edream.110203113231.699"><vh>interface Serial5/0/0:2</vh></v>
<v t="edream.110203113231.700"><vh>interface Serial5/0/1:0</vh></v>
<v t="edream.110203113231.701"><vh>interface Serial5/1/0</vh></v>
<v t="edream.110203113231.702"><vh>interface Serial5/1/1</vh></v>
</v>
<v t="edream.110203113231.703"><vh>&lt;&lt;ip community-list&gt;&gt;</vh></v>
<v t="edream.110203113231.704"><vh>&lt;&lt;ip route&gt;&gt;</vh></v>
<v t="edream.110203113231.705"><vh>&lt;&lt;line&gt;&gt;</vh>
<v t="edream.110203113231.706"><vh>line aux 0</vh></v>
<v t="edream.110203113231.707"><vh>line vty 0 4</vh></v>
</v>
<v t="edream.110203113231.708"><vh>&lt;&lt;logging&gt;&gt;</vh></v>
<v t="edream.110203113231.709"><vh>&lt;&lt;ntp&gt;&gt;</vh></v>
<v t="edream.110203113231.710"><vh>&lt;&lt;route-map&gt;&gt;</vh>
<v t="edream.110203113231.711"><vh>route-map only permit 2</vh></v>
<v t="edream.110203113231.712"><vh>route-map only1 permit 10</vh></v>
<v t="edream.110203113231.713"><vh>route-map only3 permit 10</vh></v>
<v t="edream.110203113231.714"><vh>route-map tag_com permit 10</vh></v>
<v t="edream.110203113231.715"><vh>route-map tag_com permit 20</vh></v>
</v>
<v t="edream.110203113231.716"><vh>&lt;&lt;router&gt;&gt;</vh>
<v t="edream.110203113231.717"><vh>router bgp 65001</vh></v>
<v t="edream.110203113231.718"><vh>router ospf 1</vh></v>
</v>
<v t="edream.110203113231.719"><vh>&lt;&lt;service&gt;&gt;</vh></v>
</v>
</v>
</v>
<v t="edream.110203113231.720" tnodeList="edream.110203113231.720,edream.110203113231.721"><vh>@file outline_export.py</vh>
<v t="edream.110203113231.721"><vh>newMoreHead</vh></v>
</v>
<v t="edream.110203113231.722"><vh>mod_autosave</vh>
<v t="edream.110203113231.723" tnodeList="edream.110203113231.723"><vh>@file-nosent mod_autosave.ini</vh></v>
<v t="edream.110203113231.724" tnodeList="edream.110203113231.724,edream.110203113231.725,edream.110203113231.726"><vh>@file mod_autosave.py</vh>
<v t="edream.110203113231.725"><vh>applyConfiguration</vh></v>
<v t="edream.110203113231.726"><vh>autosave</vh></v>
</v>
</v>
<v t="edream.110203113231.727" tnodeList="edream.110203113231.727,edream.110203113231.728"><vh>@file mod_timestamp.py</vh>
<v t="edream.110203113231.728"><vh>timestamp</vh></v>
</v>
</v>
<v t="edream.110203113231.729"><vh>Debugging</vh>
<v t="edream.110203113231.730" tnodeList="edream.110203113231.730,edream.110203113231.731"><vh>@file dump_globals.py</vh>
<v t="edream.110203113231.731"><vh>onStart</vh></v>
</v>
<v t="edream.110203113231.732" tnodeList="edream.110203113231.732,edream.110203113231.733"><vh>@file enable_gc.py</vh>
<v t="edream.110203113231.733"><vh>onStart</vh></v>
</v>
<v t="edream.110203113231.734" tnodeList="edream.110203113231.734"><vh>@file quit_leo.py</vh></v>
<v t="edream.110203113231.735" tnodeList="edream.110203113231.735"><vh>@file trace_gc.py</vh></v>
<v t="edream.110203113231.736" tnodeList="edream.110203113231.736,edream.110203113231.737"><vh>@file trace_keys.py</vh>
<v t="edream.110203113231.737"><vh>onKey</vh></v>
</v>
<v t="edream.110203113231.738" tnodeList="edream.110203113231.738,edream.110203113231.739"><vh>@file trace_tags.py</vh>
<v t="edream.110203113231.739"><vh>trace_tags</vh></v>
</v>
</v>
<v t="edream.110203113231.740"><vh>Directives</vh>
<v t="edream.110203113231.741" tnodeList="edream.110203113231.741,edream.110203113231.742,edream.110203113231.743"><vh>@file add_directives.py</vh>
<v t="edream.110203113231.742"><vh>addPluginDirectives</vh></v>
<v t="edream.110203113231.743"><vh>scanPluginDirectives</vh></v>
</v>
</v>
<v t="edream.110203113231.744"><vh>Drawing, graphics &amp; styled text</vh>
<v t="edream.110403140857"><vh>Wiki plugin 1.4 (color_markup)(requires add-directives plugin)</vh>
<v t="edream.110403140857.1"><vh>Plugin documentation</vh>
<v t="edream.110403140857.2"><vh>Installation</vh></v>
<v t="edream.110403140857.3"><vh>Use</vh>
<v t="edream.110403140857.4"><vh>Supported markups</vh></v>
<v t="edream.110403140857.5"><vh>Example</vh>
<v t="edream.110403140857.6"><vh>a subnode</vh></v>
</v>
</v>
<v t="edream.110403140857.7"><vh>Release notes</vh></v>
</v>
<v t="edream.110403140857.8" tnodeList="edream.110403140857.8,edream.110403140857.9,edream.110403140857.10,edream.110403140857.11,edream.110403140857.12,edream.110403140857.13,edream.110403140857.14,edream.110403140857.15,edream.110403140857.16,edream.110403140857.17,edream.110403140857.18,edream.110403140857.20,edream.110403140857.21,edream.110403140857.22,edream.110403140857.23,edream.110403140857.24,edream.110403140857.25,edream.110403140857.26,edream.110403140857.27,edream.110403140857.28"><vh>@file color_markup.py</vh>
<v t="edream.110403140857.9"><vh>initAnyMarkup</vh></v>
<v t="edream.110403140857.10"><vh>colorWikiMarkup</vh></v>
<v t="edream.110403140857.11"><vh>doWikiText</vh>
<v t="edream.110403140857.12"><vh>&lt;&lt; set first to a tuple describing the first tag to be handled &gt;&gt;</vh></v>
<v t="edream.110403140857.13"><vh>&lt;&lt; handle the tag using n1,n2,delim1,delim2 &gt;&gt;</vh>
<v t="edream.110403140857.14"><vh>&lt;&lt; parse and handle color field &gt;&gt;</vh></v>
</v>
</v>
<v t="edream.110403140857.15"><vh>insertWikiPicture</vh></v>
<v t="edream.110403140857.16"><vh>onBodykey1 (not ready)</vh></v>
<v t="edream.110403140857.17"><vh>onBodydclick1 &amp; allies</vh>
<v t="edream.110403140857.18"><vh>getUrl</vh></v>
</v>
<v t="edream.110403140857.19"><vh>Menu handling</vh>
<v t="edream.110403140857.20"><vh>createWikiMenu</vh></v>
<v t="edream.110403140857.21"><vh>doWikiBold</vh></v>
<v t="edream.110403140857.22"><vh>doWikiItalic</vh></v>
<v t="edream.110403140857.23"><vh>doWikiColor</vh></v>
<v t="edream.110403140857.24"><vh>doWikiChooseColor</vh></v>
<v t="edream.110403140857.25"><vh>doWikiPicture (not ready)</vh></v>
<v t="edream.110403140857.26"><vh>insertWikiMarkup</vh>
<v t="edream.110403140857.27"><vh>&lt;&lt; apply markup to selection &gt;&gt;</vh></v>
<v t="edream.110403140857.28"><vh>&lt;&lt; handle no selection &gt;&gt;</vh></v>
</v>
</v>
</v>
</v>
<v t="edream.110203113231.753" tnodeList="edream.110203113231.753,edream.110203113231.754,edream.110203113231.755,edream.110203113231.756,edream.110203113231.757"><vh>@file image.py</vh>
<v t="edream.110203113231.754"><vh>onSelect</vh>
<v t="edream.110203113231.755"><vh>&lt;&lt; Select Image &gt;&gt;</vh></v>
</v>
<v t="edream.110203113231.756"><vh>onUnselect</vh>
<v t="edream.110203113231.757"><vh>&lt;&lt; Unselect Image &gt;&gt;</vh></v>
</v>
</v>
<v t="edream.110203113231.758" tnodeList="edream.110203113231.758,edream.110203113231.759,edream.110203113231.760,edream.110203113231.761,edream.110203113231.762,edream.110203113231.763,edream.110203113231.764,edream.110203113231.766,edream.110203113231.767,edream.110203113231.768,edream.110203113231.769,edream.110203113231.770,edream.110203113231.771,edream.110203113231.772,edream.110203113231.773,edream.110203113231.774,edream.110203113231.775,edream.110203113231.776,edream.110203113231.777,edream.110203113231.778,edream.110203113231.779,edream.110203113231.780,edream.110203113231.781,edream.110203113231.782,edream.110203113231.783,edream.110203113231.784,edream.110203113231.785,edream.110203113231.786,edream.110203113231.787,edream.110203113231.788,edream.110203113231.789"><vh>@file nav_buttons.py</vh>
<v t="edream.110203113231.759"><vh>class commanderInfoClass</vh>
<v t="edream.110203113231.760"><vh>__init__ (commanderInfoClass)</vh></v>
<v t="edream.110203113231.761"><vh>addWidgets</vh>
<v t="edream.110203113231.762"><vh>&lt;&lt; define callbacks &gt;&gt;</vh></v>
</v>
<v t="edream.110203113231.763"><vh>createImage</vh></v>
<v t="edream.110203113231.764"><vh>updateNavButtons (nav_buttons.py)</vh></v>
<v t="edream.110203113231.765"><vh>Callbacks</vh>
<v t="edream.110203113231.766"><vh>marksButtonCallback</vh></v>
<v t="edream.110203113231.767"><vh>recentButtonCallback</vh></v>
</v>
</v>
<v t="edream.110203113231.768"><vh>class globalInfoClass</vh>
<v t="edream.110203113231.769"><vh>__init__ ( globalInfoClass)</vh></v>
<v t="edream.110203113231.770"><vh>addNavWidgets</vh></v>
<v t="edream.110203113231.771"><vh>destroyFrame, destroyAllFrames, destroyOneFrame</vh></v>
<v t="edream.110203113231.772"><vh>updateRecentSections</vh></v>
<v t="edream.110203113231.773"><vh>updateMarks &amp; updateMarksAfterCommand</vh></v>
<v t="edream.110203113231.774"><vh>updateNavButtons</vh></v>
</v>
<v t="edream.110203113231.775"><vh>class marksDialog (listBoxDialog)</vh>
<v t="edream.110203113231.776"><vh>marksDialog.__init__</vh></v>
<v t="edream.110203113231.777"><vh>createFrame</vh></v>
<v t="edream.110203113231.778"><vh>addbuttons</vh></v>
<v t="edream.110203113231.779"><vh>fillbox</vh></v>
</v>
<v t="edream.110203113231.780"><vh>class recentSectionsDialog (tkinterListBoxDialog)</vh>
<v t="edream.110203113231.781"><vh>__init__  recentSectionsDialog</vh></v>
<v t="edream.110203113231.782"><vh>addButtons</vh></v>
<v t="edream.110203113231.783"><vh>clearAll</vh></v>
<v t="edream.110203113231.784"><vh>createFrame</vh></v>
<v t="edream.110203113231.785"><vh>deleteEntry</vh></v>
<v t="edream.110203113231.786"><vh>destroy</vh></v>
<v t="edream.110203113231.787"><vh>fillbox (recent sections)</vh>
<v t="edream.110203113231.788"><vh>&lt;&lt; reconstruct the contents of self.box &gt;&gt;&gt;</vh></v>
</v>
<v t="edream.110203113231.789"><vh>synchNavButtons</vh></v>
</v>
</v>
</v>
<v t="edream.110203113231.790"><vh>External editors &amp; Open With</vh>
<v t="edream.120303095057.1" tnodeList="edream.120303095057.1,edream.120303095910,edream.120303095910.1"><vh>@file mod_tempfname.py</vh>
<v t="edream.120303095910"><vh>onStart</vh></v>
<v t="edream.120303095910.1"><vh>openWithTempFilePath</vh></v>
</v>
<v t="edream.110203113231.791" tnodeList="edream.110203113231.791,edream.110203113231.792,edream.110203113231.793,edream.110203113231.794,edream.110203113231.795,edream.110203113231.796"><vh>@file open_with.py</vh>
<v t="edream.110203113231.792"><vh>on_idle</vh>
<v t="edream.110203113231.793"><vh>&lt;&lt; update v's body text &gt;&gt;</vh>
<v t="edream.110203113231.794"><vh>&lt;&lt; set s to the file text &gt;&gt;</vh></v>
</v>
</v>
<v t="edream.110203113231.795"><vh>create_open_with_menu</vh>
<v t="edream.110203113231.796"><vh>&lt;&lt; create the Open With menu &gt;&gt;</vh></v>
</v>
</v>
<v t="edream.110203113231.799" tnodeList="edream.110203113231.799,edream.110203113231.800"><vh>@file vim.py</vh>
<v t="edream.110203113231.800"><vh>open_in_vim</vh></v>
</v>
<v t="edream.110203113231.797" tnodeList="edream.110203113231.797"><vh>@file xemacs.py</vh></v>
<v t="edream.110203113231.803"><vh>Word export</vh>
<v t="edream.110203113231.804" tnodeList="edream.110203113231.804,edream.110203113231.805,edream.110203113231.806,edream.110203113231.807,edream.110203113231.808,edream.110203113231.809"><vh>@file word_export.py</vh>
<v t="edream.110203113231.805"><vh>getConfiguration</vh></v>
<v t="edream.110203113231.806"><vh>getWordConnection</vh></v>
<v t="edream.110203113231.807"><vh>doPara</vh></v>
<v t="edream.110203113231.808"><vh>writeNodeAndTree</vh></v>
<v t="edream.110203113231.809"><vh>cmd_Export</vh></v>
</v>
<v t="edream.110203113231.810" tnodeList="edream.110203113231.810"><vh>@file-nosent word_export.ini</vh></v>
</v>
</v>
<v t="edream.110203113231.811"><vh>Files</vh>
<v t="edream.110203113231.812" tnodeList="edream.110203113231.812,edream.110203113231.813,edream.110203113231.814"><vh>@file empty_leo_file.py</vh>
<v t="edream.110203113231.813"><vh>&lt;&lt; define minimal .leo file &gt;&gt;</vh></v>
<v t="edream.110203113231.814"><vh>onOpen</vh></v>
</v>
<v t="edream.110203113231.815" tnodeList="edream.110203113231.815,edream.110203113231.816,edream.110203113231.817,edream.110203113231.818,edream.110203113231.819,edream.110203113231.820,edream.110203113231.821,edream.110203113231.822"><vh>@file open_shell.py</vh>
<v t="edream.110203113231.816"><vh>&lt;&lt; about the open shell plugin &gt;&gt;</vh></v>
<v t="edream.110203113231.817"><vh>load_menu</vh></v>
<v t="edream.110203113231.818"><vh>_getpath</vh></v>
<v t="edream.110203113231.819"><vh>_getcurrentnodepath</vh></v>
<v t="edream.110203113231.820"><vh>launchCmd</vh></v>
<v t="edream.110203113231.821"><vh>launchExplorer</vh></v>
<v t="edream.110203113231.822"><vh>launchxTerm</vh></v>
</v>
</v>
<v t="edream.110203113231.823"><vh>Foreign languages</vh>
<v t="edream.110203113231.824" tnodeList="edream.110203113231.824,edream.110203113231.825"><vh>@file french.py</vh>
<v t="edream.110203113231.825"><vh>onMenu</vh></v>
</v>
<v t="edream.110203113231.826" tnodeList="edream.110203113231.826,edream.110203113231.827"><vh>@file french_fm.py</vh>
<v t="edream.110203113231.827"><vh>onMenu</vh></v>
</v>
</v>
<v t="edream.110203113231.828"><vh>Key bindings</vh>
<v t="edream.110203113231.829" tnodeList="edream.110203113231.829,edream.110203113231.830"><vh>@file arrows.py</vh>
<v t="edream.110203113231.830"><vh>onOpen</vh></v>
</v>
</v>
<v t="edream.110203113231.831"><vh>Menus</vh>
<v t="edream.110203113231.832"><vh> Plugins menu</vh>
<v t="edream.110203113231.833" tnodeList="edream.110203113231.833,edream.110203113231.834,edream.110203113231.835,edream.110203113231.836,edream.110203113231.837,edream.110203113231.838,edream.110203113231.839,edream.110203113231.840,edream.110203113231.841,edream.110203113231.842,edream.110203113231.843,edream.110203113231.844,edream.110203113231.845,edream.110203113231.846,edream.110203113231.847,edream.110203113231.848,edream.110203113231.849,edream.110203113231.850,edream.110203113231.851,edream.110203113231.852,edream.110203113231.853,edream.110203113231.854,edream.110203113231.855"><vh>@file plugins_menu.py</vh>
<v t="edream.110203113231.834"><vh>class Plugin</vh>
<v t="edream.110203113231.835"><vh>__init__</vh>
<v t="edream.110203113231.836"><vh>&lt;&lt; Check if this can be configured &gt;&gt;</vh></v>
<v t="edream.110203113231.837"><vh>&lt;&lt; Check if this has an apply &gt;&gt;</vh></v>
<v t="edream.110203113231.838"><vh>&lt;&lt; Look for additional commands &gt;&gt;</vh></v>
</v>
<v t="edream.110203113231.839"><vh>about</vh></v>
<v t="edream.110203113231.840"><vh>properties</vh></v>
</v>
<v t="edream.110203113231.841"><vh>class PropertiesWindow</vh>
<v t="edream.110203113231.842"><vh>__init__</vh>
<v t="edream.110203113231.843"><vh>&lt;&lt; initialize all ivars &gt;&gt;</vh></v>
<v t="edream.110203113231.844"><vh>&lt;&lt; create the frame from the configuration data &gt;&gt;</vh>
<v t="edream.110203113231.845"><vh>&lt;&lt; Create the top level and the main frame &gt;&gt;</vh></v>
<v t="edream.110203113231.846"><vh>&lt;&lt; Create widgets for each section and option &gt;&gt;</vh></v>
<v t="edream.110203113231.847"><vh>&lt;&lt; Create Ok, Cancel and Apply buttons &gt;&gt;</vh></v>
</v>
</v>
<v t="edream.110203113231.848"><vh>Event Handlers</vh></v>
<v t="edream.110203113231.849"><vh>writeConfiguration</vh></v>
</v>
<v t="edream.110203113231.850"><vh>class PluginAbout</vh>
<v t="edream.110203113231.851"><vh>__init__</vh>
<v t="edream.110203113231.852"><vh>&lt;&lt; Create the contents of the about box &gt;&gt;</vh></v>
<v t="edream.110203113231.853"><vh>&lt;&lt; Create the close button &gt;&gt;</vh></v>
</v>
</v>
<v t="edream.110203113231.854"><vh>createPluginsMenu</vh>
<v t="edream.110203113231.855"><vh>&lt;&lt; add items to the plugins menu &gt;&gt;</vh></v>
</v>
</v>
<v t="edream.110203113231.856" tnodeList="edream.110203113231.856,edream.110203113231.857,edream.110203113231.858,edream.110203113231.859,edream.110203113231.860,edream.110203113231.861,edream.110203113231.862"><vh>@file pluginsTest.py</vh>
<v t="edream.110203113231.857"><vh>applyConfiguration</vh></v>
<v t="edream.110203113231.858"><vh>cmd_fn1/2/3</vh></v>
<v t="edream.110203113231.859"><vh>onSelect</vh>
<v t="edream.110203113231.860"><vh>&lt;&lt; Select Image &gt;&gt;</vh></v>
</v>
<v t="edream.110203113231.861"><vh>onUnselect</vh>
<v t="edream.110203113231.862"><vh>&lt;&lt; Unselect Image &gt;&gt;</vh></v>
</v>
</v>
<v t="edream.110203113231.863"><vh>Notes re plugins menu</vh>
<v t="edream.110203113231.864"><vh> Changes made by E.K.Ream</vh></v>
<v t="edream.110203113231.865"><vh> Design</vh></v>
<v t="edream.110203113231.866"><vh> Initial suggestion from Paul Paterson</vh></v>
</v>
</v>
<v t="edream.110203113231.867" tnodeList="edream.110203113231.867,edream.110203113231.868,edream.110203113231.869,edream.110203113231.870,edream.110203113231.871"><vh>@file scripts_menu.py</vh>
<v t="edream.110203113231.868"><vh>createScriptsMenu</vh>
<v t="edream.110203113231.869"><vh>&lt;&lt; Return if no scripts exist anywhere &gt;&gt;</vh></v>
<v t="edream.110203113231.870"><vh>&lt;&lt; Create top-level entries for every script in top_scripts &gt;&gt;</vh></v>
<v t="edream.110203113231.871"><vh>&lt;&lt; Create a submenu for dir containing each file in files &gt;&gt;</vh></v>
</v>
</v>
</v>
<v t="edream.110203113231.872" a="E"><vh>New kinds of nodes</vh>
<v t="edream.110203113231.873" tnodeList="edream.110203113231.873,edream.110203113231.874,edream.110203113231.875"><vh>@file at_folder.py</vh>
<v t="edream.110203113231.874"><vh>&lt;&lt; about this plugin &gt;&gt;</vh></v>
<v t="edream.110203113231.875"><vh>sync_node_to_folder</vh></v>
</v>
<v t="edream.110203113231.876" tnodeList="edream.110203113231.876,edream.110203113231.877,edream.110203113231.878,edream.110203113231.879,edream.110203113231.880,edream.110203113231.882,edream.110203113231.883,edream.110203113231.885,edream.110203113231.887,edream.110203113231.888,edream.110203113231.889,edream.110203113231.890,edream.110203113231.891,edream.110203113231.892,edream.110203113231.893,edream.110203113231.894,edream.110203113231.895,edream.110203113231.896,edream.110203113231.897,edream.110203113231.898,edream.110203113231.899,edream.110203113231.900"><vh>@file read_only_nodes.py</vh>
<v t="edream.110203113231.877"><vh>documentation for @read-only nodes</vh>
<v t="edream.110203113231.878"><vh>ftp/http access</vh></v>
</v>
<v t="edream.110203113231.879"><vh>class FTPurl</vh>
<v t="edream.110203113231.880"><vh>__init__</vh></v>
<v t="edream.110203113231.881"><vh>Getters</vh>
<v t="edream.110203113231.882"><vh>read</vh></v>
<v t="edream.110203113231.883"><vh>readline</vh></v>
</v>
<v t="edream.110203113231.884"><vh>Setters</vh>
<v t="edream.110203113231.885"><vh>write</vh></v>
</v>
<v t="edream.110203113231.886"><vh>Utilities</vh>
<v t="edream.110203113231.887"><vh>seek</vh></v>
<v t="edream.110203113231.888"><vh>flush</vh></v>
<v t="edream.110203113231.889"><vh>dir</vh></v>
<v t="edream.110203113231.890"><vh>exists</vh></v>
<v t="edream.110203113231.891"><vh>checkParams</vh></v>
</v>
<v t="edream.110203113231.892"><vh>close</vh></v>
</v>
<v t="edream.110203113231.893"><vh>enable/disable_body</vh></v>
<v t="edream.110203113231.894"><vh>insert_read_only_node (FTP version)</vh>
<v t="edream.110203113231.895"><vh>&lt;&lt; convert HTML to text &gt;&gt;</vh></v>
</v>
<v t="edream.110203113231.896"><vh>on_open2</vh></v>
<v t="edream.110203113231.897"><vh>on_bodykey1</vh></v>
<v t="edream.110203113231.898"><vh>on_headkey2</vh></v>
<v t="edream.110203113231.899"><vh>on_select1</vh></v>
<v t="edream.110203113231.900"><vh>on_select2</vh></v>
</v>
<v t="edream.111803100242" a="E" tnodeList="edream.111803100242,edream.111803100242.1,edream.111803100242.2,edream.111803100242.3,edream.111803100242.4,edream.111803100242.5,edream.111803100242.6,edream.111803100242.7,edream.111803100242.8"><vh>@file rst.py</vh>
<v t="edream.111803100242.1"><vh>&lt;&lt;about this plugin &gt;&gt;</vh></v>
<v t="edream.111803100242.2"><vh>&lt;&lt; change log &gt;&gt;</vh></v>
<v t="edream.111803100242.3" a="E"><vh>onIconDoubleClick</vh>
<v t="edream.111803100242.4"><vh>&lt;&lt; write rST as HTML/LaTeX &gt;&gt;</vh>
<v t="edream.111803100242.5"><vh>&lt;&lt; convert rST to HTML/LaTeX &gt;&gt;</vh></v>
</v>
<v t="edream.111803100242.6"><vh>&lt;&lt; write rST file &gt;&gt;</vh></v>
</v>
<v t="edream.111803100242.7"><vh>writeTreeAsRst</vh></v>
<v t="edream.111803100242.8"><vh>underline</vh></v>
</v>
<v t="edream.110203113231.910" tnodeList="edream.110203113231.910,edream.110203113231.911,edream.110203113231.912,edream.110203113231.913,edream.110203113231.914"><vh>@file startfile.py</vh>
<v t="edream.110203113231.911"><vh>&lt;&lt;about this plugin &gt;&gt;</vh></v>
<v t="edream.110203113231.912"><vh>&lt;&lt; change log &gt;&gt;</vh></v>
<v t="edream.110203113231.913"><vh>onIconDoubleClick</vh>
<v t="edream.110203113231.914"><vh>&lt;&lt; find path and start file &gt;&gt;</vh></v>
</v>
</v>
</v>
<v t="edream.110203113231.915"><vh>Overriding functions, methods &amp; classes</vh>
<v t="edream.110203113231.916" tnodeList="edream.110203113231.916,edream.110203113231.917,edream.110203113231.918"><vh>@file __overrideClasses.py</vh>
<v t="edream.110203113231.917"><vh>&lt;&lt; override the LeoFrame class &gt;&gt;</vh></v>
<v t="edream.110203113231.918"><vh>&lt;&lt; override methods of the LeoApp class &gt;&gt;</vh></v>
</v>
<v t="edream.110203113231.919" tnodeList="edream.110203113231.919,edream.110203113231.920"><vh>@file override_commands.py</vh>
<v t="edream.110203113231.920"><vh>onCommand</vh></v>
</v>
<v t="edream.110203113231.921" tnodeList="edream.110203113231.921,edream.110203113231.922,edream.110203113231.923"><vh>@file redefine_put.py</vh>
<v t="edream.110203113231.922"><vh>onStart</vh></v>
<v t="edream.110203113231.923"><vh>newPut and newPutNl</vh></v>
</v>
<v t="edream.110203113231.924" tnodeList="edream.110203113231.924"><vh>@file redirect_to_log.py</vh></v>
<v t="edream.110203113231.925" tnodeList="edream.110203113231.925,edream.110203113231.926,edream.110203113231.927,edream.110203113231.928,edream.110203113231.929"><vh>@file script_io_to_body.py</vh>
<v t="edream.110203113231.926"><vh>onStart</vh></v>
<v t="edream.110203113231.927"><vh>newExecuteScript</vh></v>
<v t="edream.110203113231.928"><vh>newPut and newPutNl</vh></v>
<v t="edream.110203113231.929"><vh>newEs, etc.</vh></v>
</v>
</v>
<v t="edream.110203113231.930"><vh>Spell Checking</vh>
<v t="edream.110203113231.931"><vh>@silentfile mod_spelling.txt</vh></v>
<v t="edream.110203113231.932" tnodeList="edream.110203113231.932"><vh>@silentfile mod_spelling.ini</vh></v>
<v t="edream.110203113231.933" tnodeList="edream.110203113231.933,edream.110203113231.935,edream.110203113231.936,edream.110203113231.937,edream.110203113231.938,edream.110203113231.940,edream.110203113231.941,edream.110203113231.942,edream.110203113231.943,edream.110203113231.944,edream.110203113231.945,edream.110203113231.946,edream.110203113231.947,edream.110203113231.948,edream.110203113231.950,edream.110203113231.951,edream.110203113231.952,edream.110203113231.953,edream.110203113231.954,edream.110703030027,edream.110203113231.955,edream.110203113231.956,edream.110203113231.957,edream.110203113231.959,edream.110203113231.960,edream.110203113231.961,edream.110203113231.962,edream.110203113231.963,edream.110203113231.964,edream.110203113231.966,edream.110203113231.967,edream.110203113231.968,edream.110203113231.969,edream.110203113231.970,edream.110203113231.972,edream.110203113231.973,edream.110203113231.974,edream.110203113231.975,edream.110203113231.976,edream.110203113231.977,edream.110203113231.978,edream.110203113231.979,edream.110203113231.980,edream.110203113231.981"><vh>@file mod_spelling.py</vh>
<v t="edream.110203113231.934"><vh>Functions</vh>
<v t="edream.110203113231.935"><vh>createSpellMenu</vh></v>
<v t="edream.110203113231.936"><vh>onSelect</vh></v>
<v t="edream.110203113231.937"><vh>onCommand</vh></v>
</v>
<v t="edream.110203113231.938"><vh>class Aspell</vh>
<v t="edream.110203113231.939"><vh>Birth &amp; death</vh>
<v t="edream.110203113231.940"><vh>__init__</vh></v>
<v t="edream.110203113231.941"><vh>getAspellDirectory</vh></v>
</v>
<v t="edream.110203113231.942"><vh>openPipes</vh>
<v t="edream.110203113231.943"><vh>&lt;&lt; Ensure local dictionary is present &gt;&gt;</vh></v>
</v>
<v t="edream.110203113231.944"><vh>closePipes</vh></v>
<v t="edream.110203113231.945"><vh>listAlternates</vh></v>
<v t="edream.110203113231.946"><vh>processWord</vh></v>
<v t="edream.110203113231.947"><vh>updateDictionary</vh></v>
</v>
<v t="edream.110203113231.948"><vh>class spellDialog</vh>
<v t="edream.110203113231.949"><vh>Birth &amp; death</vh>
<v t="edream.110203113231.950"><vh>spell.__init__</vh>
<v t="edream.110203113231.951"><vh>&lt;&lt; set self.dictionary &gt;&gt;</vh></v>
</v>
<v t="edream.110203113231.952"><vh>getLocalDictionary</vh></v>
<v t="edream.110203113231.953"><vh>getLocalLanguageCode</vh></v>
<v t="edream.110203113231.954"><vh>readLocalDictionary</vh></v>
<v t="edream.110703030027"><vh>destroySelf</vh></v>
</v>
<v t="edream.110203113231.955"><vh>createFrame</vh>
<v t="edream.110203113231.956"><vh>&lt;&lt; Create the text and suggestion panes &gt;&gt;</vh></v>
<v t="edream.110203113231.957"><vh>&lt;&lt; Create the spelling buttons &gt;&gt;</vh></v>
</v>
<v t="edream.110203113231.958"><vh>Buttons</vh>
<v t="edream.110203113231.959"><vh>onAddButton</vh></v>
<v t="edream.110203113231.960"><vh>onIgnoreButton</vh></v>
<v t="edream.110203113231.961"><vh>onChangeButton &amp; onChangeThenFindButton</vh></v>
<v t="edream.110203113231.962"><vh>onFindButton</vh></v>
<v t="edream.110203113231.963"><vh>onHideButton</vh></v>
<v t="edream.110203113231.964"><vh>onRedoButton &amp; onUndoButton</vh></v>
</v>
<v t="edream.110203113231.965"><vh>Commands</vh>
<v t="edream.110203113231.966"><vh>add</vh></v>
<v t="edream.110203113231.967"><vh>change</vh></v>
<v t="edream.110203113231.968"><vh>checkSpelling</vh></v>
<v t="edream.110203113231.969"><vh>find</vh></v>
<v t="edream.110203113231.970"><vh>ignore</vh></v>
</v>
<v t="edream.110203113231.971"><vh>Helpers</vh>
<v t="edream.110203113231.972"><vh>closePipes</vh></v>
<v t="edream.110203113231.973"><vh>fillbox</vh></v>
<v t="edream.110203113231.974"><vh>findNextMisspelledWord</vh>
<v t="edream.110203113231.975"><vh>&lt;&lt; Skip word if ignored or in local dictionary &gt;&gt;</vh></v>
</v>
<v t="edream.110203113231.976"><vh>findNextWord</vh></v>
<v t="edream.110203113231.977"><vh>getSuggestion</vh></v>
<v t="edream.110203113231.978"><vh>onMap</vh></v>
<v t="edream.110203113231.979"><vh>onSelectListBox</vh></v>
<v t="edream.110203113231.980"><vh>update</vh></v>
<v t="edream.110203113231.981"><vh>updateButtons</vh></v>
</v>
</v>
</v>
</v>
<v t="edream.110203113231.982"><vh>Plugin manager (demo)</vh>
<v t="edream.110203113231.983"><vh>Notes by Paul Paterson</vh></v>
<v t="edream.110203113231.984" tnodeList="edream.110203113231.984,edream.110203113231.985,edream.110203113231.986,edream.110203113231.987,edream.110203113231.988,edream.110203113231.989,edream.110203113231.990,edream.110203113231.991,edream.110203113231.992,edream.110203113231.993"><vh>@file leopm_client.py</vh>
<v t="edream.110203113231.985"><vh>class LeoPMClient</vh>
<v t="edream.110203113231.986"><vh>__init__</vh></v>
<v t="edream.110203113231.987"><vh>poll</vh></v>
<v t="edream.110203113231.988"><vh>_getSelectedPluginName</vh></v>
<v t="edream.110203113231.989"><vh>updateDetail</vh></v>
<v t="edream.110203113231.990"><vh>downloadPlugin</vh></v>
<v t="edream.110203113231.991"><vh>getPluginList</vh></v>
<v t="edream.110203113231.992"><vh>initListbox</vh></v>
<v t="edream.110203113231.993"><vh>getVersionOfFile</vh></v>
</v>
</v>
<v t="edream.110203113231.994" tnodeList="edream.110203113231.994,edream.110203113231.995,edream.110203113231.995,edream.110203113231.996,edream.110203113231.997,edream.110203113231.998,edream.110203113231.999,edream.110203113231.1000,edream.110203113231.1001"><vh>@file leopm_server.py</vh>
<v t="edream.110203113231.995"><vh>class LeoPM</vh>
<v t="edream.110203113231.996"><vh>__init__</vh></v>
<v t="edream.110203113231.997"><vh>getPluginNames</vh></v>
<v t="edream.110203113231.998"><vh>getPluginDescription</vh></v>
<v t="edream.110203113231.999"><vh>getPlugin</vh></v>
<v t="edream.110203113231.1000"><vh>getPluginVersion</vh></v>
<v t="edream.110203113231.1001"><vh>getPluginFilenames</vh></v>
</v>
</v>
</v>
</v>
<v t="ekr.20040107092135" a="E"><vh>New plugins:  very cool</vh>
<v t="ekr.20040109080300"><vh> Changes made by EKR</vh></v>
<v t="ekr.20040111053758"><vh> Description of rst2 by Steve Zatz</vh></v>
<v t="ekr.20040118081748" a="E" tnodeList="ekr.20040118081748,ekr.20040118081748.1,ekr.20040118081748.2,ekr.20040118081748.3,ekr.20040118081748.4,ekr.20040118081748.5,ekr.20040118081748.6,ekr.20040118081748.7,ekr.20040118081748.8"><vh>@file rst2.py</vh>
<v t="ekr.20040118081748.1" a="M"><vh>&lt;&lt;about this plugin &gt;&gt;</vh></v>
<v t="ekr.20040118081748.2"><vh>&lt;&lt; change log &gt;&gt;</vh></v>
<v t="ekr.20040118081748.3" a="E"><vh>onIconDoubleClick</vh>
<v t="ekr.20040118081748.4" a="E"><vh>&lt;&lt; write rST as HTML/LaTeX &gt;&gt;</vh>
<v t="ekr.20040118081748.5"><vh>&lt;&lt; define code-block &gt;&gt;</vh></v>
</v>
<v t="ekr.20040118081748.6"><vh>&lt;&lt; write rST file &gt;&gt;</vh></v>
</v>
<v t="ekr.20040118081748.7" a="TV"><vh>writeTreeAsRst</vh></v>
<v t="ekr.20040118081748.8"><vh>underline</vh></v>
</v>
<v t="ekr.20040107092135.2" tnodeList="ekr.20040107092135.2,ekr.20040108060748,ekr.20040108054555.14,ekr.20040107092135.3,ekr.20040108054555.4,ekr.20040108054555.3,ekr.20040107092135.5,ekr.20040107111307,ekr.20040108054555.5,ekr.20040108054555.8,ekr.20040108054555.7,ekr.20040107092135.6,ekr.20040107092135.7,ekr.20040107092135.8,ekr.20040107103252,ekr.20040107103339"><vh>@file searchbox.py</vh>
<v t="ekr.20040108054555.14"><vh>&lt;&lt; vars &gt;&gt;</vh></v>
<v t="ekr.20040107092135.3"><vh>class SearchBox</vh>
<v t="ekr.20040108054555.4"><vh>_getSizer</vh></v>
<v t="ekr.20040108054555.3"><vh>addWidgets</vh></v>
<v t="ekr.20040107092135.5"><vh>doSearch</vh></v>
<v t="ekr.20040107111307"><vh>onBackSpace</vh></v>
<v t="ekr.20040108054555.5"><vh>onKey</vh></v>
<v t="ekr.20040108054555.8"><vh>searchRecent</vh></v>
<v t="ekr.20040108054555.7"><vh>updateRecentList</vh></v>
</v>
<v t="ekr.20040107092135.6"><vh>class QuickFind</vh>
<v t="ekr.20040107092135.7"><vh>__init__</vh></v>
<v t="ekr.20040107092135.8"><vh>set_ivars</vh></v>
<v t="ekr.20040107103252"><vh>init_s_text</vh></v>
<v t="ekr.20040107103339"><vh>gui_search</vh></v>
</v>
<v t="ekr.20040108060748"><vh>&lt;&lt; doc string &gt;&gt;</vh></v>
</v>
<v t="ekr.20040108062655" tnodeList="ekr.20040108062655,ekr.20040108062655.2,ekr.20040108062655.3,ekr.20040108062655.4,ekr.20040108062655.5,ekr.20040108091136,ekr.20040108062655.6"><vh>@file nodenavigator.py</vh>
<v t="ekr.20040108062655.2" a="E"><vh>class Navigator</vh>
<v t="ekr.20040108062655.3"><vh>addWidgets</vh></v>
<v t="ekr.20040108062655.4"><vh>_getSizer</vh></v>
<v t="ekr.20040108062655.5"><vh>onSelect</vh></v>
<v t="ekr.20040108091136"><vh>updateRecent</vh></v>
<v t="ekr.20040108062655.6"><vh>updateMarks</vh></v>
</v>
</v>
<v t="ekr.20040108095351" tnodeList="ekr.20040108095351,ekr.20040108095351.1,ekr.20040108100040,ekr.20040108095351.2,ekr.20040108095351.4"><vh>@file rowcol.py</vh>
<v t="ekr.20040108095351.1" a="E"><vh>class rowColClass</vh>
<v t="ekr.20040108100040"><vh>__init__</vh></v>
<v t="ekr.20040108095351.2"><vh>addWidgets</vh></v>
<v t="ekr.20040108095351.4"><vh>updateRowColWidget</vh></v>
</v>
</v>
<v t="ekr.20040119044414"><vh>Minimal http plugin</vh>
<v t="ekr.20040119044414.1" tnodeList="ekr.20040119044414.1,ekr.20040119102021.3,ekr.20040119044414.3,ekr.20040119044414.5,ekr.20040119044414.6,ekr.20040119044414.7,ekr.20040119044414.8,ekr.20040119044414.9,ekr.20040119044414.10,ekr.20040119044414.11,ekr.20040119044414.12,ekr.20040119044414.13,ekr.20040119044414.14,ekr.20040119044414.17,ekr.20040119044414.15,ekr.20040119044414.16,ekr.20040119044414.18,ekr.20040119044414.19,ekr.20040119044414.20,ekr.20040119044414.22,ekr.20040119044414.23,ekr.20040119044414.24,ekr.20040119044414.25,ekr.20040119044414.26,ekr.20040119044414.27,ekr.20040119044414.28,ekr.20040119044414.29,ekr.20040119044414.30,ekr.20040119044414.31,ekr.20040119044414.32,ekr.20040119044414.33,ekr.20040119044414.34,ekr.20040119044414.35,ekr.20040119044414.36,ekr.20040119044414.37,ekr.20040119044414.38,ekr.20040119044414.39,ekr.20040119044414.40,ekr.20040119044414.41,ekr.20040119064609,ekr.20040119064609.1,ekr.20040119064609.2,ekr.20040119044414.42,ekr.20040119044414.43,ekr.20040119044414.45,ekr.20040119044414.46"><vh>@file mod_http.py</vh>
<v t="ekr.20040119102021.3"><vh>&lt;&lt; how to use this plugin &gt;&gt;</vh></v>
<v t="ekr.20040119044414.3"><vh>&lt;&lt; imports &gt;&gt;</vh></v>
<v t="ekr.20040119044414.5"><vh>class delayedSocketStream</vh>
<v t="ekr.20040119044414.6"><vh>__init__</vh></v>
<v t="ekr.20040119044414.7"><vh>write</vh></v>
<v t="ekr.20040119044414.8"><vh>initiate_sending</vh></v>
<v t="ekr.20040119044414.9"><vh>handle_read</vh></v>
<v t="ekr.20040119044414.10"><vh>writable</vh></v>
</v>
<v t="ekr.20040119044414.11"><vh>class nodeNotFound</vh></v>
<v t="ekr.20040119044414.12"><vh>class escaped_StringIO</vh>
<v t="ekr.20040119044414.13"><vh>write_escaped</vh></v>
</v>
<v t="ekr.20040119044414.14"><vh>class RequestHandler</vh>
<v t="ekr.20040119044414.17"><vh>__init__</vh></v>
<v t="ekr.20040119044414.15"><vh>copyfile</vh></v>
<v t="ekr.20040119044414.16"><vh>log_message</vh></v>
<v t="ekr.20040119044414.18"><vh>collect_incoming_data</vh></v>
<v t="ekr.20040119044414.19"><vh>prepare_POST</vh></v>
<v t="ekr.20040119044414.20"><vh>handle_post_data</vh></v>
<v t="ekr.20040119044414.21"><vh>Leo specific code</vh>
<v t="ekr.20040119044414.22"><vh>add_leo_links</vh></v>
<v t="ekr.20040119044414.23"><vh>create_href</vh></v>
<v t="ekr.20040119044414.24"><vh>create_leo_reference</vh></v>
<v t="ekr.20040119044414.25"><vh>format_leo_node</vh></v>
<v t="ekr.20040119044414.26"><vh>get_leo_nameparts</vh></v>
<v t="ekr.20040119044414.27"><vh>get_leo_node</vh></v>
<v t="ekr.20040119044414.28"><vh>get_leo_windowlist</vh></v>
<v t="ekr.20040119044414.29"><vh>write_path</vh></v>
<v t="ekr.20040119044414.30"><vh>send_head</vh></v>
<v t="ekr.20040119044414.31"><vh>split_leo_path</vh></v>
</v>
<v t="ekr.20040119044414.32"><vh>do_GET</vh></v>
<v t="ekr.20040119044414.33"><vh>do_POST</vh></v>
<v t="ekr.20040119044414.34"><vh>query</vh></v>
<v t="ekr.20040119044414.35"><vh>handle_data</vh></v>
<v t="ekr.20040119044414.36"><vh>handle_request_line</vh></v>
<v t="ekr.20040119044414.37"><vh>finish</vh></v>
</v>
<v t="ekr.20040119044414.38"><vh>class Server</vh>
<v t="ekr.20040119044414.39"><vh>__init__</vh></v>
<v t="ekr.20040119044414.40"><vh>handle_accept</vh></v>
</v>
<v t="ekr.20040119044414.41" a="M"><vh>poll</vh>
<v t="ekr.20040119064609"><vh>&lt;&lt; try r, w, e = select.select &gt;&gt;</vh></v>
<v t="ekr.20040119064609.1"><vh>&lt;&lt; asyncore.read(map.get(fd)) &gt;&gt;</vh></v>
<v t="ekr.20040119064609.2"><vh>&lt;&lt; asyncore.write(map.get(fd)) &gt;&gt;</vh></v>
</v>
<v t="ekr.20040119044414.42"><vh>loop</vh></v>
<v t="ekr.20040119044414.43"><vh>plugin_wrapper</vh></v>
<v t="ekr.20040119044414.44" a="E"><vh>asynchore_overrides</vh>
<v t="ekr.20040119044414.45"><vh>a_read</vh></v>
</v>
<v t="ekr.20040119044414.46"><vh>applyConfiguration</vh></v>
</v>
<v t="ekr.20040119044414.48" tnodeList="ekr.20040119044414.48"><vh>@file mod_http.ini</vh></v>
</v>
<v t="ekr.20040127111517" tnodeList="ekr.20040127111517,ekr.20040127111023,ekr.20040127111023.1,ekr.20040127111023.2,ekr.20040127111023.3,ekr.20040127111023.4,ekr.20040127113621.5,ekr.20040127120834,ekr.20040127113621.6,ekr.20040127113621.7,ekr.20040127113621.8,ekr.20040127113621.9,ekr.20040127113621.10,ekr.20040127114616"><vh>@file-noref newButtons.py</vh>
<v t="ekr.20040127111023"><vh>Helper classes</vh>
<v t="ekr.20040127111023.1"><vh>class FlatOptionMenu</vh></v>
<v t="ekr.20040127111023.2"><vh>class Node</vh></v>
<v t="ekr.20040127111023.3"><vh>class NodeAdder</vh></v>
<v t="ekr.20040127111023.4" a="E"><vh>class Helper</vh></v>
</v>
<v t="ekr.20040127113621.5" a="E"><vh>Modifiable classes to add buttons</vh>
<v t="ekr.20040127120834"><vh>body text used by AddTestModule &amp; AddTestClass</vh></v>
<v t="ekr.20040127113621.6" a="E"><vh>class AddTestModule</vh></v>
<v t="ekr.20040127113621.7"><vh>class AddTestClass</vh></v>
<v t="ekr.20040127113621.8"><vh>class AddTestMethod</vh></v>
<v t="ekr.20040127113621.9"><vh>class AddClass</vh></v>
<v t="ekr.20040127113621.10"><vh>class AddClassMethod</vh></v>
</v>
<v t="ekr.20040127114616"><vh>main code</vh></v>
</v>
<v t="ekr.20040201060959" tnodeList="ekr.20040201060959"><vh>@file status_line.py</vh></v>
<v t="ekr.20040211080148" tnodeList="ekr.20040211080148,ekr.20040211080148.1,ekr.20040211080148.2,ekr.20040211080148.3,ekr.20040211080148.4,ekr.20040211080148.5,ekr.20040211080148.6"><vh>@file hoist.py</vh>
<v t="ekr.20040211080148.1"><vh>class HoistButtons</vh>
<v t="ekr.20040211080148.2"><vh>_getSizer</vh></v>
<v t="ekr.20040211080148.3"><vh>addWidgets</vh></v>
<v t="ekr.20040211080148.4"><vh>doHoistOn</vh></v>
<v t="ekr.20040211080148.5"><vh>doHoistOff</vh></v>
<v t="ekr.20040211080148.6"><vh>onIdle</vh></v>
</v>
</v>
</v>
<v t="ekr.20040205071616"><vh>mnplugins.py</vh>
<v t="ekr.20040205071616.1"><vh>mnstamp</vh></v>
<v t="ekr.20040205071616.2"><vh>mnOKstamp</vh></v>
<v t="ekr.20040205071616.3"><vh>onStart</vh></v>
<v t="ekr.20040205071616.4"><vh>setHeadOK</vh></v>
<v t="ekr.20040205071616.5"><vh>insertBodystamp</vh></v>
<v t="ekr.20040205071616.6"><vh>is_subnodesOK</vh></v>
<v t="ekr.20040205071616.7"><vh>onRclick</vh></v>
<v t="ekr.20040205071616.8"><vh>insertOKcmd</vh></v>
<v t="ekr.20040205071616.9"><vh>insertUser</vh></v>
<v t="ekr.20040205071616.10"><vh>create_UserMenu</vh></v>
</v>
<v t="edream.120603093808" a="M" tnodeList="edream.120603093808"><vh>@file pluginsManager.txt</vh></v>
</vnodes>
<tnodes>
<t tx="edream.031216103123">@nocolor

http://sourceforge.net/forum/message.php?msg_id=2336153
By: dsalomoni

- redefine_put.py:

Traceback (most recent call last):
  File "/user/davides/Software/leo-4.1-rc1/src/leoGlobals.py", line 1977, in
doHook
    return app.hookFunction(tag,keywords)
  File "/user/davides/Software/leo-4.1-rc1/src/leoPlugins.py", line 27,
in doPlugins
    return doHandlersForTag(tag,keywords)
  File "/user/davides/Software/leo-4.1-rc1/src/leoPlugins.py", line 94,
in doHandlersForTag
    ret = handle_fn(tag,keywords)
  File "/user/davides/Software/leo-4.1-rc1/plugins/redefine_put.py", line 22,
in onStart
    funcToMethod(newPut,leoFrame.LeoFrame,"put")
AttributeError: 'module' object has no attribute 'LeoFrame'

** Changed LeoFrame to leoTkinterLog

- trace_gc.py:

Traceback (most recent call last):
  File "/user/davides/Software/leo-4.1-rc1/src/leoGlobals.py", line 1977, in
doHook
    return app.hookFunction(tag,keywords)
  File "/user/davides/Software/leo-4.1-rc1/src/leoPlugins.py", line 27,
in doPlugins
    return doHandlersForTag(tag,keywords)
  File "/user/davides/Software/leo-4.1-rc1/src/leoPlugins.py", line 94,
in doHandlersForTag
    ret = handle_fn(tag,keywords)
  File "/user/davides/Software/leo-4.1-rc1/plugins/trace_gc.py", line 17, in
printIdleGC
    global count ; count += 1
NameError: global name 'count' is not defined

** Used gcCount (in plugin) rather than count in leoGlobals.py.</t>
<t tx="edream.031217094146"></t>
<t tx="edream.031217101015"># These are experimental scripts.

@ignore</t>
<t tx="edream.031217101015.1"></t>
<t tx="edream.110203113231">@nocolor</t>
<t tx="edream.110203113231.1">Updated color_markup.py to use c.body.bodyCtrl.</t>
<t tx="edream.110203113231.2">- Made open_with.py gui-independent by calling app.gui dialog routines.

- Updated nav_buttons.py to use new tkinter class:
	from leoTkinterDialog import tkinterListBoxDialog</t>
<t tx="edream.110203113231.3">@nocolor

This file contains code for all plugins distributed with Leo.</t>
<t tx="edream.110203113231.4">@nocolor

What is a plugin?

A plugin is a .py file that appears in Leo's plugin subdirectory. Leo tries to
import all such files while starting up. This is done at "start1" time, that
is, in the call to doHook("start1") in the run function in leo.py. Plugins
exist to define "hook code".

What is hook code?

Leo automatically calls hook code at various times during Leo's execution.
Typical hooks are:

- "start2", called at the end of Leo's startup process,
- "command1", called before executing any of Leo's commands
- "idle", called at Tk's idle time, when nothing else is happening,

See the documentation for hooks in this file for full details.

N.B. Plugins can use "start2" hooks to override any of Leo's classes. See
"Overriding functions, methods &amp; classes" in leoPlugins.leo for several
examples of how to do this.

How do plugins work?

Plugins register themselves when Leo imports them using the following code,
which should appear as the outer level of the .py file:

@color

"""A description of this plugin"""

registerHandler("xxx", onXXX)
__version__ = "1.2"
plugin_signon(__name__)
	
@nocolor

Line by line:

1) """A description of this plugin"""

This is a Python doc string describing the plugin. This string becomes the
value of the __name__ attribute for the module (.py file).

2) registerHandler("xxx", onXXX)

This line registers a handler called onXXX for the hook called "xxx". See the
documentation for hooks for a complete list of hook names that you can use
instead of "xxx". onXXX is the name of a function or method, presumably defined
in the plugin file, that Leo will call at "xxx" time. For example:

registerHandler("idle",onIdle)

will cause Leo to call the onIdle function at "idle" time.

You can pass a list of hook names as the first argument to registerHandler. For
example:

registerHandler(("bodykey1","bodykey2","headkey1","headkey2"), onKey)

3) __version__ = "1.2"

This assigns a version attribute to module. At present this attribute is used
by the plugin code that creates Leo's Plugins menu.

4) plugin_signon(__name__)

This line increases the count of loaded modules. The present code for
plugin_signon does not actually print separate signons--it seems to verbose.

About hook handlers

See the "About hooks" section of leoPlugins.leo for full documentation about
how to write hook handler routines, like onXXX or onKey in the examples above.
Basically, each hook should have this pattern:
	
@color

def onXXX (tag,keywords):
	c = keywords.get("c")
	otherKeyword = keywords.get("otherKeyword")
	&lt;&lt; do something with c and otherKeyword, etc. &gt;&gt;
	
@nocolor

In other words, keywords is a Python dictionary containing the keyword
arguments passed to the hook handler. See the See the "About hooks" section of
leoPlugins.leo for a list of the keywords passed to each hook handler.

The tag is the name of the hook. For example, tag would one of
"bodykey1","bodykey2","headkey1","headkey2", for the onKey hook handler in the
example above.

What's next?

It's one thing to know how to create a plugin. It's another to know how to
actually change Leo. Obviously, some study is needed. The place to start your
study is LeoPy.leo. In particular, study very carefully the section called
"Overview of code". Leo is a highly modular program, and Python is ideally
suited to this style of programming.</t>
<t tx="edream.110203113231.5">@nocolor

Scripting is fully documented in Leo's Users Guide, and the following should be enough to get you started:

@color

top() # The commander of the top (current) windows.
top().rootVnode() # The root vnode of the outline.
top().currentVnode() # The presently selected vnode.

@nocolor

If v is any vnode:
	
@color

v.headString() # is the headline of v.
v.bodyString() # is the body of v.
v.threadNext() # is node after v in outline order.

@nocolor

For example, this prints every headline of an outline:
	
@color

v = top().rootVnode()
while v:
	print v.headString()
	v = v.threadNext()
</t>
<t tx="edream.110203113231.6">At startup time Leo looks all files of the form mod_*.py in the plugins
directory. Leo assumes that these files are "plugins" containing Python modules
that customizes Leo's operation. Leo attempts to import each file.

Each module should register routines that are called at various times during
execution. Such times are identified by strings known as "tags". The code in in
one or more plugins corresponding to each tag are known as the "hook" routines
for that tag. Leo catches exceptions (including syntax errors) in hook
routines, so it is safe to hack away on this code.

Leo passes two argument to all hook routines: the tag and a keywords dictionary
containing additional information. For example, keywords["label"] indicates the
kind of command for "command1" and "command2" hooks.

For some hooks, returning anything other than None "overrides" Leo's default
action. Hooks have full access to all of Leo's source code. Just import the
relevant file. For example, top() returns the commander for the topmost Leo
window.

The following table summarizes the arguments passed to hooks: ( Overrides is
"yes" if returning anything other than None overrides Leo's normal command or
event processing.)

tag argument                                              keys in keywords
(hook name)  overrides       when called                  dictionary argument
---------    ---------       -----------                  -------------------
"bodyclick1"   yes      before normal click in body       c,v,event 
"bodyclick2"            after  normal click in body       c,v,event 
"bodydclick1"  yes      before double click in body       c,v,event 
"bodydclick2"           after  double click in body       c,v,event 
"bodykey1"     yes      before body keystrokes            c,v,ch,oldSel,undoType
"bodykey2"              after  body keystrokes            c,v,ch,oldSel,undoType
"bodyrclick1"  yes      before right click in body        c,v,event 
"bodyrclick2"           after  right click in body        c,v,event 
"boxclick1"    yes      before click in +- box            c,v,event 
"boxclick2"             after  click in +- box            c,v,event 
"command1"     yes      before each command               c,v,label (note 2)
"command2"              after  each command               c,v,label (note 2)
"drag1"        yes      before start of drag              c,v,event 
"drag2"                 after  start of drag              c,v,event 
"dragging1"    yes      before continuing to drag         c,v,event 
"dragging2"             after  continuing to drag         c,v,event 
"end1"                  start of app.quit()
"enddrag1"     yes      before end of drag                c,v,event 
"enddrag2"              after  end of drag                c,v,event 
"headkey1"     yes      before headline keystrokes        c,v,ch
"headkey2"              after  headline keystrokes        c,v,ch
"headclick1"   yes      before normal click in headline   c,v,event 
"headclick2"            after  normal click in headline   c,v,event 
"headrclick1"  yes      before right click in headline    c,v,event 
"headrclick2"           after  right click in headline    c,v,event 
"hypercclick1" yes      before control click in hyperlink c,v,event 
"hypercclick2"          after  control click in hyperlink c,v,event 
"hyperenter1"  yes      before entering hyperlink         c,v,event 
"hyperenter2"           after  entering hyperlink         c,v,event 
"hyperleave1"  yes      before leaving  hyperlink         c,v,event 
"hyperleave2"           after  leaving  hyperlink         c,v,event 
"iconclick1"   yes      before single click in icon box   c,v,event 
"iconclick2"            after  single click in icon box   c,v,event 
"iconrclick1"  yes      before right click in icon box    c,v,event 
"iconrclick2"           after  right click in icon box    c,v,event 
"icondclick1"  yes      before double click in icon box   c,v,event 
"icondclick2"           after  double click in icon box   c,v,event 
"idle"                  periodically (at idle time)       c,v
"menu1"        yes      before creating menus             c,v (note 3)
"menu2"        yes      before updating menus             c,v
"new"          no       during New command                old_c,new_c
"open1"        yes      before opening any file           old_c,new_c,fileName (note 4)
"open2"                 after  opening any file           old_c,new_c,fileName (note 4)
"openwith1"    yes      before Open With command          c,v,openType,arg,ext
"openwith2"             after  Open With command          c,v,openType,arg,ext
"recentfiles1" yes      before Recent Files command       c,v,fileName,closeFlag
"recentfiles2"          after  Recent Files command       c,v,fileName,closeFlag
"save1"        yes      before any Save command           c,v,fileName
"save2"                 after  any Save command           c,v,fileName
"select1"      yes      before selecting a vnode          c,new_v,old_v
"select2"               after  selecting a vnode          c,new_v,old_v
"start1"       no       after app.finishCreate()
"start2"                after opening first Leo window    c,v,fileName
"unselect1"    yes      before unselecting a vnode        c,new_v,old_v 
"unselect2"             after  unselecting a vnode        c,old_v,old_v 
"@url1"        yes      before double-click @url node     c,v (note 5)
"@url2"                 after  double-click @url node     c,v (note 5)

The following hooks are a new breed of hook, called "stub hooks". Conceptually,
these hooks are like calls to stub routines that can be filled in by code in
plugins.

tag argument                                                   keys in keywords
(hook name)             overrides    when called               dictionary argument
---------               ---------    -----------               -------------------

"create-optional-menus"  no          (note 8)                  (note 8)

"draw-outine-box"        yes         start of drawBox          tree,v,x,y (note 6)
"draw-outline-icon"      yes         start of tree.drawIcon    tree,v,x,y (note 6)
"draw-outline-node"      yes         start of tree.drawNode    tree,v,x,y (note 6)
"draw-outline-text-box"  yes         start of tree.drawText    tree,v,x,y (note 6)
"draw-sub-outline"       yes         start of tree.drawTree    tree,v,x,y,h,level (note 6)
"redraw-entire-outline"  yes         start of tree.redraw      c (note 6)

"color-optional-markup"  yes *       (note 7)                  colorer,v (note 7)
"init-color-markup"      no          (note 7)                  colorer,v,s,i,j,colortag (note 7)

"new"                    no          start of New command      old_c,new_c (note 9)

"scan-directives"        no          in scanDirectives         c,v,s,old_dict,dict,pluginsList (note 10)

Notes:

(1) "activate" and "deactivate" hooks: These have been removed because they do
not work as expected.

(2) "commands" hooks: The label entry in the keywords dict contains the
"canonicalized" form of the command, that is, the lowercase name of the command
with all non-alphabetic characters removed.

Commands hooks now set the label for undo and redo commands "undo" and "redo"
rather than "cantundo" and "cantredo".

(3) "menu1" hook: Setting app().realMenuNameDict in this hook is an easy way of
translating menu names to other languages. Note: the "new" names created this
way affect only the actual spelling of the menu items, they do _not_ affect how
you specify shortcuts in leoConfig.txt, nor do they affect the "official"
command names passed in app().commandName. For example, suppose you set
app().realMenuNameDict["Open..."] = "Ouvre".

(4) "open1" and "open2" hooks: These are called with a keywords dict containing
the following entries:

old_c: The commander of the previously open window.
new_c: The commander of the newly opened window.
fileName: The name of the file being opened.

You can use old_c.currentVnode() and new_c.currentVnode() to get the current
vnode in the old and new windows.

Leo calls the "open1" and "open2" hooks only if the file is already open.
Leo will also call the "open1" and "open2" hooks if:
a) a file is opened using the Recent Files menu and
b) the file is not already open.

(5) "@url1" and "@url2" hooks are only executed if "icondclick1" hook returns
None.

(6) These stub hooks allow plugins to revise or completely replace how Leo
draws outlines. For example, you could change tree.drawIcon to add additional
icons. These stub hooks are really methods of the leoTree class, with the
"tree" keyword corresponding to the "self" parameter. These stub hooks are
called at the beginning of the indicated method. See the method themselves for
a description of the paramters.

(7) These stub hooks allow plugins to parse and handle markup withing doc
parts, comments and Python """ strings. Note that these hooks are _not_ called
in Python ''' strings. See the color_markup plugin for a complete example of
how to use these hooks.

(8) The "create-optional-menus" stub hook is called when Leo is creating menus,
at the place at which creating new menus is appropriate. Therefore, this hook
need only create new menus in the correct order, without worrying about the
placement of the menus in the menu bar. See the plugins_menu and scripts_menu
plugins for examples of how to use this hook. Leo now executes hooks in
alphabetical order, so that the Plugins menu will be created before the Scripts
menu.

(9) The "new" stub hook is called at the beginning of the code that implements
the New command. This provides a much easier way of recognizing when Leo is
about to create a new Leo window.

(10) The "scan-directives" stub hooks is called inside the scanDirectives
global function. The dictionary returned by scanDirectives now contains an item
whose key is "pluginsList". The value of this item is a list of tuples
(d,v,s,k) where:

- d is the spelling of the @directive, without the leading @.
- v is the vnode containing the directive, _not_ the original vnode.
- s[k:] is a string containing whatever follows the @directive. k has already
been moved past any whitespace that follows the @directive.

See the add_directives plugins directive for a complete example of how to use
the "scan-directives" stub hook.</t>
<t tx="edream.110203113231.7">Naively using hooks can expose you and your .leo files to malicious attacks.

** Hooks should never blindly execute Python scripts in .leo files.

It is safe to import and execute code from Leo itself, provided that you got Leo from Leo's SourceForge site.</t>
<t tx="edream.110203113231.8">@color
@ WARNING ***** Using the following routine exposes you malicious code in .leo files! *****

Do not EVER use code that blindly executes code in .leo files!
Someone could send you malicious code embedded in the .leo file.

WARNING 1: Changing "@onloadpythonscript" to something else will NOT protect
           you if you EVER share either your files with anyone else.

WARNING 2: Replacing exec by rexec below provides NO additional protection!
           A malicious rexec script could trash your .leo file in subtle ways.
@c
if 0: # WRONG: This blindly execute scripts found in an .leo file! NEVER DO THIS!
	def onLoadFile():
		v = top().rootVnode()
		while v:
			h = v.headString().lower()
			if match_word(h,0,"@onloadpythonscript"):
				s = v.bodyString()
				if s and len(s) &gt; 0:
					try: # SECURITY BREACH: s may be malicious!
						exec s + '\n' in {}
					except:
						es_exception()
			v = v.threadNext()</t>
<t tx="edream.110203113231.9"></t>
<t tx="edream.110203113231.10"></t>
<t tx="edream.110203113231.11">@nocolor

Allow different default types for each section.
Create _all_ menus from settings ?

[plugins]

pluginName = 1/0 # enables or disables plugin

# option = type (overrides defaults)

	[types]

__default_type = bool
page_width = int
tab_width = int
default_tangle_directory = string

	use type name in option?
	
	_color: color
	
	_font: font
	_key: keystroke
	_flag: bool
	everything else: bool
	
	bool: checkmark
	color: picker (or use dialog)

[menus]
child = parent</t>
<t tx="edream.110203113231.12"></t>
<t tx="edream.110203113231.13">"""Create a settings menu to replace LeoConfig.leo"""

from leoPlugins import *
from leoGlobals import *

try:  import Tkinter
except: Tkinter = None

import leoApp,leoAtFile,leoTkinterDialog,leoFileCommands,leoFrame,leoNodes

if Tkinter and 0: # Register the handlers...

	settingsMenu = None

	@others
	
	# registerHandler("start1",onAfterFinishCreate)
	registerHandler("create-optional-menus",createSettingsMenu)

	__version__ = "0.1"
	plugin_signon(__name__)</t>
<t tx="edream.110203113231.14">def createSettingsMenu (tag,keywords):

	c = keywords.get("c")
	
	global settingsMenu
	settingsMenu = c.frame.createNewMenu("&amp;Settings")</t>
<t tx="edream.110203113231.15">@ignore
@nocolor

This contains code that I am studying for later use.

@color</t>
<t tx="edream.110203113231.16"></t>
<t tx="edream.110203113231.17">@ignore
@language elisp

@others

(provide 'pymacs)</t>
<t tx="edream.110203113231.18">;;; Interface between Emacs Lisp and Python - Lisp part.    -*- emacs-lisp -*-
;;; Copyright © 2001, 2002, 2003 Progiciels Bourbeau-Pinard inc.
;;; François Pinard &lt;pinard@iro.umontreal.ca&gt;, 2001.

&lt;&lt; free software stuff &gt;&gt;

;;; See the Pymacs documentation (in `README') for more information.</t>
<t tx="edream.110203113231.19">
;;; This program is free software; you can redistribute it and/or modify
;;; it under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 2, or (at your option)
;;; any later version.
;;;
;;; This program is distributed in the hope that it will be useful,
;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with this program; if not, write to the Free Software Foundation,
;;; Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.</t>
<t tx="edream.110203113231.20">;;; Published functions.</t>
<t tx="edream.110203113231.21"></t>
<t tx="edream.110203113231.22">(defvar pymacs-load-path nil
  "List of additional directories to search for Python modules.
The directories listed will be searched first, in the order given.")</t>
<t tx="edream.110203113231.23">(defvar pymacs-trace-transit '(5000 . 30000)

"Keep the communication buffer growing, for debugging.
When this variable is nil, the `*Pymacs*' communication buffer gets erased
before each communication round-trip.  Setting it to `t' guarantees that
the full communication is saved, which is useful for debugging.
It could also be given as (KEEP . LIMIT): whenever the buffer exceeds LIMIT
bytes, it is reduced to approximately KEEP bytes.")</t>
<t tx="edream.110203113231.24">(defvar pymacs-forget-mutability nil
  "Transmit copies to Python instead of Lisp handles, as much as possible.
When this variable is nil, most mutable objects are transmitted as handles.
This variable is meant to be temporarily rebound to force copies.")</t>
<t tx="edream.110203113231.25">(defvar pymacs-mutable-strings nil
  "Prefer transmitting Lisp strings to Python as handles.
When this variable is nil, strings are transmitted as copies, and the
Python side thus has no way for modifying the original Lisp strings.
This variable is ignored whenever `forget-mutability' is set.")</t>
<t tx="edream.110203113231.26">(defvar pymacs-timeout-at-start 30
  "Maximum reasonable time, in seconds, for starting `pymacs-services'.
A machine should be pretty loaded before one needs to increment this.")</t>
<t tx="edream.110203113231.27">(defvar pymacs-timeout-at-reply 5
  "Expected maximum time, in seconds, to get the first line of a reply.
The status of `pymacs-services' is checked at every such timeout.")</t>
<t tx="edream.110203113231.28">(defvar pymacs-timeout-at-line 2
  "Expected maximum time, in seconds, to get another line of a reply.
The status of 'pymacs-services' is checked at every such timeout.")</t>
<t tx="edream.110203113231.29">(defun pymacs-load (module &amp;optional prefix noerror)

  "Import the Python module named MODULE into Emacs.
Each function in the Python module is made available as an Emacs function.
The Lisp name of each function is the concatenation of PREFIX with
the Python name, in which underlines are replaced by dashes.  If PREFIX is
not given, it defaults to MODULE followed by a dash.
If NOERROR is not nil, do not raise error when the module is not found."

  (interactive
   (let* ((module (read-string "Python module? "))
	  (default (concat (car (last (split-string module "\\."))) "-"))
	  (prefix (read-string (format "Prefix? [%s] " default)
			       nil nil default)))
     (list module prefix)))
  (message "Pymacs loading %s..." module)
  (let ((lisp-code (pymacs-call "pymacs_load_helper" module prefix)))
    (cond (lisp-code (let ((result (eval lisp-code)))
		       (message "Pymacs loading %s...done" module)
		       result))
	  (noerror (message "Pymacs loading %s...failed" module) nil)
	  (t (error "Pymacs loading %s...failed" module)))))</t>
<t tx="edream.110203113231.30">(defun pymacs-eval (text)

  "Compile TEXT as a Python expression, and return its value."
 
  (interactive "sPython expression? ")
  (let ((value (pymacs-call "eval" text)))
    (when (interactive-p)
      (message "%S" value))
    value))</t>
<t tx="edream.110203113231.31">(defun pymacs-exec (text)

"Compile and execute TEXT as a sequence of Python statements.
This functionality is experimental, and does not appear to be useful."

  (interactive "sPython statements? ")
  (let ((value (pymacs-serve-until-reply
		`(progn (princ "exec ") (prin1 ,text)))))
    (when (interactive-p)
      (message "%S" value))
    value))</t>
<t tx="edream.110203113231.32">(defun pymacs-call (function &amp;rest arguments)

"Return the result of calling a Python function FUNCTION over ARGUMENTS.
FUNCTION is a string denoting the Python function, ARGUMENTS are separate
Lisp expressions, one per argument.  Immutable Lisp constants are converted
to Python equivalents, other structures are converted into Lisp handles."

  (pymacs-serve-until-reply `(pymacs-print-for-apply ',function ',arguments)))</t>
<t tx="edream.110203113231.33">(defun pymacs-apply (function arguments)

"Return the result of calling a Python function FUNCTION over ARGUMENTS.
FUNCTION is a string denoting the Python function, ARGUMENTS is a list of
Lisp expressions.  Immutable Lisp constants are converted to Python
equivalents, other structures are converted into Lisp handles."

  (pymacs-serve-until-reply `(pymacs-print-for-apply ',function ',arguments)))</t>
<t tx="edream.110203113231.34">;;; Integration details.</t>
<t tx="edream.110203113231.35">;; Python functions and modules should ideally look like Lisp functions and
;; modules.  This page tries to increase the integration seamlessness.

(defadvice documentation (around pymacs-ad-documentation activate)
  ;; Integration of doc-strings.
  (let* ((reference (pymacs-python-reference function))
	 (python-doc (when reference
		       (pymacs-eval (format "doc_string(%s)" reference)))))
    (if (or reference python-doc)
	(setq ad-return-value
	      (concat
	       "It interfaces to a Python function.\n\n"
	       (when python-doc
		 (if raw python-doc (substitute-command-keys python-doc)))))
      ad-do-it)))
</t>
<t tx="edream.110203113231.36">(defun pymacs-python-reference (object)
  ;; Return the text reference of a Python object if possible, else nil.
  (when (functionp object)
    (let* ((definition (indirect-function object))
	   (body (and (pymacs-proper-list-p definition)
		      (&gt; (length definition) 2)
		      (eq (car definition) 'lambda)
		      (cddr definition))))
      (when (and body (listp (car body)) (eq (caar body) 'interactive))
	;; Skip the interactive specification of a function.
	(setq body (cdr body)))
      (when (and body
		 ;; Advised functions start with a string.
		 (not (stringp (car body)))
		 ;; Python trampolines hold exactly one expression.
		 (= (length body) 1))
	(let ((expression (car body)))
	  ;; EXPRESSION might now hold something like:
	  ;;    (pymacs-apply (quote (pymacs-python . N)) ARGUMENT-LIST)
	  (when (and (pymacs-proper-list-p expression)
		     (= (length expression) 3)
		     (eq (car expression) 'pymacs-apply)
		     (eq (car (cadr expression)) 'quote))
	    (setq object (cadr (cadr expression))))))))
  (when (eq (car-safe object) 'pymacs-python)
    (format "python[%d]" (cdr object))))</t>
<t tx="edream.110203113231.37">;; The following functions are experimental -- they are not satisfactory yet.

</t>
<t tx="edream.110203113231.38">(defun pymacs-file-handler (operation &amp;rest arguments)
  ;; Integration of load-file, autoload, etc.
  ;; Emacs might want the contents of some `MODULE.el' which does not exist,
  ;; while there is a `MODULE.py' or `MODULE.pyc' file in the same directory.
  ;; The goal is to generate a virtual contents for this `MODULE.el' file, as
  ;; a set of Lisp trampoline functions to the Python module functions.
  ;; Python modules can then be loaded or autoloaded as if they were Lisp.
  ;(message "** %S %S" operation arguments)
  (cond ((and (eq operation 'file-readable-p)
	      (let ((module (substring (car arguments) 0 -3)))
		(or (pymacs-file-force operation arguments)
		    (file-readable-p (concat module ".py"))
		    (file-readable-p (concat module ".pyc"))))))
	((and (eq operation 'load)
	      (not (pymacs-file-force
		    'file-readable-p (list (car arguments))))
	      (file-readable-p (car arguments)))
	 (let ((lisp-code (pymacs-call "pymacs_load_helper"
				       (substring (car arguments) 0 -3)
				       nil)))
	   (unless lisp-code
	     (error "Python import error"))
	   (eval lisp-code)))
	((and (eq operation 'insert-file-contents)
	      (not (pymacs-file-force
		    'file-readable-p (list (car arguments))))
	      (file-readable-p (car arguments)))
	 (let ((lisp-code (pymacs-call "pymacs_load_helper"
				       (substring (car arguments) 0 -3)
				       nil)))
	   (unless lisp-code
	     (error "Python import error"))
	   (insert (prin1-to-string lisp-code))))
	(t (pymacs-file-force operation arguments))))</t>
<t tx="edream.110203113231.39">(defun pymacs-file-force (operation arguments)
  ;; Bypass the file handler.
  (let ((inhibit-file-name-handlers
	 (cons 'pymacs-file-handler
	       (and (eq inhibit-file-name-operation operation)
		    inhibit-file-name-handlers)))
	(inhibit-file-name-operation operation))
    (apply operation arguments)))
	
;(add-to-list 'file-name-handler-alist '("\\.el\\'" . pymacs-file-handler))</t>
<t tx="edream.110203113231.40">;;; Gargabe collection of Python IDs.

;; Python objects which have no Lisp representation are allocated on the
;; Python side as `python[INDEX]', and INDEX is transmitted to Emacs, with
;; the value to use on the Lisp side for it.  Whenever Lisp does not need a
;; Python object anymore, it should be freed on the Python side.  The
;; following variables and functions are meant to fill this duty.

</t>
<t tx="edream.110203113231.41"></t>
<t tx="edream.110203113231.42">(defvar pymacs-use-hash-tables nil
  "Automatically set to t if hash tables are available.")</t>
<t tx="edream.110203113231.43">(defvar pymacs-used-ids nil
  "List of received IDs, currently allocated on the Python side.")</t>
<t tx="edream.110203113231.44">(defvar pymacs-weak-hash nil
  "Weak hash table, meant to find out which IDs are still needed.")</t>
<t tx="edream.110203113231.45">(defvar pymacs-gc-wanted nil
  "Flag if it is time to clean up unused IDs on the Python side.")</t>
<t tx="edream.110203113231.46">(defvar pymacs-gc-running nil
  "Flag telling that a Pymacs garbage collection is in progress.")</t>
<t tx="edream.110203113231.47">(defvar pymacs-gc-timer nil
  "Timer to trigger Pymacs garbage collection at regular time intervals.
The timer is used only if `post-gc-hook' is not available.")</t>
<t tx="edream.110203113231.48">(defun pymacs-schedule-gc ()
  (unless pymacs-gc-running
    (setq pymacs-gc-wanted t)))</t>
<t tx="edream.110203113231.49">(defun pymacs-garbage-collect ()
  ;; Clean up unused IDs on the Python side.
  (when pymacs-use-hash-tables
    (let ((pymacs-gc-running t)
	  (pymacs-forget-mutability t)
	  (ids pymacs-used-ids)
	  used-ids unused-ids)
      (while ids
	(let ((id (car ids)))
	  (setq ids (cdr ids))
	  (if (gethash id pymacs-weak-hash)
	      (setq used-ids (cons id used-ids))
	    (setq unused-ids (cons id unused-ids)))))
      ;;(message "** pymacs-garbage-collect %d %d"
      ;;         (length used-ids) (length unused-ids))
      (setq pymacs-used-ids used-ids
	    pymacs-gc-wanted nil)
      (when unused-ids
	(pymacs-apply "free_python" unused-ids)))))</t>
<t tx="edream.110203113231.50">(defun pymacs-defuns (arguments)
  ;; Take one argument, a list holding a number of items divisible by 3.  The
  ;; first argument is an INDEX, the second is a NAME, the third is the
  ;; INTERACTION specification, and so forth.  Register Python INDEX with a
  ;; function with that NAME and INTERACTION on the Lisp side.  The strange
  ;; calling convention is to minimise quoting at call time.
  (while (&gt;= (length arguments) 3)
    (let ((index (nth 0 arguments))
	  (name (nth 1 arguments))
	  (interaction (nth 2 arguments)))
      (fset name (pymacs-defun index interaction))
      (setq arguments (nthcdr 3 arguments)))))</t>
<t tx="edream.110203113231.51">(defun pymacs-defun (index interaction)
  ;; Register INDEX on the Lisp side with a Python object that is a function,
  ;; and return a lambda form calling that function.  If the INTERACTION
  ;; specification is nil, the function is not interactive.  Otherwise, the
  ;; function is interactive, INTERACTION is then either a string, or the
  ;; index of an argument-less Python function returning the argument list.
  (let ((object (pymacs-python index)))
    (cond ((null interaction)
	   `(lambda (&amp;rest arguments)
	      (pymacs-apply ',object arguments)))
	  ((stringp interaction)
	   `(lambda (&amp;rest arguments)
	      (interactive ,interaction)
	      (pymacs-apply ',object arguments)))
	  (t `(lambda (&amp;rest arguments)
		(interactive (pymacs-call ',(pymacs-python interaction)))
		(pymacs-apply ',object arguments))))))</t>
<t tx="edream.110203113231.52">(defun pymacs-python (index)
  ;; Register on the Lisp side a Python object having INDEX, and return it.
  ;; The result is meant to be recognised specially by `print-for-eval', and
  ;; in the function position by `print-for-apply'.
  (let ((object (cons 'pymacs-python index)))
    (when pymacs-use-hash-tables
      (puthash index object pymacs-weak-hash)
      (setq pymacs-used-ids (cons index pymacs-used-ids)))
    object))</t>
<t tx="edream.110203113231.53">;;; Generating Python code.

;; Many Lisp expressions cannot fully be represented in Python, at least
;; because the object is mutable on the Lisp side.  Such objects are allocated
;; somewhere into a vector of handles, and the handle index is used for
;; communication instead of the expression itself.


</t>
<t tx="edream.110203113231.54">(defvar pymacs-lisp nil
  "Vector of handles to hold transmitted expressions.")</t>
<t tx="edream.110203113231.55">(defvar pymacs-freed-list nil
  "List of unallocated indices in Lisp.")</t>
<t tx="edream.110203113231.56">;; When the Python CG is done with a Lisp object, a communication occurs so to
;; free the object on the Lisp side as well.

(defun pymacs-allocate-lisp (expression)
  ;; This function allocates some handle for an EXPRESSION, and return its
  ;; index.
  (unless pymacs-freed-list
    (let* ((previous pymacs-lisp)
	   (old-size (length previous))
	   (new-size (if (zerop old-size) 100 (+ old-size (/ old-size 2))))
	   (counter new-size))
      (setq pymacs-lisp (make-vector new-size nil))
      (while (&gt; counter 0)
	(setq counter (1- counter))
	(if (&lt; counter old-size)
	    (aset pymacs-lisp counter (aref previous counter))
	  (setq pymacs-freed-list (cons counter pymacs-freed-list))))))
  (let ((index (car pymacs-freed-list)))
    (setq pymacs-freed-list (cdr pymacs-freed-list))
    (aset pymacs-lisp index expression)
    index))</t>
<t tx="edream.110203113231.57">(defun pymacs-free-lisp (&amp;rest indices)
  ;; This function is triggered from Python side for Lisp handles which lost
  ;; their last reference.  These references should be cut on the Lisp side as
  ;; well, or else, the objects will never be garbage-collected.
  (while indices
    (let ((index (car indices)))
      (aset pymacs-lisp index nil)
      (setq pymacs-freed-list (cons index pymacs-freed-list)
	    indices (cdr indices)))))</t>
<t tx="edream.110203113231.58">(defun pymacs-print-for-apply-expanded (function arguments)
  ;; This function acts like `print-for-apply', but produce arguments which
  ;; are expanded copies whenever possible, instead of handles.  Proper lists
  ;; are turned into Python lists, vectors are turned into Python tuples.
  (let ((pymacs-forget-mutability t))
    (pymacs-print-for-apply function arguments)))</t>
<t tx="edream.110203113231.59">(defun pymacs-print-for-apply (function arguments)
  ;; This function prints a Python expression calling FUNCTION, which is a
  ;; string naming a Python function, or a Python reference, over all its
  ;; ARGUMENTS, which are Lisp expressions.
  (let ((separator "")
	argument)
    (if (eq (car-safe function) 'pymacs-python)
	(princ (format "python[%d]" (cdr function)))
      (princ function))
    (princ "(")
    (while arguments
      (setq argument (car arguments)
	    arguments (cdr arguments))
      (princ separator)
      (setq separator ", ")
      (pymacs-print-for-eval argument))
    (princ ")")))</t>
<t tx="edream.110203113231.60">(defun pymacs-print-for-eval (expression)
  ;; This function prints a Python expression out of a Lisp EXPRESSION.
  (let (done)
    (cond ((not expression)
	   (princ "None")
	   (setq done t))
	  ((numberp expression)
	   (princ expression)
	   (setq done t))
	  ((stringp expression)
	   (when (or pymacs-forget-mutability
		     (not pymacs-mutable-strings))
	     (let ((text (copy-sequence expression)))
	       (set-text-properties 0 (length text) nil text)
	       (princ (mapconcat 'identity
				 (split-string (prin1-to-string text) "\n")
				 "\\n")))
	     (setq done t)))
	  ((symbolp expression)
	   (let ((name (symbol-name expression)))
	     ;; The symbol can only be transmitted when in the main oblist.
	     (when (eq expression (intern-soft name))
	       (cond
		((save-match-data
		   (string-match "^[A-Za-z][-A-Za-z0-9]*$" name))
		 (princ "lisp.")
		 (princ (mapconcat 'identity (split-string name "-") "_")))
		(t (princ "lisp[")
		   (prin1 name)
		   (princ "]")))
	       (setq done t))))
	  ((vectorp expression)
	   (when pymacs-forget-mutability
	     (let ((limit (length expression))
		   (counter 0))
	       (princ "(")
	       (while (&lt; counter limit)
		 (unless (zerop counter)
		   (princ ", "))
		 (pymacs-print-for-eval (aref expression counter))
		 (setq counter (1+ counter)))
	       (when (= limit 1)
		 (princ ","))
	       (princ ")")
	       (setq done t))))
	  ((eq (car-safe expression) 'pymacs-python)
	   (princ "python[")
	   (princ (cdr expression))
	   (princ "]")
	   (setq done t))
	  ((pymacs-proper-list-p expression)
	   (when pymacs-forget-mutability
	     (princ "[")
	     (pymacs-print-for-eval (car expression))
	     (while (setq expression (cdr expression))
	       (princ ", ")
	       (pymacs-print-for-eval (car expression)))
	     (princ "]")
	     (setq done t))))
    (unless done
      (let ((class (cond ((vectorp expression) "Vector")
			 ((and pymacs-use-hash-tables
			       (hash-table-p expression))
			  "Table")
			 ((bufferp expression) "Buffer")
			 ((pymacs-proper-list-p expression) "List")
			 (t "Lisp"))))
	(princ class)
	(princ "(")
	(princ (pymacs-allocate-lisp expression))
	(princ ")")))))</t>
<t tx="edream.110203113231.61">;;; Communication protocol.

(defvar pymacs-transit-buffer nil
  "Communication buffer between Emacs and Python.")
  
;; The principle behind the communication protocol is that it is easier to
;; generate than parse, and that each language already has its own parser.

;; So, the Emacs side generates Python text for the Python side to interpret,
;; while the Python side generates Lisp text for the Lisp side to interpret.
;; About nothing but expressions are transmitted, which are evaluated on
;; arrival.  The pseudo `reply' function is meant to signal the final result
;; of a series of exchanges following a request, while the pseudo `error'
;; function is meant to explain why an exchange could not have been completed.

;; The protocol itself is rather simple, and contains human readable text
;; only.  A message starts at the beginning of a line in the communication
;; buffer, either with `&gt;' for the Lisp to Python direction, or `&lt;' for the
;; Python to Lisp direction.  This is followed by a decimal number giving the
;; length of the message text, a TAB character, and the message text itself.
;; Message direction alternates systematically between messages, it never
;; occurs that two successive messages are sent in the same direction.  The
;; first message is received from the Python side, it is `(version VERSION)'.
</t>
<t tx="edream.110203113231.62">(defun pymacs-start-services ()
  ;; This function gets called automatically, as needed.
  (let ((buffer (get-buffer-create "*Pymacs*")))
    (with-current-buffer buffer
      (buffer-disable-undo)
      (save-match-data
	;; Launch the Python helper.
	(let ((process (apply 'start-process "pymacs" buffer "pymacs-services"
			      (mapcar 'expand-file-name pymacs-load-path))))
	  (process-kill-without-query process)
	  ;; Receive the synchronising reply.
	  (while (progn
		   (goto-char (point-min))
		   (not (re-search-forward "&lt;\\([0-9]+\\)\t" nil t)))
	    (unless (accept-process-output process pymacs-timeout-at-start)
	      (error "Pymacs helper did not start within %d seconds."
		     pymacs-timeout-at-start)))
	  (let ((marker (process-mark process))
		(limit-position (+ (match-end 0)
				   (string-to-number (match-string 1)))))
	    (while (&lt; (marker-position marker) limit-position)
	      (unless (accept-process-output process pymacs-timeout-at-start)
		(error "Pymacs helper probably was interrupted at start.")))))
	;; Check that synchronisation occurred.
	(goto-char (match-end 0))
	(let ((reply (read (current-buffer))))
	  (if (and (pymacs-proper-list-p reply)
		   (= (length reply) 2)
		   (eq (car reply) 'pymacs-version))
	      (unless (string-equal (cadr reply) "0.22")
		(error "Pymacs Lisp version is 0.22, Python is %s."
		       (cadr reply)))
	    (error "Pymacs got an invalid initial reply.")))))
    (setq pymacs-use-hash-tables (and (fboundp 'make-hash-table)
				      (fboundp 'gethash)
				      (fboundp 'puthash)))
    (when pymacs-use-hash-tables
      (if pymacs-weak-hash
	  ;; A previous Pymacs session occurred in *this* Emacs session.  Some
	  ;; IDs may hang around, which do not correspond to anything on the
	  ;; Python side.  Python should not recycle such IDs for new objects.
	  (when pymacs-used-ids
	    (let ((pymacs-transit-buffer buffer)
		  (pymacs-forget-mutability t))
	      (pymacs-apply "zombie_python" pymacs-used-ids)))
	(setq pymacs-weak-hash (make-hash-table :weakness 'value)))
      (if (boundp 'post-gc-hook)
	  (add-hook 'post-gc-hook 'pymacs-schedule-gc)
	(setq pymacs-gc-timer (run-at-time 20 20 'pymacs-schedule-gc))))
    ;; If nothing failed, only then declare that Pymacs has started!
    (setq pymacs-transit-buffer buffer)))</t>
<t tx="edream.110203113231.63">(defun pymacs-terminate-services ()
  ;; This function is mainly provided for documentation purposes.
  (interactive)
  (garbage-collect)
  (pymacs-garbage-collect)
  (when (or (not pymacs-used-ids)
	    (yes-or-no-p "\
Killing the helper might create zombie objects.  Kill? "))
    (cond ((boundp 'post-gc-hook)
	   (remove-hook 'post-gc-hook 'pymacs-schedule-gc))
	  ((timerp pymacs-gc-timer)
	   (cancel-timer pymacs-gc-timer)))
    (when pymacs-transit-buffer
      (kill-buffer pymacs-transit-buffer))
    (setq pymacs-gc-running nil
	  pymacs-gc-timer nil
	  pymacs-transit-buffer nil
	  pymacs-lisp nil
	  pymacs-freed-list nil)))</t>
<t tx="edream.110203113231.64">(defun pymacs-reply (expression)
  ;; This pseudo-function returns `(pymacs-reply . EXPRESSION)'.
  ;; It is only used from within the `loop' function on the Python side.
  ;; `serve-until-reply' later recognises this form.
  (cons 'pymacs-reply expression))</t>
<t tx="edream.110203113231.65">(defun pymacs-error (expression)
  ;; This pseudo-function returns `(pymacs-error . EXPRESSION)'.
  ;; It is only used from within the `loop' function on the Python side.
  ;; `serve-until-reply' later recognises this form.
  (cons 'pymacs-error expression))</t>
<t tx="edream.110203113231.66">(defun pymacs-expand (expression)
  ;; This pseudo-function returns `(pymacs-expand . EXPRESSION)'.  It is
  ;; only called from the `loop' function within `Pymacs/pymacs.py'.
  ;; `serve-until-reply' later recognises this form.
  (cons 'pymacs-expand expression))</t>
<t tx="edream.110203113231.67">(defun pymacs-serve-until-reply (inserter)
  ;; This function evals INSERTER to print a Python request.  It sends it to
  ;; the Python helper, and serves all sub-requests coming from the
  ;; Python side, until either a reply or an error is finally received.
  (unless (and pymacs-transit-buffer
	       (buffer-name pymacs-transit-buffer)
	       (get-buffer-process pymacs-transit-buffer))
    (pymacs-start-services))
  (when pymacs-gc-wanted
    (pymacs-garbage-collect))
  (let (done value)
    (while (not done)
      (let* ((text (pymacs-round-trip inserter))
	     (reply (condition-case info
			(eval text)
		      (error (cons 'pymacs-oops (prin1-to-string info))))))
	(cond ((not (consp reply))
	       (setq inserter `(pymacs-print-for-apply 'reply '(,reply))))
	      ((eq 'pymacs-reply (car reply))
	       (setq done t value (cdr reply)))
	      ((eq 'pymacs-error (car reply))
	       (error "Python: %s" (cdr reply)))
	      ((eq 'pymacs-expand (car reply))
	       (setq inserter `(pymacs-print-for-apply-expanded
				'reply '(,(cdr reply)))))
	      ((eq 'pymacs-oops (car reply))
	       (setq inserter `(pymacs-print-for-apply
				'error '(,(cdr reply)))))
	      (t (setq inserter `(pymacs-print-for-apply 'reply '(,reply)))))))
    value))</t>
<t tx="edream.110203113231.68">(defun pymacs-round-trip (inserter)
  ;; This function evals INSERTER to print a Python request.  It sends it to
  ;; the Python helper, awaits for any kind of reply, and returns it.
  (with-current-buffer pymacs-transit-buffer
    ;; Possibly trim the beginning of the transit buffer.
    (cond ((not pymacs-trace-transit)
	   (erase-buffer))
	  ((consp pymacs-trace-transit)
	   (when (&gt; (buffer-size) (cdr pymacs-trace-transit))
	     (let ((cut (- (buffer-size) (car pymacs-trace-transit))))
	       (when (&gt; cut 0)
		 (save-excursion
		   (goto-char cut)
		   (unless (memq (preceding-char) '(0 ?\n))
		     (forward-line 1))
		   (delete-region (point-min) (point))))))))
    ;; Send the request, wait for a reply, and process it.
    (let* ((process (get-buffer-process pymacs-transit-buffer))
	   (status (process-status process))
	   (marker (process-mark process))
	   (moving (= (point) marker))
	   send-position reply-position reply)
      (save-excursion
	(save-match-data
	  ;; Encode request.
	  (setq send-position (marker-position marker))
	  (let ((standard-output marker))
	    (eval inserter))
	  (goto-char marker)
	  (unless (= (preceding-char) ?\n)
	    (princ "\n" marker))
	  ;; Send request text.
	  (goto-char send-position)
	  (insert (format "&gt;%d\t" (- marker send-position)))
	  (setq reply-position (marker-position marker))
	  (process-send-region process send-position marker)
	  ;; Receive reply text.
	  (while (and (eq status 'run)
		      (progn
			(goto-char reply-position)
			(not (re-search-forward "&lt;\\([0-9]+\\)\t" nil t))))
	    (unless (accept-process-output process pymacs-timeout-at-reply)
	      (setq status (process-status process))))
	  (when (eq status 'run)
	    (let ((limit-position (+ (match-end 0)
				     (string-to-number (match-string 1)))))
	      (while (and (eq status 'run)
			  (&lt; (marker-position marker) limit-position))
		(unless (accept-process-output process pymacs-timeout-at-line)
		  (setq status (process-status process))))))
	  ;; Decode reply.
	  (if (not (eq status 'run))
	      (error "Pymacs helper status is `%S'." status)
	    (goto-char (match-end 0))
	    (setq reply (read (current-buffer))))))
      (when (and moving (not pymacs-trace-transit))
	(goto-char marker))
      reply)))</t>
<t tx="edream.110203113231.69">(defun pymacs-proper-list-p (expression)
  ;; Tell if a list is proper, id est, that it is `nil' or ends with `nil'.
  (cond ((not expression))
	((consp expression) (not (cdr (last expression))))))</t>
<t tx="edream.110203113231.70"></t>
<t tx="edream.110203113231.71"></t>
<t tx="edream.110203113231.72">@ignore
@language python

&lt;&lt; version &gt;&gt;

import sys, os, time
import wx    # This module uses the new wx namespace
import wx.html
import images

&lt;&lt; define the tree of demo elements &gt;&gt;

@others

&lt;&lt; overview of demo &gt;&gt;

if __name__ == '__main__':
    main()</t>
<t tx="edream.110203113231.73">#!/bin/env python

#----------------------------------------------------------------------------
# Name:         Main.py
# Purpose:      Testing lots of stuff, controls, window types, etc.
#
# Author:       Robin Dunn
#
# Created:      A long time ago, in a galaxy far, far away...
# RCS-ID:       $Id: leoPlugins.leo,v 1.88 2004/02/17 15:24:33 edream Exp $
# Copyright:    (c) 1999 by Total Control Software
# Licence:      wxWindows license
#----------------------------------------------------------------------------
</t>
<t tx="edream.110203113231.74">_treeList = [
    # new stuff
    ('Recent Additions', [
        'wxScrolledPanel',
        'ShapedWindow',
        'NewNamespace',
        'PopupMenu',
        'AnalogClockWindow',
        'MaskedEditControls',
        'wxTreeListCtrl',
        'wxGrid_MegaExample',
        ]),

    # managed windows == things with a (optional) caption you can close
    ('Base Frames and Dialogs', [
        'wxDialog',
        'wxFrame',
        'wxMDIWindows',
        'wxMiniFrame',
        'wxWizard',
        ]),

    # the common dialogs
    ('Common Dialogs', [
        'wxColourDialog',
        'wxDirDialog',
        'wxFileDialog',
        'wxFindReplaceDialog',
        'wxFontDialog',
        'wxMessageDialog',
        'wxPageSetupDialog',
        'wxPrintDialog',
        'wxProgressDialog',
        'wxSingleChoiceDialog',
        'wxTextEntryDialog',
        ]),

    # dialogs from libraries
    ('More Dialogs', [
        'ErrorDialogs',
        'ImageBrowser',
        'wxMultipleChoiceDialog',
        'wxScrolledMessageDialog',
        ]),

    # core controls
    ('Core Windows/Controls', [
        'PopupMenu',
        'wxButton',
        'wxCheckBox',
        'wxCheckListBox',
        'wxChoice',
        'wxComboBox',
        'wxGauge',
        'wxGenericDirCtrl',
        'wxGrid',
        'wxGrid_MegaExample',
        'wxListBox',
        'wxListCtrl',
        'wxListCtrl_virtual',
        'wxMenu',
        'wxNotebook',
        'wxPopupWindow',
        'wxRadioBox',
        'wxRadioButton',
        'wxSashWindow',
        'wxScrolledWindow',
        'wxSlider',
        'wxSpinButton',
        'wxSpinCtrl',
        'wxSplitterWindow',
        'wxStaticBitmap',
        'wxStaticText',
        'wxStatusBar',
        'wxTextCtrl',
        'wxToggleButton',
        'wxToolBar',
        'wxTreeCtrl',
        'wxValidator',
        ]),

    # controls coming from other librairies
    ('More Windows/Controls', [
        #'wxFloatBar',          deprecated
        #'wxMVCTree',           deprecated
        #'wxRightTextCtrl',     deprecated as we have wxTE_RIGHT now.
        'AnalogClockWindow',
        'ColourSelect',
        'ContextHelp',
        'FancyText',
        'FileBrowseButton',
        'GenericButtons',
        'MaskedEditControls',
        'PyShell',
        'PyCrust',
        'SplitTree',
        'TablePrint',
        'Throbber',
        'wxCalendar',
        'wxCalendarCtrl',
        'wxPyColourChooser',
        'wxDynamicSashWindow',
        'wxEditableListBox',
        'wxEditor',
        'wxHtmlWindow',
        'wxIEHtmlWin',
        'wxIntCtrl',
        'wxLEDNumberCtrl',
        'wxMimeTypesManager',
        'wxMultiSash',
        'wxPopupControl',
        'wxStyledTextCtrl_1',
        'wxStyledTextCtrl_2',
        'wxTimeCtrl',
        'wxTreeListCtrl',
        ]),

    # How to lay out the controls in a frame/dialog
    ('Window Layout', [
        'LayoutAnchors',
        'Layoutf',
        'RowColSizer',
        'Sizers',
        'wxLayoutConstraints',
        'wxScrolledPanel',
        'wxXmlResource',
        'wxXmlResourceHandler',
        ]),

    # ditto
    ('Process and Events', [
        'EventManager',
        'infoframe',
        'OOR',
        'PythonEvents',
        'Threads',
        'wxKeyEvents',
        'wxProcess',
        'wxTimer',
        ]),

    # Clipboard and DnD
    ('Clipboard and DnD', [
        'CustomDragAndDrop',
        'DragAndDrop',
        'URLDragAndDrop',
        ]),

    # Images
    ('Using Images', [
        'Throbber',
        'wxArtProvider',
        'wxDragImage',
        'wxImage',
        'wxImageFromStream',
        'wxMask',
        ]),

    # Other stuff
    ('Miscellaneous', [
        'ColourDB',
        'DialogUnits',
        'DrawXXXList',
        'FontEnumerator',
        'PrintFramework',
        'Throbber',
        'Unicode',
        'wxFileHistory',
        'wxJoystick',
        'wxOGL',
        'wxWave',
        ]),

    # need libs not coming with the demo
    ('Objects using an external library', [
        'ActiveXWrapper_Acrobat',
        'ActiveXWrapper_IE',
        'wxGLCanvas',
        'wxPlotCanvas',
        ]),


    ('Check out the samples dir too', [
        ]),
]</t>
<t tx="edream.110203113231.75">class MyLog(wx.PyLog):
	@others
</t>
<t tx="edream.110203113231.76">def __init__(self, textCtrl, logTime=0):
    wx.PyLog.__init__(self)
    self.tc = textCtrl
    self.logTime = logTime
</t>
<t tx="edream.110203113231.77">def DoLogString(self, message, timeStamp):
    if self.logTime:
        message = time.strftime("%X", time.localtime(timeStamp)) + \
                  ": " + message
    if self.tc:
        self.tc.AppendText(message + '\n')
</t>
<t tx="edream.110203113231.78">class MyTP(wx.PyTipProvider):
	@others
</t>
<t tx="edream.110203113231.79">def GetTip(self):
    return "This is my tip"
</t>
<t tx="edream.110203113231.80">def opj(path):
    """Convert paths to the platform-specific separator"""
    return apply(os.path.join, tuple(path.split('/')))
</t>
<t tx="edream.110203113231.81">class wxPythonDemo(wx.Frame):
	overviewText = "wxPython Overview"
	@others
</t>
<t tx="edream.110203113231.82">def __init__(self, parent, id, title):

    wx.Frame.__init__(self, parent, -1, title, size = (800, 600),
		style=wx.DEFAULT_FRAME_STYLE|wx.NO_FULL_REPAINT_ON_RESIZE)

    self.cwd = os.getcwd()
    self.curOverview = ""
    self.window = None

    icon = images.getMondrianIcon()
    self.SetIcon(icon)

    if wx.Platform == '__WXMSW__':
        &lt;&lt; setup a taskbar icon, and catch some events from it &gt;&gt;

    wx.CallAfter(self.ShowTip)
    self.otherWin = None
    wx.EVT_IDLE(self, self.OnIdle)
    wx.EVT_CLOSE(self, self.OnCloseWindow)
    wx.EVT_ICONIZE(self, self.OnIconfiy)
    wx.EVT_MAXIMIZE(self, self.OnMaximize)

    self.Centre(wx.BOTH)
    self.CreateStatusBar(1, wx.ST_SIZEGRIP)

    splitter  = wx.SplitterWindow(self,     -1, style=wx.NO_3D|wx.SP_3D)
    splitter2 = wx.SplitterWindow(splitter, -1, style=wx.NO_3D|wx.SP_3D)

    def EmptyHandler(evt): pass
    wx.EVT_ERASE_BACKGROUND(splitter, EmptyHandler)
    wx.EVT_ERASE_BACKGROUND(splitter2, EmptyHandler)

    # Prevent TreeCtrl from displaying all items after destruction when True
    self.dying = False

	&lt;&lt; create menus &gt;&gt;
    self.finddata = wx.FindReplaceData()
    if 0:
		&lt;&lt; create accelerators &gt;&gt;
    &lt;&lt; Create a TreeCtrl &gt;&gt;
    &lt;&lt; Create a Notebook &gt;&gt;
    &lt;&lt; Set up a TextCtrl on the Demo Code Notebook page &gt;&gt;
    &lt;&lt; Set up a log on the View Log Notebook page &gt;&gt;
    self.Show(True)
    &lt;&lt; add the windows to the splitter and split it &gt;&gt;
    # select initial items
    self.nb.SetSelection(0)
    self.tree.SelectItem(root)
	&lt;&lt; handle sys.argv args &gt;&gt;
    wx.LogMessage('window handle: %s' % self.GetHandle())</t>
<t tx="edream.110203113231.83"># Make a File menu
self.mainmenu = wx.MenuBar()
menu = wx.Menu()
exitID = wx.NewId()
menu.Append(exitID, 'E&amp;xit\tAlt-X', 'Get the heck outta here!')
wx.EVT_MENU(self, exitID, self.OnFileExit)
wx.App_SetMacExitMenuItemId(exitID)
self.mainmenu.Append(menu, '&amp;File')

# Make a Demo menu
menu = wx.Menu()
for item in _treeList:
    submenu = wx.Menu()
    for childItem in item[1]:
        mID = wx.NewId()
        submenu.Append(mID, childItem)
        wx.EVT_MENU(self, mID, self.OnDemoMenu)
    menu.AppendMenu(wx.NewId(), item[0], submenu)
self.mainmenu.Append(menu, '&amp;Demo')


# Make a Help menu
helpID = wx.NewId()
findID = wx.NewId()
findnextID = wx.NewId()
menu = wx.Menu()
menu.Append(findID, '&amp;Find\tCtrl-F', 'Find in the Demo Code')
menu.Append(findnextID, 'Find &amp;Next\tF3', 'Find Next')
menu.AppendSeparator()
menu.Append(helpID, '&amp;About\tCtrl-H', 'wxPython RULES!!!')
wx.App_SetMacAboutMenuItemId(helpID)
wx.EVT_MENU(self, helpID, self.OnHelpAbout)
wx.EVT_MENU(self, findID, self.OnHelpFind)
wx.EVT_MENU(self, findnextID, self.OnFindNext)
wx.EVT_COMMAND_FIND(self, -1, self.OnFind)
wx.EVT_COMMAND_FIND_NEXT(self, -1, self.OnFind)
wx.EVT_COMMAND_FIND_CLOSE(self, -1 , self.OnFindClose)
self.mainmenu.Append(menu, '&amp;Help')
self.SetMenuBar(self.mainmenu)</t>
<t tx="edream.110203113231.84">tID = wx.NewId()
self.treeMap = {}
self.tree = wx.TreeCtrl(splitter, tID,
	style=wx.TR_HAS_BUTTONS | wx.TR_HAS_VARIABLE_ROW_HEIGHT)

root = self.tree.AddRoot("wxPython Overview")
firstChild = None
for item in _treeList:
    child = self.tree.AppendItem(root, item[0])
    if not firstChild: firstChild = child
    for childItem in item[1]:
        theDemo = self.tree.AppendItem(child, childItem)
        self.treeMap[childItem] = theDemo

self.tree.Expand(root)
self.tree.Expand(firstChild)

wx.EVT_TREE_ITEM_EXPANDED   (self.tree, tID, self.OnItemExpanded)
wx.EVT_TREE_ITEM_COLLAPSED  (self.tree, tID, self.OnItemCollapsed)
wx.EVT_TREE_SEL_CHANGED     (self.tree, tID, self.OnSelChanged)
wx.EVT_LEFT_DOWN            (self.tree,      self.OnTreeLeftDown)</t>
<t tx="edream.110203113231.85">self.nb = wx.Notebook(splitter2, -1, style=wx.CLIP_CHILDREN)

# Set up a wx.html.HtmlWindow on the Overview Notebook page
# we put it in a panel first because there seems to be a
# refresh bug of some sort (wxGTK) when it is directly in
# the notebook...

if 0:  # the old way
    self.ovr = wx.html.HtmlWindow(self.nb, -1, size=(400, 400))
    self.nb.AddPage(self.ovr, self.overviewText)

else:  # hopefully I can remove this hacky code soon, see SF bug #216861
    panel = wx.Panel(self.nb, -1, style=wx.CLIP_CHILDREN)
    self.ovr = wx.html.HtmlWindow(panel, -1, size=(400, 400))
    self.nb.AddPage(panel, self.overviewText)

    def OnOvrSize(evt, ovr=self.ovr):
        ovr.SetSize(evt.GetSize())

    wx.EVT_SIZE(panel, OnOvrSize)
    wx.EVT_ERASE_BACKGROUND(panel, EmptyHandler)

self.SetOverview(self.overviewText, overview)</t>
<t tx="edream.110203113231.86">self.txt = wx.TextCtrl(self.nb, -1,
	style = wx.TE_MULTILINE|
	wx.TE_READONLY|
	wx.HSCROLL|
	wx.TE_RICH2|
	wx.TE_NOHIDESEL)
	
self.nb.AddPage(self.txt, "Demo Code")
</t>
<t tx="edream.110203113231.87">self.log = wx.TextCtrl(splitter2, -1,
	style = wx.TE_MULTILINE|wx.TE_READONLY|wx.HSCROLL)

# Set the wxWindows log target to be this textctrl
#wx.Log_SetActiveTarget(wx.LogTextCtrl(self.log))

# But instead of the above we want to show how to use our own wx.Log class
wx.Log_SetActiveTarget(MyLog(self.log))

# for serious debugging
#wx.Log_SetActiveTarget(wx.LogStderr())
#wx.Log_SetTraceMask(wx.TraceMessages)</t>
<t tx="edream.110203113231.88">splitter2.SplitHorizontally(self.nb, self.log, 450)
splitter.SplitVertically(self.tree, splitter2, 180)

splitter.SetMinimumPaneSize(20)
splitter2.SetMinimumPaneSize(20)</t>
<t tx="edream.110203113231.89"># This is another way to set Accelerators, in addition to
# using the '\t&lt;key&gt;' syntax in the menu items.
aTable = wx.AcceleratorTable(
	[(wx.ACCEL_ALT,  ord('X'), exitID),
	(wx.ACCEL_CTRL, ord('H'), helpID),
	(wx.ACCEL_CTRL, ord('F'), findID),
	(wx.ACCEL_NORMAL, WXK_F3, findnextID)
	])
	
self.SetAcceleratorTable(aTable)
</t>
<t tx="edream.110203113231.90">self.tbicon = wx.TaskBarIcon()
self.tbicon.SetIcon(icon, "wxPython Demo")

wx.EVT_TASKBAR_LEFT_DCLICK(self.tbicon, self.OnTaskBarActivate)
wx.EVT_TASKBAR_RIGHT_UP(self.tbicon, self.OnTaskBarMenu)
wx.EVT_MENU(self.tbicon, self.TBMENU_RESTORE, self.OnTaskBarActivate)
wx.EVT_MENU(self.tbicon, self.TBMENU_CLOSE, self.OnTaskBarClose)</t>
<t tx="edream.110203113231.91">if len(sys.argv) == 2:
    try:
        selectedDemo = self.treeMap[sys.argv[1]]
    except:
        selectedDemo = None
    if selectedDemo:
        self.tree.SelectItem(selectedDemo)
        self.tree.EnsureVisible(selectedDemo)</t>
<t tx="edream.110203113231.92">def WriteText(self, text):
    if text[-1:] == '\n':
        text = text[:-1]
    wx.LogMessage(text)
</t>
<t tx="edream.110203113231.93">def write(self, txt):
    self.WriteText(txt)
</t>
<t tx="edream.110203113231.94"></t>
<t tx="edream.110203113231.95">def OnItemExpanded(self, event):
	
    item = event.GetItem()
    wx.LogMessage("OnItemExpanded: %s" % self.tree.GetItemText(item))
    event.Skip()

</t>
<t tx="edream.110203113231.96">def OnItemCollapsed(self, event):

    item = event.GetItem()
    wx.LogMessage("OnItemCollapsed: %s" % self.tree.GetItemText(item))
    event.Skip()
</t>
<t tx="edream.110203113231.97">def OnTreeLeftDown(self, event):
	
    pt = event.GetPosition();
    item, flags = self.tree.HitTest(pt)
    if item == self.tree.GetSelection():
        self.SetOverview(self.tree.GetItemText(item)+" Overview", self.curOverview)
    event.Skip()

</t>
<t tx="edream.110203113231.98">def OnSelChanged(self, event):

    if self.dying:
        return

    item = event.GetItem()
    itemText = self.tree.GetItemText(item)
    self.RunDemo(itemText)</t>
<t tx="edream.110203113231.99">def RunDemo(self, itemText):
    os.chdir(self.cwd)
    if self.nb.GetPageCount() == 3:
        if self.nb.GetSelection() == 2:
            self.nb.SetSelection(0)
        # inform the window that it's time to quit if it cares
        if self.window is not None:
            if hasattr(self.window, "ShutdownDemo"):
                self.window.ShutdownDemo()
        wx.SafeYield() # in case the page has pending events
        self.nb.DeletePage(2)

    if itemText == self.overviewText:
        self.GetDemoFile('Main.py')
        self.SetOverview(self.overviewText, overview)
        self.nb.Refresh();
        self.window = None

    else:
        if os.path.exists(itemText + '.py'):
            wx.BeginBusyCursor()
            wx.LogMessage("Running demo %s.py..." % itemText)
            try:
                self.GetDemoFile(itemText + '.py')
                module = __import__(itemText, globals())
                self.SetOverview(itemText + " Overview", module.overview)
            finally:
                wx.EndBusyCursor()
            self.tree.Refresh()

            # in case runTest is modal, make sure things look right...
            self.nb.Refresh();
            wx.SafeYield()

            self.window = module.runTest(self, self.nb, self) ###
            if self.window is not None:
                self.nb.AddPage(self.window, 'Demo')
                self.nb.SetSelection(2)
                self.nb.Refresh()  # without this wxMac has troubles showing the just added page

        else:
            self.ovr.SetPage("")
            self.txt.Clear()
            self.window = None
</t>
<t tx="edream.110203113231.100">#---------------------------------------------
# Get the Demo files
def GetDemoFile(self, filename):
    self.txt.Clear()
    try:
        self.txt.SetValue(open(filename).read())
    except IOError:
        self.txt.WriteText("Cannot open %s file." % filename)

    self.txt.SetInsertionPoint(0)
    self.txt.ShowPosition(0)
</t>
<t tx="edream.110203113231.101">#---------------------------------------------
def SetOverview(self, name, text):
    self.curOverview = text
    lead = text[:6]
    if lead != '&lt;html&gt;' and lead != '&lt;HTML&gt;':
        text = '&lt;br&gt;'.join(text.split('\n'))
    self.ovr.SetPage(text)
    self.nb.SetPageText(0, name)
</t>
<t tx="edream.110203113231.102">#---------------------------------------------
# Menu methods
def OnFileExit(self, *event):
    self.Close()
</t>
<t tx="edream.110203113231.103">def OnHelpAbout(self, event):
    from About import MyAboutBox
    about = MyAboutBox(self)
    about.ShowModal()
    about.Destroy()
</t>
<t tx="edream.110203113231.104">def OnHelpFind(self, event):
    self.nb.SetSelection(1)
    self.finddlg = wx.FindReplaceDialog(self, self.finddata, "Find",
                    wx.FR_NOUPDOWN |
                    wx.FR_NOMATCHCASE |
                    wx.FR_NOWHOLEWORD)
    self.finddlg.Show(True)
</t>
<t tx="edream.110203113231.105">def OnFind(self, event):
    self.nb.SetSelection(1)
    end = self.txt.GetLastPosition()
    textstring = self.txt.GetRange(0, end).lower()
    start = self.txt.GetSelection()[1]
    findstring = self.finddata.GetFindString().lower()
    loc = textstring.find(findstring, start)
    if loc == -1 and start != 0:
        # string not found, start at beginning
        start = 0
        loc = textstring.find(findstring, start)
    if loc == -1:
        dlg = wx.MessageDialog(self, 'Find String Not Found',
                      'Find String Not Found in Demo File',
                      wx.OK | wx.ICON_INFORMATION)
        dlg.ShowModal()
        dlg.Destroy()
    if self.finddlg:
        if loc == -1:
            self.finddlg.SetFocus()
            return
        else:
            self.finddlg.Destroy()
    self.txt.SetSelection(loc, loc + len(findstring))
    self.txt.ShowPosition(loc)
</t>
<t tx="edream.110203113231.106">def OnFindNext(self, event):
    if self.finddata.GetFindString():
        self.OnFind(event)
    else:
        self.OnHelpFind(event)
</t>
<t tx="edream.110203113231.107">def OnFindClose(self, event):
    event.GetDialog().Destroy()
</t>
<t tx="edream.110203113231.108">#---------------------------------------------
def OnCloseWindow(self, event):
    self.dying = True
    self.window = None
    self.mainmenu = None
    if hasattr(self, "tbicon"):
        del self.tbicon
    self.Destroy()
</t>
<t tx="edream.110203113231.109">#---------------------------------------------
def OnIdle(self, event):
    if self.otherWin:
        self.otherWin.Raise()
        self.window = self.otherWin
        self.otherWin = None
</t>
<t tx="edream.110203113231.110">#---------------------------------------------
def ShowTip(self):
    try:
        showTipText = open(opj("data/showTips")).read()
        showTip, index = eval(showTipText)
    except IOError:
        showTip, index = (1, 0)
    if showTip:
        tp = wx.CreateFileTipProvider(opj("data/tips.txt"), index)
        ##tp = MyTP(0)
        showTip = wx.ShowTip(self, tp)
        index = tp.GetCurrentTip()
        open(opj("data/showTips"), "w").write(str( (showTip, index) ))
</t>
<t tx="edream.110203113231.111">#---------------------------------------------
def OnDemoMenu(self, event):
    try:
        selectedDemo = self.treeMap[self.mainmenu.GetLabel(event.GetId())]
    except:
        selectedDemo = None
    if selectedDemo:
        self.tree.SelectItem(selectedDemo)
        self.tree.EnsureVisible(selectedDemo)
</t>
<t tx="edream.110203113231.112">#---------------------------------------------
def OnTaskBarActivate(self, evt):
    if self.IsIconized():
        self.Iconize(False)
    if not self.IsShown():
        self.Show(True)
    self.Raise()
</t>
<t tx="edream.110203113231.113">#---------------------------------------------

TBMENU_RESTORE = 1000
TBMENU_CLOSE   = 1001

def OnTaskBarMenu(self, evt):
    menu = wx.Menu()
    menu.Append(self.TBMENU_RESTORE, "Restore wxPython Demo")
    menu.Append(self.TBMENU_CLOSE,   "Close")
    self.tbicon.PopupMenu(menu)
    menu.Destroy()
</t>
<t tx="edream.110203113231.114">#---------------------------------------------
def OnTaskBarClose(self, evt):
    self.Close()

    # because of the way wx.TaskBarIcon.PopupMenu is implemented we have to
    # prod the main idle handler a bit to get the window to actually close
    wx.GetApp().ProcessIdle()
</t>
<t tx="edream.110203113231.115">#---------------------------------------------
def OnIconfiy(self, evt):
    wx.LogMessage("OnIconfiy")
    evt.Skip()
</t>
<t tx="edream.110203113231.116">#---------------------------------------------
def OnMaximize(self, evt):
    wx.LogMessage("OnMaximize")
    evt.Skip()
</t>
<t tx="edream.110203113231.117">class MySplashScreen(wx.SplashScreen):
	@others
</t>
<t tx="edream.110203113231.118">def __init__(self):

    bmp = wx.Image(opj("bitmaps/splash.gif")).ConvertToBitmap()

    wx.SplashScreen.__init__(self, bmp,
		wx.SPLASH_CENTRE_ON_SCREEN|wx.SPLASH_TIMEOUT,
		4000, None, -1,
		style = wx.SIMPLE_BORDER|wx.FRAME_NO_TASKBAR|wx.STAY_ON_TOP)

    wx.EVT_CLOSE(self, self.OnClose)</t>
<t tx="edream.110203113231.119">def OnClose(self, evt):
    frame = wxPythonDemo(None, -1, "wxPython: (A Demonstration)")
    frame.Show()
    evt.Skip()  # Make sure the default handler runs too...
</t>
<t tx="edream.110203113231.120">class MyApp(wx.App):
	@others
</t>
<t tx="edream.110203113231.121">def OnInit(self):
    """
    Create and show the splash screen.  It will then create and show
    the main frame when it is time to do so.
    """

    #import locale
    #self.locale = wx.Locale(wx.LANGUAGE_FRENCH)
    #locale.setlocale(locale.LC_ALL, 'fr')

    wx.InitAllImageHandlers()
    splash = MySplashScreen()
    splash.Show()
    return True
</t>
<t tx="edream.110203113231.122">def main():
    try:
        demoPath = os.path.dirname(__file__)
        os.chdir(demoPath)
    except:
        pass

    app = MyApp(wx.Platform == "__WXMAC__")
    app.MainLoop()</t>
<t tx="edream.110203113231.123">overview = """&lt;html&gt;&lt;body&gt;
&lt;h2&gt;wxPython&lt;/h2&gt;

&lt;p&gt; wxPython is a &lt;b&gt;GUI toolkit&lt;/b&gt; for the &lt;a
href="http://www.python.org/"&gt;Python&lt;/a&gt; programming language.  It
allows Python programmers to create programs with a robust, highly
functional graphical user interface, simply and easily.  It is
implemented as a Python extension module (native code) that wraps the
popular &lt;a href="http://wxwindows.org/front.htm"&gt;wxWindows&lt;/a&gt; cross
platform GUI library, which is written in C++.

&lt;p&gt; Like Python and wxWindows, wxPython is &lt;b&gt;Open Source&lt;/b&gt; which
means that it is free for anyone to use and the source code is
available for anyone to look at and modify.  Or anyone can contribute
fixes or enhnacments to the project.

&lt;p&gt; wxPython is a &lt;b&gt;cross-platform&lt;/b&gt; toolkit.  This means that the
same program will run on multiple platforms without modification.
Currently supported platforms are 32-bit Microsoft Windows, most Unix
or unix-like systems, and Macintosh OS X. Since the language is
Python, wxPython programs are &lt;b&gt;simple, easy&lt;/b&gt; to write and easy to
understand.

&lt;p&gt; &lt;b&gt;This demo&lt;/b&gt; is not only a collection of test cases for
wxPython, but is also designed to help you learn about and how to use
wxPython.  Each sample is listed in the tree control on the left.
When a sample is selected in the tree then a module is loaded and run
(usually in a tab of this notebook,) and the source code of the module
is loaded in another tab for you to browse and learn from.

"""</t>
<t tx="edream.110203113231.124"></t>
<t tx="edream.110203113231.125">@ignore
@language python

from wxPython.wx import *
from wxPython.gizmos import wxTreeListCtrl

import images

@others

overview = """&lt;html&gt;&lt;body&gt;
&lt;h2&gt;&lt;center&gt;wxTreeListCtrl&lt;/center&gt;&lt;/h2&gt;

The wxTreeListCtrl is essentially a wxTreeCtrl with extra columns,
such that the look is similar to a wxListCtrl.

&lt;/body&gt;&lt;/html&gt;
"""

if __name__ == '__main__':
    #raw_input("Press enter...")
    import sys,os,run
    run.main(['', os.path.basename(sys.argv[0])])</t>
<t tx="edream.110203113231.126">class TestPanel(wxPanel):
	@others
</t>
<t tx="edream.110203113231.127">def __init__(self, parent, log):
    self.log = log
    wxPanel.__init__(self, parent, -1)
    EVT_SIZE(self, self.OnSize)

    self.tree = wxTreeListCtrl(self, -1, style = wxTR_DEFAULT_STYLE
                               #| wxTR_ROW_LINES
                               #| wxTR_NO_LINES | wxTR_TWIST_BUTTONS
                               )
    isz = (16,16)
    il = wxImageList(isz[0], isz[1])
    fldridx     = il.Add(wxArtProvider_GetBitmap(wxART_FOLDER,      wxART_OTHER, isz))
    fldropenidx = il.Add(wxArtProvider_GetBitmap(wxART_FILE_OPEN,   wxART_OTHER, isz))
    fileidx     = il.Add(wxArtProvider_GetBitmap(wxART_REPORT_VIEW, wxART_OTHER, isz))
    smileidx    = il.Add(images.getSmilesBitmap())

    self.tree.SetImageList(il)
    self.il = il

    # create some columns
    self.tree.AddColumn("Main column")
    self.tree.AddColumn("Column 1")
    self.tree.AddColumn("Column 2")
    self.tree.SetMainColumn(0) # the one with the tree in it...
    self.tree.SetColumnWidth(0, 175)


    self.root = self.tree.AddRoot("The Root Item")
    self.tree.SetItemText(self.root, "col 1 root", 1)
    self.tree.SetItemText(self.root, "col 2 root", 2)
    self.tree.SetItemImage(self.root, fldridx, which = wxTreeItemIcon_Normal)
    self.tree.SetItemImage(self.root, fldropenidx, which = wxTreeItemIcon_Expanded)


    for x in range(15):
        txt = "Item %d" % x
        child = self.tree.AppendItem(self.root, txt)
        self.tree.SetItemText(child, txt + "(c1)", 1)
        self.tree.SetItemText(child, txt + "(c2)", 2)
        self.tree.SetItemImage(child, fldridx, which = wxTreeItemIcon_Normal)
        self.tree.SetItemImage(child, fldropenidx, which = wxTreeItemIcon_Expanded)

        for y in range(5):
            txt = "item %d-%s" % (x, chr(ord("a")+y))
            last = self.tree.AppendItem(child, txt)
            self.tree.SetItemText(last, txt + "(c1)", 1)
            self.tree.SetItemText(last, txt + "(c2)", 2)
            self.tree.SetItemImage(last, fldridx, which = wxTreeItemIcon_Normal)
            self.tree.SetItemImage(last, fldropenidx, which = wxTreeItemIcon_Expanded)

            for z in range(5):
                txt = "item %d-%s-%d" % (x, chr(ord("a")+y), z)
                item = self.tree.AppendItem(last,  txt)
                self.tree.SetItemText(item, txt + "(c1)", 1)
                self.tree.SetItemText(item, txt + "(c2)", 2)
                self.tree.SetItemImage(item, fileidx, which = wxTreeItemIcon_Normal)
                self.tree.SetItemImage(item, smileidx, which = wxTreeItemIcon_Selected)


    self.tree.Expand(self.root)
</t>
<t tx="edream.110203113231.128">def OnSize(self, evt):
    self.tree.SetSize(self.GetSize())
</t>
<t tx="edream.110203113231.129">def runTest(frame, nb, log):
    win = TestPanel(nb, log)
    return win
</t>
<t tx="edream.110203113231.130">@ignore
@language python

from wxPython.wx import *
import images,string

@others

overview = """\
A tree control presents information as a hierarchy, with items that may be expanded to show further items. Items in a tree control are referenced by wxTreeItemId handles.

"""

if __name__ == '__main__':
    import sys,os,run
    run.main(['', os.path.basename(sys.argv[0])])

</t>
<t tx="edream.110203113231.131">class MyTreeCtrl(wxTreeCtrl):
	@others
</t>
<t tx="edream.110203113231.132">def __init__(self, parent, id, pos, size, style, log):

    wxTreeCtrl.__init__(self, parent, id, pos, size, style)
    self.log = log
</t>
<t tx="edream.110203113231.133">def OnCompareItems(self, item1, item2):

    t1 = self.GetItemText(item1)
    t2 = self.GetItemText(item2)
    self.log.WriteText('compare: ' + t1 + ' &lt;&gt; ' + t2 + '\n')
    if t1 &lt; t2: return -1
    if t1 == t2: return 0
    return 1
</t>
<t tx="edream.110203113231.134">class TestTreeCtrlPanel(wxPanel):
	@others
</t>
<t tx="edream.110203113231.135">def __init__(self, parent, log):

    # Use the WANTS_CHARS style so the panel doesn't eat the Return key.
    wxPanel.__init__(self, parent, -1, style=wxWANTS_CHARS)
    EVT_SIZE(self,self.OnSize)

    self.log = log
    tID = wxNewId()

    self.tree = MyTreeCtrl(self, tID, wxDefaultPosition, wxDefaultSize,
                          wxTR_HAS_BUTTONS
                           | wxTR_EDIT_LABELS
                           #| wxTR_MULTIPLE
                           #| wxTR_HIDE_ROOT
                           , self.log)

    isz = (16,16)
    il = wxImageList(isz[0], isz[1])
    fldridx     = il.Add(wxArtProvider_GetBitmap(wxART_FOLDER,      wxART_OTHER, isz))
    fldropenidx = il.Add(wxArtProvider_GetBitmap(wxART_FILE_OPEN,   wxART_OTHER, isz))
    fileidx     = il.Add(wxArtProvider_GetBitmap(wxART_REPORT_VIEW, wxART_OTHER, isz))
    smileidx    = il.Add(images.getSmilesBitmap())

    self.tree.SetImageList(il)
    self.il = il

    # NOTE:  For some reason tree items have to have a data object in
    #        order to be sorted.  Since our compare just uses the labels
    #        we don't need any real data, so we'll just use None below for
    #        the item data.

    self.root = self.tree.AddRoot("The Root Item")
    self.tree.SetPyData(self.root, None)
    self.tree.SetItemImage(self.root, fldridx, wxTreeItemIcon_Normal)
    self.tree.SetItemImage(self.root, fldropenidx, wxTreeItemIcon_Expanded)


    for x in range(15):
        child = self.tree.AppendItem(self.root, "Item %d" % x)
        self.tree.SetPyData(child, None)
        self.tree.SetItemImage(child, fldridx, wxTreeItemIcon_Normal)
        self.tree.SetItemImage(child, fldropenidx, wxTreeItemIcon_Expanded)
        for y in range(5):
            last = self.tree.AppendItem(child, "item %d-%s" % (x, chr(ord("a")+y)))
            self.tree.SetPyData(last, None)
            self.tree.SetItemImage(last, fldridx, wxTreeItemIcon_Normal)
            self.tree.SetItemImage(last, fldropenidx, wxTreeItemIcon_Expanded)
            for z in range(5):
                item = self.tree.AppendItem(last,  "item %d-%s-%d" % (x, chr(ord("a")+y), z))
                self.tree.SetPyData(item, None)
                self.tree.SetItemImage(item, fileidx, wxTreeItemIcon_Normal)
                self.tree.SetItemImage(item, smileidx, wxTreeItemIcon_Selected)

    self.tree.Expand(self.root)
    EVT_TREE_ITEM_EXPANDED  (self, tID, self.OnItemExpanded)
    EVT_TREE_ITEM_COLLAPSED (self, tID, self.OnItemCollapsed)
    EVT_TREE_SEL_CHANGED    (self, tID, self.OnSelChanged)
    EVT_TREE_BEGIN_LABEL_EDIT(self, tID, self.OnBeginEdit)
    EVT_TREE_END_LABEL_EDIT (self, tID, self.OnEndEdit)
    EVT_TREE_ITEM_ACTIVATED (self, tID, self.OnActivate)

    EVT_LEFT_DCLICK(self.tree, self.OnLeftDClick)
    EVT_RIGHT_DOWN(self.tree, self.OnRightClick)
    EVT_RIGHT_UP(self.tree, self.OnRightUp)
</t>
<t tx="edream.110203113231.136">def OnRightClick(self, event):

    pt = event.GetPosition();
    item, flags = self.tree.HitTest(pt)
    self.log.WriteText("OnRightClick: %s, %s, %s\n" %
                       (self.tree.GetItemText(item), type(item), item.__class__))
    self.tree.SelectItem(item)
</t>
<t tx="edream.110203113231.137">def OnRightUp(self, event):

    pt = event.GetPosition();
    item, flags = self.tree.HitTest(pt)
    self.log.WriteText("OnRightUp: %s (manually starting label edit)\n"
                       % self.tree.GetItemText(item))
    self.tree.EditLabel(item)
</t>
<t tx="edream.110203113231.138">def OnBeginEdit(self, event):
    self.log.WriteText("OnBeginEdit\n")
    # show how to prevent edit...
    if self.tree.GetItemText(event.GetItem()) == "The Root Item":
        wxBell()
        self.log.WriteText("You can't edit this one...\n")

        # Lets just see what's visible of its children
        cookie = 0
        root = event.GetItem()
        (child, cookie) = self.tree.GetFirstChild(root, cookie)
        while child.IsOk():
            self.log.WriteText("Child [%s] visible = %d" %
                               (self.tree.GetItemText(child),
                                self.tree.IsVisible(child)))
            (child, cookie) = self.tree.GetNextChild(root, cookie)

        event.Veto()
</t>
<t tx="edream.110203113231.139">def OnEndEdit(self, event):
    self.log.WriteText("OnEndEdit\n")
    # show how to reject edit, we'll not allow any digits
    for x in event.GetLabel():
        if x in string.digits:
            self.log.WriteText("You can't enter digits...\n")
            event.Veto()
            return
</t>
<t tx="edream.110203113231.140">def OnLeftDClick(self, event):
    pt = event.GetPosition();
    item, flags = self.tree.HitTest(pt)
    self.log.WriteText("OnLeftDClick: %s\n" % self.tree.GetItemText(item))
    parent = self.tree.GetItemParent(item)
    self.tree.SortChildren(parent)
    event.Skip()
</t>
<t tx="edream.110203113231.141">def OnSize(self, event):
    w,h = self.GetClientSizeTuple()
    self.tree.SetDimensions(0, 0, w, h)
</t>
<t tx="edream.110203113231.142">def OnItemExpanded(self, event):
    item = event.GetItem()
    self.log.WriteText("OnItemExpanded: %s\n" % self.tree.GetItemText(item))
</t>
<t tx="edream.110203113231.143">def OnItemCollapsed(self, event):
    item = event.GetItem()
    self.log.WriteText("OnItemCollapsed: %s\n" % self.tree.GetItemText(item))
</t>
<t tx="edream.110203113231.144">def OnSelChanged(self, event):
    self.item = event.GetItem()
    self.log.WriteText("OnSelChanged: %s\n" % self.tree.GetItemText(self.item))
    if wxPlatform == '__WXMSW__':
        self.log.WriteText("BoundingRect: %s\n" %
                           self.tree.GetBoundingRect(self.item, True))
    #items = self.tree.GetSelections()
    #print map(self.tree.GetItemText, items)
    event.Skip()
</t>
<t tx="edream.110203113231.145">def OnActivate(self, event):
    self.log.WriteText("OnActivate: %s\n" % self.tree.GetItemText(self.item))
</t>
<t tx="edream.110203113231.146">def runTest(frame, nb, log):
    win = TestTreeCtrlPanel(nb, log)
    return win
</t>
<t tx="edream.110203113231.147"></t>
<t tx="edream.110203113231.148">@ignore
@language python
&lt;&lt; wxStyledTextCtrl_1 declarations &gt;&gt;
@others



#----------------------------------------------------------------------


overview = """\
&lt;html&gt;&lt;body&gt;
Once again, no docs yet.  &lt;b&gt;Sorry.&lt;/b&gt;  But &lt;a href="data/stc.h.html"&gt;this&lt;/a&gt;
and &lt;a href="http://www.scintilla.org/ScintillaDoc.html"&gt;this&lt;/a&gt; should
be helpful.
&lt;/body&gt;&lt;html&gt;
"""


if __name__ == '__main__':
    import sys,os
    import run
    run.main(['', os.path.basename(sys.argv[0])])

</t>
<t tx="edream.110203113231.149">from wxPython.wx import *
from wxPython.stc import *

import images

#----------------------------------------------------------------------

debug = 1


demoText = """\

This editor is provided by a class named wxStyledTextCtrl.  As
the name suggests, you can define styles that can be applied to
sections of text.  This will typically be used for things like
syntax highlighting code editors, but I'm sure that there are other
applications as well.  A style is a combination of font, point size,
forground and background colours.  The editor can handle
proportional fonts just as easily as monospaced fonts, and various
styles can use different sized fonts.

There are a few canned language lexers and colourizers included,
(see the next demo) or you can handle the colourization yourself.
If you do you can simply register an event handler and the editor
will let you know when the visible portion of the text needs
styling.

wxStyledTextEditor also supports setting markers in the margin...




...and indicators within the text.  You can use these for whatever
you want in your application.  Cut, Copy, Paste, Drag and Drop of
text works, as well as virtually unlimited Undo and Redo
capabilities, (right click to try it out.)
"""

if wxPlatform == '__WXMSW__':
    face1 = 'Arial'
    face2 = 'Times New Roman'
    face3 = 'Courier New'
    pb = 10
else:
    face1 = 'Helvetica'
    face2 = 'Times'
    face3 = 'Courier'
    pb = 10


#----------------------------------------------------------------------
# This shows how to catch the Modified event from the wxStyledTextCtrl

</t>
<t tx="edream.110203113231.150">class MySTC(wxStyledTextCtrl):
	@others
</t>
<t tx="edream.110203113231.151">def __init__(self, parent, ID, log):
    wxStyledTextCtrl.__init__(self, parent, ID)
    self.log = log

    EVT_STC_DO_DROP(self, ID, self.OnDoDrop)
    EVT_STC_DRAG_OVER(self, ID, self.OnDragOver)
    EVT_STC_START_DRAG(self, ID, self.OnStartDrag)
    EVT_STC_MODIFIED(self, ID, self.OnModified)

    EVT_WINDOW_DESTROY(self, self.OnDestroy)
</t>
<t tx="edream.110203113231.152">def OnDestroy(self, evt):
    # This is how the clipboard contents can be preserved after
    # the app has exited.
    wxTheClipboard.Flush()
    evt.Skip()
</t>
<t tx="edream.110203113231.153">def OnStartDrag(self, evt):
    self.log.write("OnStartDrag: %d, %s\n"
                   % (evt.GetDragAllowMove(), evt.GetDragText()))

    if debug and evt.GetPosition() &lt; 250:
        evt.SetDragAllowMove(False)     # you can prevent moving of text (only copy)
        evt.SetDragText("DRAGGED TEXT") # you can change what is dragged
</t>
<t tx="edream.110203113231.154">        #evt.SetDragText("")             # or prevent the drag with empty text


def OnDragOver(self, evt):
    self.log.write("OnDragOver: x,y=(%d, %d)  pos: %d  DragResult: %d\n"
                   % (evt.GetX(), evt.GetY(), evt.GetPosition(), evt.GetDragResult()))

    if debug and evt.GetPosition() &lt; 250:
        evt.SetDragResult(wxDragNone)   # prevent dropping at the begining of the buffer
</t>
<t tx="edream.110203113231.155">def OnDoDrop(self, evt):
    self.log.write("OnDoDrop: x,y=(%d, %d)  pos: %d  DragResult: %d\n"
                   "\ttext: %s\n"
                   % (evt.GetX(), evt.GetY(), evt.GetPosition(), evt.GetDragResult(),
                      evt.GetDragText()))

    if debug and evt.GetPosition() &lt; 500:
        evt.SetDragText("DROPPED TEXT")  # Can change text if needed
</t>
<t tx="edream.110203113231.156">        ##evt.SetDragResult(wxDragNone)  # Can also change the drag operation, but it
                                         # is probably better to do it in OnDragOver so
                                         # there is visual feedback

        ##evt.SetPosition(25)            # Can also change position, but I'm not sure why
                                         # you would want to...




def OnModified(self, evt):
    self.log.write("""OnModified
    Mod type:     %s
    At position:  %d
    Lines added:  %d
    Text Length:  %d
    Text:         %s\n""" % ( self.transModType(evt.GetModificationType()),
                              evt.GetPosition(),
                              evt.GetLinesAdded(),
                              evt.GetLength(),
                              repr(evt.GetText()) ))
</t>
<t tx="edream.110203113231.157">def transModType(self, modType):
    st = ""
    table = [(wxSTC_MOD_INSERTTEXT, "InsertText"),
             (wxSTC_MOD_DELETETEXT, "DeleteText"),
             (wxSTC_MOD_CHANGESTYLE, "ChangeStyle"),
             (wxSTC_MOD_CHANGEFOLD, "ChangeFold"),
             (wxSTC_PERFORMED_USER, "UserFlag"),
             (wxSTC_PERFORMED_UNDO, "Undo"),
             (wxSTC_PERFORMED_REDO, "Redo"),
             (wxSTC_LASTSTEPINUNDOREDO, "Last-Undo/Redo"),
             (wxSTC_MOD_CHANGEMARKER, "ChangeMarker"),
             (wxSTC_MOD_BEFOREINSERT, "B4-Insert"),
             (wxSTC_MOD_BEFOREDELETE, "B4-Delete")
             ]

    for flag,text in table:
        if flag &amp; modType:
            st = st + text + " "

    if not st:
        st = 'UNKNOWN'

    return st
</t>
<t tx="edream.110203113231.158">#----------------------------------------------------------------------

_USE_PANEL = 1

def runTest(frame, nb, log):
    if not _USE_PANEL:
        ed = p = MySTC(nb, -1, log)

    else:
        p = wxPanel(nb, -1, style=wxNO_FULL_REPAINT_ON_RESIZE)
        ed = MySTC(p, -1, log)
        s = wxBoxSizer(wxHORIZONTAL)
        s.Add(ed, 1, wxEXPAND)
        p.SetSizer(s)
        p.SetAutoLayout(True)


    #ed.SetBufferedDraw(False)
    #ed.StyleClearAll()
    #ed.SetScrollWidth(800)
    #ed.SetWrapMode(True)

    ed.SetText(demoText)
    if wxUSE_UNICODE:
        import codecs
        decode = codecs.lookup("utf-8")[1]

        ed.GotoPos(ed.GetLength())
        ed.AddText("\n\nwxStyledTextCtrl can also do Unicode:\n")
        unitext, l = decode('\xd0\x9f\xd0\xb8\xd1\x82\xd0\xbe\xd0\xbd - '
                            '\xd0\xbb\xd1\x83\xd1\x87\xd1\x88\xd0\xb8\xd0\xb9 '
                            '\xd1\x8f\xd0\xb7\xd1\x8b\xd0\xba \xd0\xbf\xd1\x80\xd0\xbe\xd0\xb3\xd1\x80\xd0\xb0\xd0\xbc\xd0\xbc\xd0\xb8\xd1\x80\xd0\xbe\xd0\xb2\xd0\xb0\xd0\xbd\xd0\xb8\xd1\x8f!\n\n')
        ed.AddText('\tRussian: ')
        ed.AddText(unitext)
        ed.GotoPos(0)

    ed.EmptyUndoBuffer()

    # make some styles
    ed.StyleSetSpec(wxSTC_STYLE_DEFAULT, "size:%d,face:%s" % (pb, face3))
    ed.StyleSetSpec(1, "size:%d,bold,face:%s,fore:#0000FF" % (pb+2, face1))
    ed.StyleSetSpec(2, "face:%s,italic,fore:#FF0000,size:%d" % (face2, pb))
    ed.StyleSetSpec(3, "face:%s,bold,size:%d" % (face2, pb+2))
    ed.StyleSetSpec(4, "face:%s,size:%d" % (face1, pb-1))

    # Now set some text to those styles...  Normally this would be
    # done in an event handler that happens when text needs displayed.
    ed.StartStyling(98, 0xff)
    ed.SetStyling(6, 1)  # set style for 6 characters using style 1

    ed.StartStyling(190, 0xff)
    ed.SetStyling(20, 2)

    ed.StartStyling(310, 0xff)
    ed.SetStyling(4, 3)
    ed.SetStyling(2, 0)
    ed.SetStyling(10, 4)


    # line numbers in the margin
    ed.SetMarginType(0, wxSTC_MARGIN_NUMBER)
    ed.SetMarginWidth(0, 22)
    ed.StyleSetSpec(wxSTC_STYLE_LINENUMBER, "size:%d,face:%s" % (pb, face1))

    # setup some markers
    ed.SetMarginType(1, wxSTC_MARGIN_SYMBOL)
    ed.MarkerDefine(0, wxSTC_MARK_ROUNDRECT, "#CCFF00", "RED")
    #ed.MarkerDefine(1, wxSTC_MARK_CIRCLE, "FOREST GREEN", "SIENNA")
    ed.MarkerDefineBitmap(1, images.getFolder1Bitmap())
    ed.MarkerDefine(2, wxSTC_MARK_SHORTARROW, "blue", "blue")
    ed.MarkerDefine(3, wxSTC_MARK_ARROW, "#00FF00", "#00FF00")

    # put some markers on some lines
    ed.MarkerAdd(17, 0)
    ed.MarkerAdd(18, 1)
    ed.MarkerAdd(19, 2)
    ed.MarkerAdd(20, 3)
    ed.MarkerAdd(20, 0)


    # and finally, an indicator or two
    ed.IndicatorSetStyle(0, wxSTC_INDIC_SQUIGGLE)
    ed.IndicatorSetForeground(0, wxRED)
    ed.IndicatorSetStyle(1, wxSTC_INDIC_DIAGONAL)
    ed.IndicatorSetForeground(1, wxBLUE)
    ed.IndicatorSetStyle(2, wxSTC_INDIC_STRIKE)
    ed.IndicatorSetForeground(2, wxRED)

    ed.StartStyling(836, wxSTC_INDICS_MASK)
    ed.SetStyling(10, wxSTC_INDIC0_MASK)
    ed.SetStyling(10, wxSTC_INDIC1_MASK)
    ed.SetStyling(10, wxSTC_INDIC2_MASK | wxSTC_INDIC1_MASK)


    # some test stuff...
    if debug:
        print "GetTextLength(): ", ed.GetTextLength(), len(ed.GetText())
        print "GetText(): ", repr(ed.GetText())
        print
        print "GetStyledText(98, 104): ", repr(ed.GetStyledText(98, 104)), len(ed.GetStyledText(98, 104))
        print
        print "GetCurLine(): ", repr(ed.GetCurLine())
        ed.GotoPos(5)
        print "GetCurLine(): ", repr(ed.GetCurLine())
        print
        print "GetLine(1): ", repr(ed.GetLine(1))
        print
        ed.SetSelection(25, 35)
        print "GetSelectedText(): ", repr(ed.GetSelectedText())
        print "GetTextRange(25, 35): ", repr(ed.GetTextRange(25, 35))
        print "FindText(0, max, 'indicators'): ",
        print ed.FindText(0, ed.GetTextLength(), "indicators")

        ed.GotoPos(0)


    return p
</t>
<t tx="edream.110203113231.159">@ignore
@language python
&lt;&lt; wxStyledTextCtrl_2 declarations &gt;&gt;
@others



#----------------------------------------------------------------------


overview = """\
&lt;html&gt;&lt;body&gt;
Once again, no docs yet.  &lt;b&gt;Sorry.&lt;/b&gt;  But &lt;a href="data/stc.h.html"&gt;this&lt;/a&gt;
and &lt;a href="http://www.scintilla.org/ScintillaDoc.html"&gt;this&lt;/a&gt; should
be helpful.
&lt;/body&gt;&lt;html&gt;
"""


if __name__ == '__main__':
    import sys,os
    import run
    run.main(['', os.path.basename(sys.argv[0])])





#----------------------------------------------------------------------
#----------------------------------------------------------------------

</t>
<t tx="edream.110203113231.160">from wxPython.wx import *
from wxPython.stc import *
import images
import keyword

demoText = """\
## This version of the editor has been set up to edit Python source
## code.  Here is a copy of wxPython/demo/Main.py to play with.


"""

if wxPlatform == '__WXMSW__':
    faces = { 'times': 'Times New Roman',
              'mono' : 'Courier New',
              'helv' : 'Arial',
              'other': 'Comic Sans MS',
              'size' : 10,
              'size2': 8,
             }
else:
    faces = { 'times': 'Times',
              'mono' : 'Courier',
              'helv' : 'Helvetica',
              'other': 'new century schoolbook',
              'size' : 12,
              'size2': 10,
             }


#----------------------------------------------------------------------

</t>
<t tx="edream.110203113231.161">class PythonSTC(wxStyledTextCtrl):
	@others
</t>
<t tx="edream.110203113231.162">def __init__(self, parent, ID):
    wxStyledTextCtrl.__init__(self, parent, ID,
                              style = wxNO_FULL_REPAINT_ON_RESIZE)

    self.CmdKeyAssign(ord('B'), wxSTC_SCMOD_CTRL, wxSTC_CMD_ZOOMIN)
    self.CmdKeyAssign(ord('N'), wxSTC_SCMOD_CTRL, wxSTC_CMD_ZOOMOUT)

    self.SetLexer(wxSTC_LEX_PYTHON)
    self.SetKeyWords(0, " ".join(keyword.kwlist))

    self.SetProperty("fold", "1")
    self.SetProperty("tab.timmy.whinge.level", "1")
    self.SetMargins(0,0)

    self.SetViewWhiteSpace(False)
    #self.SetBufferedDraw(False)
    #self.SetViewEOL(True)

    self.SetEdgeMode(wxSTC_EDGE_BACKGROUND)
    self.SetEdgeColumn(78)

    # Setup a margin to hold fold markers
    #self.SetFoldFlags(16)  ###  WHAT IS THIS VALUE?  WHAT ARE THE OTHER FLAGS?  DOES IT MATTER?
    self.SetMarginType(2, wxSTC_MARGIN_SYMBOL)
    self.SetMarginMask(2, wxSTC_MASK_FOLDERS)
    self.SetMarginSensitive(2, True)
    self.SetMarginWidth(2, 12)

    if 0: # simple folder marks, like the old version
        self.MarkerDefine(wxSTC_MARKNUM_FOLDER, wxSTC_MARK_ARROW, "navy", "navy")
        self.MarkerDefine(wxSTC_MARKNUM_FOLDEROPEN, wxSTC_MARK_ARROWDOWN, "navy", "navy")
        # Set these to an invisible mark
        self.MarkerDefine(wxSTC_MARKNUM_FOLDEROPENMID, wxSTC_MARK_BACKGROUND, "white", "black")
        self.MarkerDefine(wxSTC_MARKNUM_FOLDERMIDTAIL, wxSTC_MARK_BACKGROUND, "white", "black")
        self.MarkerDefine(wxSTC_MARKNUM_FOLDERSUB, wxSTC_MARK_BACKGROUND, "white", "black")
        self.MarkerDefine(wxSTC_MARKNUM_FOLDERTAIL, wxSTC_MARK_BACKGROUND, "white", "black")

    else: # more involved "outlining" folder marks
        self.MarkerDefine(wxSTC_MARKNUM_FOLDEREND,     wxSTC_MARK_BOXPLUSCONNECTED,  "white", "black")
        self.MarkerDefine(wxSTC_MARKNUM_FOLDEROPENMID, wxSTC_MARK_BOXMINUSCONNECTED, "white", "black")
        self.MarkerDefine(wxSTC_MARKNUM_FOLDERMIDTAIL, wxSTC_MARK_TCORNER,  "white", "black")
        self.MarkerDefine(wxSTC_MARKNUM_FOLDERTAIL,    wxSTC_MARK_LCORNER,  "white", "black")
        self.MarkerDefine(wxSTC_MARKNUM_FOLDERSUB,     wxSTC_MARK_VLINE,    "white", "black")
        self.MarkerDefine(wxSTC_MARKNUM_FOLDER,        wxSTC_MARK_BOXPLUS,  "white", "black")
        self.MarkerDefine(wxSTC_MARKNUM_FOLDEROPEN,    wxSTC_MARK_BOXMINUS, "white", "black")


    EVT_STC_UPDATEUI(self,    ID, self.OnUpdateUI)
    EVT_STC_MARGINCLICK(self, ID, self.OnMarginClick)
    EVT_KEY_DOWN(self, self.OnKeyPressed)


    # Make some styles,  The lexer defines what each style is used for, we
    # just have to define what each style looks like.  This set is adapted from
    # Scintilla sample property files.

    self.StyleClearAll()

    # Global default styles for all languages
    self.StyleSetSpec(wxSTC_STYLE_DEFAULT,     "face:%(helv)s,size:%(size)d" % faces)
    self.StyleSetSpec(wxSTC_STYLE_LINENUMBER,  "back:#C0C0C0,face:%(helv)s,size:%(size2)d" % faces)
    self.StyleSetSpec(wxSTC_STYLE_CONTROLCHAR, "face:%(other)s" % faces)
    self.StyleSetSpec(wxSTC_STYLE_BRACELIGHT,  "fore:#FFFFFF,back:#0000FF,bold")
    self.StyleSetSpec(wxSTC_STYLE_BRACEBAD,    "fore:#000000,back:#FF0000,bold")

    # Python styles
    # White space
    self.StyleSetSpec(wxSTC_P_DEFAULT, "fore:#808080,face:%(helv)s,size:%(size)d" % faces)
    # Comment
    self.StyleSetSpec(wxSTC_P_COMMENTLINE, "fore:#007F00,face:%(other)s,size:%(size)d" % faces)
    # Number
    self.StyleSetSpec(wxSTC_P_NUMBER, "fore:#007F7F,size:%(size)d" % faces)
    # String
    self.StyleSetSpec(wxSTC_P_STRING, "fore:#7F007F,italic,face:%(times)s,size:%(size)d" % faces)
    # Single quoted string
    self.StyleSetSpec(wxSTC_P_CHARACTER, "fore:#7F007F,italic,face:%(times)s,size:%(size)d" % faces)
    # Keyword
    self.StyleSetSpec(wxSTC_P_WORD, "fore:#00007F,bold,size:%(size)d" % faces)
    # Triple quotes
    self.StyleSetSpec(wxSTC_P_TRIPLE, "fore:#7F0000,size:%(size)d" % faces)
    # Triple double quotes
    self.StyleSetSpec(wxSTC_P_TRIPLEDOUBLE, "fore:#7F0000,size:%(size)d" % faces)
    # Class name definition
    self.StyleSetSpec(wxSTC_P_CLASSNAME, "fore:#0000FF,bold,underline,size:%(size)d" % faces)
    # Function or method name definition
    self.StyleSetSpec(wxSTC_P_DEFNAME, "fore:#007F7F,bold,size:%(size)d" % faces)
    # Operators
    self.StyleSetSpec(wxSTC_P_OPERATOR, "bold,size:%(size)d" % faces)
    # Identifiers
    self.StyleSetSpec(wxSTC_P_IDENTIFIER, "fore:#808080,face:%(helv)s,size:%(size)d" % faces)
    # Comment-blocks
    self.StyleSetSpec(wxSTC_P_COMMENTBLOCK, "fore:#7F7F7F,size:%(size)d" % faces)
    # End of line where string is not closed
    self.StyleSetSpec(wxSTC_P_STRINGEOL, "fore:#000000,face:%(mono)s,back:#E0C0E0,eol,size:%(size)d" % faces)

    self.SetCaretForeground("BLUE")


    # register some images for use in the AutoComplete box.
    self.RegisterImage(1, images.getSmilesBitmap())
    self.RegisterImage(2, images.getFile1Bitmap())
    self.RegisterImage(3, images.getCopyBitmap())
</t>
<t tx="edream.110203113231.163">def OnKeyPressed(self, event):
    if self.CallTipActive():
        self.CallTipCancel()
    key = event.KeyCode()
    if key == 32 and event.ControlDown():
        pos = self.GetCurrentPos()
        # Tips
        if event.ShiftDown():
            self.CallTipSetBackground("yellow")
            self.CallTipShow(pos, 'lots of of text: blah, blah, blah\n\n'
                             'show some suff, maybe parameters..\n\n'
                             'fubar(param1, param2)')
        # Code completion
        else:
            #lst = []
            #for x in range(50000):
            #    lst.append('%05d' % x)
            #st = " ".join(lst)
            #print len(st)
            #self.AutoCompShow(0, st)

            kw = keyword.kwlist[:]
            kw.append("zzzzzz?2")
            kw.append("aaaaa?2")
            kw.append("__init__?3")
            kw.append("zzaaaaa?2")
            kw.append("zzbaaaa?2")
            kw.append("this_is_a_longer_value")
            #kw.append("this_is_a_much_much_much_much_much_much_much_longer_value")

            kw.sort()  # Python sorts are case sensitive
            self.AutoCompSetIgnoreCase(False)  # so this needs to match

            # Images are specified with a appended "?type"
            for i in range(len(kw)):
                if kw[i] in keyword.kwlist:
                    kw[i] = kw[i] + "?1"

            self.AutoCompShow(0, " ".join(kw))
    else:
        event.Skip()
</t>
<t tx="edream.110203113231.164">def OnUpdateUI(self, evt):
    # check for matching braces
    braceAtCaret = -1
    braceOpposite = -1
    charBefore = None
    caretPos = self.GetCurrentPos()
    if caretPos &gt; 0:
        charBefore = self.GetCharAt(caretPos - 1)
        styleBefore = self.GetStyleAt(caretPos - 1)

    # check before
    if charBefore and chr(charBefore) in "[]{}()" and styleBefore == wxSTC_P_OPERATOR:
        braceAtCaret = caretPos - 1

    # check after
    if braceAtCaret &lt; 0:
        charAfter = self.GetCharAt(caretPos)
        styleAfter = self.GetStyleAt(caretPos)
        if charAfter and chr(charAfter) in "[]{}()" and styleAfter == wxSTC_P_OPERATOR:
            braceAtCaret = caretPos

    if braceAtCaret &gt;= 0:
        braceOpposite = self.BraceMatch(braceAtCaret)

    if braceAtCaret != -1  and braceOpposite == -1:
        self.BraceBadLight(braceAtCaret)
    else:
        self.BraceHighlight(braceAtCaret, braceOpposite)
</t>
<t tx="edream.110203113231.165">        #pt = self.PointFromPosition(braceOpposite)
        #self.Refresh(True, wxRect(pt.x, pt.y, 5,5))
        #print pt
        #self.Refresh(False)


def OnMarginClick(self, evt):
    # fold and unfold as needed
    if evt.GetMargin() == 2:
        if evt.GetShift() and evt.GetControl():
            self.FoldAll()
        else:
            lineClicked = self.LineFromPosition(evt.GetPosition())
            if self.GetFoldLevel(lineClicked) &amp; wxSTC_FOLDLEVELHEADERFLAG:
                if evt.GetShift():
                    self.SetFoldExpanded(lineClicked, True)
                    self.Expand(lineClicked, True, True, 1)
                elif evt.GetControl():
                    if self.GetFoldExpanded(lineClicked):
                        self.SetFoldExpanded(lineClicked, False)
                        self.Expand(lineClicked, False, True, 0)
                    else:
                        self.SetFoldExpanded(lineClicked, True)
                        self.Expand(lineClicked, True, True, 100)
                else:
                    self.ToggleFold(lineClicked)
</t>
<t tx="edream.110203113231.166">def FoldAll(self):
    lineCount = self.GetLineCount()
    expanding = True

    # find out if we are folding or unfolding
    for lineNum in range(lineCount):
        if self.GetFoldLevel(lineNum) &amp; wxSTC_FOLDLEVELHEADERFLAG:
            expanding = not self.GetFoldExpanded(lineNum)
            break;

    lineNum = 0
    while lineNum &lt; lineCount:
        level = self.GetFoldLevel(lineNum)
        if level &amp; wxSTC_FOLDLEVELHEADERFLAG and \
           (level &amp; wxSTC_FOLDLEVELNUMBERMASK) == wxSTC_FOLDLEVELBASE:

            if expanding:
                self.SetFoldExpanded(lineNum, True)
                lineNum = self.Expand(lineNum, True)
                lineNum = lineNum - 1
            else:
                lastChild = self.GetLastChild(lineNum, -1)
                self.SetFoldExpanded(lineNum, False)
                if lastChild &gt; lineNum:
                    self.HideLines(lineNum+1, lastChild)

        lineNum = lineNum + 1
</t>
<t tx="edream.110203113231.167">def Expand(self, line, doExpand, force=False, visLevels=0, level=-1):
    lastChild = self.GetLastChild(line, level)
    line = line + 1
    while line &lt;= lastChild:
        if force:
            if visLevels &gt; 0:
                self.ShowLines(line, line)
            else:
                self.HideLines(line, line)
        else:
            if doExpand:
                self.ShowLines(line, line)

        if level == -1:
            level = self.GetFoldLevel(line)

        if level &amp; wxSTC_FOLDLEVELHEADERFLAG:
            if force:
                if visLevels &gt; 1:
                    self.SetFoldExpanded(line, True)
                else:
                    self.SetFoldExpanded(line, False)
                line = self.Expand(line, doExpand, force, visLevels-1)

            else:
                if doExpand and self.GetFoldExpanded(line):
                    line = self.Expand(line, True, force, visLevels-1)
                else:
                    line = self.Expand(line, False, force, visLevels-1)
        else:
            line = line + 1;

    return line
</t>
<t tx="edream.110203113231.168">#----------------------------------------------------------------------

_USE_PANEL = 1

def runTest(frame, nb, log):
    if not _USE_PANEL:
        ed = p = PythonSTC(nb, -1)
    else:
        p = wxPanel(nb, -1, style = wxNO_FULL_REPAINT_ON_RESIZE)
        ed = PythonSTC(p, -1)
        s = wxBoxSizer(wxHORIZONTAL)
        s.Add(ed, 1, wxEXPAND)
        p.SetSizer(s)
        p.SetAutoLayout(True)


    ed.SetText(demoText + open('Main.py').read())
    ed.EmptyUndoBuffer()
    ed.Colourise(0, -1)

    # line numbers in the margin
    ed.SetMarginType(1, wxSTC_MARGIN_NUMBER)
    ed.SetMarginWidth(1, 25)

    return p
</t>
<t tx="edream.110203113231.169">@ignore
@language python
&lt;&lt; wxTextCtrl declarations &gt;&gt;
@others

#---------------------------------------------------------------------------




overview = """\
"""




if __name__ == '__main__':
    import sys,os
    import run
    run.main(['', os.path.basename(sys.argv[0])])

</t>
<t tx="edream.110203113231.170">import sys
from wxPython.wx import *

#---------------------------------------------------------------------------

</t>
<t tx="edream.110203113231.171">class TestPanel(wxPanel):
	@others
</t>
<t tx="edream.110203113231.172">def OnSetFocus(self, evt):
    print "OnSetFocus"
    evt.Skip()
</t>
<t tx="edream.110203113231.173">def OnKillFocus(self, evt):
    print "OnKillFocus"
    evt.Skip()
</t>
<t tx="edream.110203113231.174">def OnWindowDestroy(self, evt):
    print "OnWindowDestroy"
    evt.Skip()
</t>
<t tx="edream.110203113231.175">def __init__(self, parent, log):
    wxPanel.__init__(self, parent, -1)
    self.log = log

    l1 = wxStaticText(self, -1, "wxTextCtrl")
    t1 = wxTextCtrl(self, -1, "Test it out and see", size=(125, -1))
    t1.SetInsertionPoint(0)
    self.tc1 = t1
    EVT_TEXT(self, t1.GetId(), self.EvtText)
    EVT_CHAR(t1, self.EvtChar)
    EVT_SET_FOCUS(t1, self.OnSetFocus)
    EVT_KILL_FOCUS(t1, self.OnKillFocus)
    EVT_WINDOW_DESTROY(t1, self.OnWindowDestroy)

    l2 = wxStaticText(self, -1, "Passsword")
    t2 = wxTextCtrl(self, -1, "", size=(125, -1), style=wxTE_PASSWORD)
    EVT_TEXT(self, t2.GetId(), self.EvtText)

    l3 = wxStaticText(self, -1, "Multi-line")
    t3 = wxTextCtrl(self, -1,
                    "Here is a looooooooooooooong line of text set in the control.\n\n"
                    "The quick brown fox jumped over the lazy dog...",
                   size=(200, 100), style=wxTE_MULTILINE)
    t3.SetInsertionPoint(0)
    EVT_TEXT(self, t3.GetId(), self.EvtText)
    b = wxButton(self, -1, "Test Replace")
    EVT_BUTTON(self, b.GetId(), self.OnTestReplace)
    b2 = wxButton(self, -1, "Test GetSelection")
    EVT_BUTTON(self, b2.GetId(), self.OnTestGetSelection)
    b3 = wxButton(self, -1, "Test WriteText")
    EVT_BUTTON(self, b3.GetId(), self.OnTestWriteText)
    self.tc = t3
    b4 = wxButton(self, -1, "Test Simulated Event")
    EVT_BUTTON(self, b4.GetId(), self.OnTestEvent)


    l4 = wxStaticText(self, -1, "Rich Text")
    t4 = wxTextCtrl(self, -1, "If supported by the native control, this is red, and this is a different font.",
                    size=(200, 100), style=wxTE_MULTILINE|wxTE_RICH2)
    t4.SetInsertionPoint(0)
    t4.SetStyle(44, 47, wxTextAttr("RED", "YELLOW"))
    points = t4.GetFont().GetPointSize()  # get the current size
    f = wxFont(points+3, wxROMAN, wxITALIC, wxBOLD, True)
    t4.SetStyle(63, 77, wxTextAttr("BLUE", wxNullColour, f))

    l5 = wxStaticText(self, -1, "Test Positions")
    t5 = wxTextCtrl(self, -1, "0123456789\n" * 5, size=(200, 100),
                    style = wxTE_MULTILINE
                    #| wxTE_RICH
                    | wxTE_RICH2
                    )
    EVT_LEFT_DOWN(t5, self.OnT5LeftDown)
    self.t5 = t5


    bsizer = wxBoxSizer(wxVERTICAL)
    bsizer.Add(b, 0, wxGROW|wxALL, 4)
    bsizer.Add(b2, 0, wxGROW|wxALL, 4)
    bsizer.Add(b3, 0, wxGROW|wxALL, 4)
    bsizer.Add(b4, 0, wxGROW|wxALL, 4)

    sizer = wxFlexGridSizer(cols=3, hgap=6, vgap=6)
    sizer.AddMany([ l1, t1, (0,0),
                    l2, t2, (0,0),
                    l3, t3, bsizer,
                    l4, t4, (0,0),
                    l5, t5, (0,0),
                    ])
    border = wxBoxSizer(wxVERTICAL)
    border.Add(sizer, 0, wxALL, 25)
    self.SetSizer(border)
    self.SetAutoLayout(True)
</t>
<t tx="edream.110203113231.176">def EvtText(self, event):
    self.log.WriteText('EvtText: %s\n' % event.GetString())
</t>
<t tx="edream.110203113231.177">def EvtChar(self, event):
    self.log.WriteText('EvtChar: %d\n' % event.GetKeyCode())
    event.Skip()
</t>
<t tx="edream.110203113231.178">def OnTestReplace(self, evt):
    self.tc.Replace(5, 9, "IS A")
</t>
<t tx="edream.110203113231.179">    #self.tc.Remove(5, 9)

def OnTestWriteText(self, evt):
    self.tc.WriteText("TEXT")
</t>
<t tx="edream.110203113231.180">def OnTestGetSelection(self, evt):
    start, end = self.tc.GetSelection()
    text = self.tc.GetValue()
    if wxPlatform == "__WXMSW__":  # This is why GetStringSelection was added
        text = text.replace('\n', '\r\n')
    self.log.write("GetSelection(): (%d, %d)\n"
                   "\tGetStringSelection(): %s\n"
                   "\tSelectedText: %s\n" %
                   (start, end,
                    self.tc.GetStringSelection(),
                    repr(text[start:end])))
</t>
<t tx="edream.110203113231.181">def OnT5LeftDown(self, evt):
    evt.Skip()
    wxCallAfter(self.LogT5Position, evt)
</t>
<t tx="edream.110203113231.182">def LogT5Position(self, evt):
    text = self.t5.GetValue()
    ip = self.t5.GetInsertionPoint()
    lp = self.t5.GetLastPosition()
    self.log.write("LogT5Position:\n"
                   "\tGetInsertionPoint:\t%d\n"
                   "\ttext[insertionpoint]:\t%s\n"
                   "\tGetLastPosition:\t%d\n"
                   "\tlen(text):\t\t%d\n"
                   % (ip, text[ip], lp, len(text)))
</t>
<t tx="edream.110203113231.183">def OnTestEvent(self, evt):
    ke = wxKeyEvent(wxEVT_CHAR)
    ke.SetEventObject(self.tc1)
    ke.SetId(self.tc1.GetId())
    ke.m_keyCode = ord('A')
    self.tc1.GetEventHandler().ProcessEvent(ke)
</t>
<t tx="edream.110203113231.184">#---------------------------------------------------------------------------

def runTest(frame, nb, log):
    win = TestPanel(nb, log)
    return win
</t>
<t tx="edream.110203113231.185"></t>
<t tx="edream.110203113231.186">@ignore
@language python

import sys, os
from   wxPython.wx         import *
from   wxPython.html       import *
import wxPython.lib.wxpTag
from Main import opj

@others

overview = """&lt;html&gt;&lt;body&gt;
&lt;h2&gt;wxHtmlWindow&lt;/h2&gt;

&lt;p&gt;wxHtmlWindow is capable of parsing and rendering most
simple HTML tags.

&lt;p&gt;It is not intended to be a high-end HTML browser.  If you're
looking for something like that try http://www.mozilla.org - there's a
chance you'll be able to make their widget wxWindows-compatible. I'm
sure everyone will enjoy your work in that case...

&lt;/body&gt;&lt;/html&gt;
"""

if __name__ == '__main__':
    import sys,os,run
    run.main(['', os.path.basename(sys.argv[0])])
</t>
<t tx="edream.110203113231.187"># This shows how to catch the OnLinkClicked non-event.  (It's a virtual
# method in the C++ code...)

class MyHtmlWindow(wxHtmlWindow):
	@others
</t>
<t tx="edream.110203113231.188">def __init__(self, parent, id, log):
    wxHtmlWindow.__init__(self, parent, id, style=wxNO_FULL_REPAINT_ON_RESIZE)
    self.log = log
    EVT_SCROLLWIN( self, self.OnScroll )
</t>
<t tx="edream.110203113231.189">def OnScroll( self, event ):
    #print 'event.GetOrientation()',event.GetOrientation()
    #print 'event.GetPosition()',event.GetPosition()
    event.Skip()
</t>
<t tx="edream.110203113231.190">def OnLinkClicked(self, linkinfo):
    self.log.WriteText('OnLinkClicked: %s\n' % linkinfo.GetHref())

    # Virtuals in the base class have been renamed with base_ on the front.
    self.base_OnLinkClicked(linkinfo)
</t>
<t tx="edream.110203113231.191">def OnSetTitle(self, title):
    self.log.WriteText('OnSetTitle: %s\n' % title)
    self.base_OnSetTitle(title)
</t>
<t tx="edream.110203113231.192">def OnCellMouseHover(self, cell, x, y):
    self.log.WriteText('OnCellMouseHover: %s, (%d %d)\n' % (cell, x, y))
    self.base_OnCellMouseHover(cell, x, y)
</t>
<t tx="edream.110203113231.193">def OnCellClicked(self, cell, x, y, evt):
    self.log.WriteText('OnCellClicked: %s, (%d %d)\n' % (cell, x, y))
    self.base_OnCellClicked(cell, x, y, evt)
</t>
<t tx="edream.110203113231.194"># This filter doesn't really do anything but show how to use filters
class MyHtmlFilter(wxHtmlFilter):
	@others
</t>
<t tx="edream.110203113231.195">def __init__(self, log):
    wxHtmlFilter.__init__(self)
    self.log = log
</t>
<t tx="edream.110203113231.196"># This method decides if this filter is able to read the file
def CanRead(self, fsfile):
    self.log.write("CanRead: %s\n" % fsfile.GetMimeType())
    return False
</t>
<t tx="edream.110203113231.197"># If CanRead returns True then this method is called to actually
# read the file and return the contents.
def ReadFile(self, fsfile):
    return ""
</t>
<t tx="edream.110203113231.198">class TestHtmlPanel(wxPanel):
	@others
</t>
<t tx="edream.110203113231.199">def __init__(self, parent, frame, log):
    wxPanel.__init__(self, parent, -1, style=wxNO_FULL_REPAINT_ON_RESIZE)
    self.log = log
    self.frame = frame
    self.cwd = os.path.split(sys.argv[0])[0]
    if not self.cwd:
        self.cwd = os.getcwd()
    if frame:
        self.titleBase = frame.GetTitle()

    wxHtmlWindow_AddFilter(MyHtmlFilter(log))

    self.html = MyHtmlWindow(self, -1, log)
    self.html.SetRelatedFrame(frame, self.titleBase + " -- %s")
    self.html.SetRelatedStatusBar(0)

    self.printer = wxHtmlEasyPrinting()

    self.box = wxBoxSizer(wxVERTICAL)
    self.box.Add(self.html, 1, wxGROW)

    subbox = wxBoxSizer(wxHORIZONTAL)

    btn = wxButton(self, -1, "Load File")
    EVT_BUTTON(self, btn.GetId(), self.OnLoadFile)
    subbox.Add(btn, 1, wxGROW | wxALL, 2)

    btn = wxButton(self, -1, "Load URL")
    EVT_BUTTON(self, btn.GetId(), self.OnLoadURL)
    subbox.Add(btn, 1, wxGROW | wxALL, 2)

    btn = wxButton(self, -1, "With Widgets")
    EVT_BUTTON(self, btn.GetId(), self.OnWithWidgets)
    subbox.Add(btn, 1, wxGROW | wxALL, 2)

    btn = wxButton(self, -1, "Back")
    EVT_BUTTON(self, btn.GetId(), self.OnBack)
    subbox.Add(btn, 1, wxGROW | wxALL, 2)

    btn = wxButton(self, -1, "Forward")
    EVT_BUTTON(self, btn.GetId(), self.OnForward)
    subbox.Add(btn, 1, wxGROW | wxALL, 2)

    btn = wxButton(self, -1, "Print")
    EVT_BUTTON(self, btn.GetId(), self.OnPrint)
    subbox.Add(btn, 1, wxGROW | wxALL, 2)

    btn = wxButton(self, -1, "View Source")
    EVT_BUTTON(self, btn.GetId(), self.OnViewSource)
    subbox.Add(btn, 1, wxGROW | wxALL, 2)

    self.box.Add(subbox, 0, wxGROW)
    self.SetSizer(self.box)
    self.SetAutoLayout(True)

    # A button with this ID is created on the widget test page.
    EVT_BUTTON(self, wxID_OK, self.OnOk)

    self.OnShowDefault(None)
</t>
<t tx="edream.110203113231.200">def ShutdownDemo(self):
    # put the frame title back
    if self.frame:
        self.frame.SetTitle(self.titleBase)
</t>
<t tx="edream.110203113231.201">def OnShowDefault(self, event):
    name = os.path.join(self.cwd, opj('data/test.htm'))
    self.html.LoadPage(name)
</t>
<t tx="edream.110203113231.202">def OnLoadFile(self, event):
    dlg = wxFileDialog(self, wildcard = '*.htm*', style=wxOPEN)
    if dlg.ShowModal():
        path = dlg.GetPath()
        self.html.LoadPage(path)
    dlg.Destroy()
</t>
<t tx="edream.110203113231.203">def OnLoadURL(self, event):
    dlg = wxTextEntryDialog(self, "Enter a URL")
    if dlg.ShowModal():
        url = dlg.GetValue()
        self.html.LoadPage(url)
    dlg.Destroy()
</t>
<t tx="edream.110203113231.204">def OnWithWidgets(self, event):
    os.chdir(self.cwd)
    name = os.path.join(self.cwd, opj('data/widgetTest.htm'))
    self.html.LoadPage(name)
</t>
<t tx="edream.110203113231.205">def OnOk(self, event):
    self.log.WriteText("It works!\n")
</t>
<t tx="edream.110203113231.206">def OnBack(self, event):
    if not self.html.HistoryBack():
        wxMessageBox("No more items in history!")
</t>
<t tx="edream.110203113231.207">def OnForward(self, event):
    if not self.html.HistoryForward():
        wxMessageBox("No more items in history!")
</t>
<t tx="edream.110203113231.208">def OnViewSource(self, event):
    from wxPython.lib.dialogs import wxScrolledMessageDialog
    source = self.html.GetParser().GetSource()
    dlg = wxScrolledMessageDialog(self, source, 'HTML Source')
    dlg.ShowModal()
    dlg.Destroy()
</t>
<t tx="edream.110203113231.209">def OnPrint(self, event):
    ##self.printer.GetPageSetupData().SetMarginTopLeft((100,100))
    self.printer.PrintFile(self.html.GetOpenedPage())
</t>
<t tx="edream.110203113231.210">def runTest(frame, nb, log):
    win = TestHtmlPanel(nb, frame, log)
    print wxWindow_FindFocus()
    return win
</t>
<t tx="edream.110203113231.211">@ignore
@language python

from wxPython.wx import *
if wxPlatform == '__WXMSW__':
    from wxPython.iewin import *

@others



overview = """\
&lt;html&gt;&lt;body&gt;
&lt;h2&gt;wxIEHtmlWin&lt;/h2&gt;

The wxIEHtmlWin class is the first example of using a contributed
wxActiveX class in wxWindows C++.  It is still experimental, but
I think it is useful.

&lt;p&gt; Using this class is simpler than ActiveXWrapper, doesn't rely on
the win32all extensions, and is more "wx\'ish", meaning that it uses
events and etc. as would be expected from any other wx window.

&lt;/body&gt;&lt;/html&gt;
"""



if __name__ == '__main__':
    import sys,os
    import run
    run.main(['', os.path.basename(sys.argv[0])])


#----------------------------------------------------------------------

</t>
<t tx="edream.110203113231.212">class TestPanel(wxWindow):
	@others
</t>
<t tx="edream.110203113231.213">def __init__(self, parent, log, frame=None):
    wxWindow.__init__(self, parent, -1,
                      style=wxTAB_TRAVERSAL|wxCLIP_CHILDREN|wxNO_FULL_REPAINT_ON_RESIZE)
    self.log = log
    self.current = "http://wxWindows.org/"
    self.frame = frame
    if frame:
        self.titleBase = frame.GetTitle()


    sizer = wxBoxSizer(wxVERTICAL)
    btnSizer = wxBoxSizer(wxHORIZONTAL)

    self.ie = wxIEHtmlWin(self, -1, style = wxNO_FULL_REPAINT_ON_RESIZE)


    btn = wxButton(self, wxNewId(), "Open", style=wxBU_EXACTFIT)
    EVT_BUTTON(self, btn.GetId(), self.OnOpenButton)
    btnSizer.Add(btn, 0, wxEXPAND|wxALL, 2)

    btn = wxButton(self, wxNewId(), "Home", style=wxBU_EXACTFIT)
    EVT_BUTTON(self, btn.GetId(), self.OnHomeButton)
    btnSizer.Add(btn, 0, wxEXPAND|wxALL, 2)

    btn = wxButton(self, wxNewId(), "&lt;--", style=wxBU_EXACTFIT)
    EVT_BUTTON(self, btn.GetId(), self.OnPrevPageButton)
    btnSizer.Add(btn, 0, wxEXPAND|wxALL, 2)

    btn = wxButton(self, wxNewId(), "--&gt;", style=wxBU_EXACTFIT)
    EVT_BUTTON(self, btn.GetId(), self.OnNextPageButton)
    btnSizer.Add(btn, 0, wxEXPAND|wxALL, 2)

    btn = wxButton(self, wxNewId(), "Stop", style=wxBU_EXACTFIT)
    EVT_BUTTON(self, btn.GetId(), self.OnStopButton)
    btnSizer.Add(btn, 0, wxEXPAND|wxALL, 2)

    btn = wxButton(self, wxNewId(), "Search", style=wxBU_EXACTFIT)
    EVT_BUTTON(self, btn.GetId(), self.OnSearchPageButton)
    btnSizer.Add(btn, 0, wxEXPAND|wxALL, 2)

    btn = wxButton(self, wxNewId(), "Refresh", style=wxBU_EXACTFIT)
    EVT_BUTTON(self, btn.GetId(), self.OnRefreshPageButton)
    btnSizer.Add(btn, 0, wxEXPAND|wxALL, 2)

    txt = wxStaticText(self, -1, "Location:")
    btnSizer.Add(txt, 0, wxCENTER|wxALL, 2)

    self.location = wxComboBox(self, wxNewId(), "", style=wxCB_DROPDOWN|wxPROCESS_ENTER)
    EVT_COMBOBOX(self, self.location.GetId(), self.OnLocationSelect)
    EVT_KEY_UP(self.location, self.OnLocationKey)
    EVT_CHAR(self.location, self.IgnoreReturn)
    btnSizer.Add(self.location, 1, wxEXPAND|wxALL, 2)


    sizer.Add(btnSizer, 0, wxEXPAND)
    sizer.Add(self.ie, 1, wxEXPAND)

    self.ie.Navigate(self.current)
    self.location.Append(self.current)

    self.SetSizer(sizer)
    self.SetAutoLayout(True)
    EVT_SIZE(self, self.OnSize)

    # Hook up the event handlers for the IE window
    EVT_MSHTML_BEFORENAVIGATE2(self, -1, self.OnBeforeNavigate2)
    EVT_MSHTML_NEWWINDOW2(self, -1, self.OnNewWindow2)
    EVT_MSHTML_DOCUMENTCOMPLETE(self, -1, self.OnDocumentComplete)
    #EVT_MSHTML_PROGRESSCHANGE(self, -1, self.OnProgressChange)
    EVT_MSHTML_STATUSTEXTCHANGE(self, -1, self.OnStatusTextChange)
    EVT_MSHTML_TITLECHANGE(self, -1, self.OnTitleChange)
</t>
<t tx="edream.110203113231.214">def ShutdownDemo(self):
    # put the frame title back
    if self.frame:
        self.frame.SetTitle(self.titleBase)
</t>
<t tx="edream.110203113231.215">def OnSize(self, evt):
    self.Layout()
</t>
<t tx="edream.110203113231.216">def OnLocationSelect(self, evt):
    url = self.location.GetStringSelection()
    self.log.write('OnLocationSelect: %s\n' % url)
    self.ie.Navigate(url)
</t>
<t tx="edream.110203113231.217">def OnLocationKey(self, evt):
    if evt.KeyCode() == WXK_RETURN:
        URL = self.location.GetValue()
        self.location.Append(URL)
        self.ie.Navigate(URL)
    else:
        evt.Skip()
</t>
<t tx="edream.110203113231.218">def IgnoreReturn(self, evt):
    if evt.GetKeyCode() != WXK_RETURN:
        evt.Skip()
</t>
<t tx="edream.110203113231.219">def OnOpenButton(self, event):
    dlg = wxTextEntryDialog(self, "Open Location",
                            "Enter a full URL or local path",
                            self.current, wxOK|wxCANCEL)
    dlg.CentreOnParent()
    if dlg.ShowModal() == wxID_OK:
        self.current = dlg.GetValue()
        self.ie.Navigate(self.current)
    dlg.Destroy()
</t>
<t tx="edream.110203113231.220">def OnHomeButton(self, event):
    self.ie.GoHome()    ## ET Phone Home!
</t>
<t tx="edream.110203113231.221">def OnPrevPageButton(self, event):
    self.ie.GoBack()
</t>
<t tx="edream.110203113231.222">def OnNextPageButton(self, event):
    self.ie.GoForward()
</t>
<t tx="edream.110203113231.223">def OnStopButton(self, evt):
    self.ie.Stop()
</t>
<t tx="edream.110203113231.224">def OnSearchPageButton(self, evt):
    self.ie.GoSearch()
</t>
<t tx="edream.110203113231.225">def OnRefreshPageButton(self, evt):
    self.ie.Refresh(wxIEHTML_REFRESH_COMPLETELY)
</t>
<t tx="edream.110203113231.226">def logEvt(self, name, event):
    self.log.write('%s: %s\n' %
                   (name, (event.GetLong1(), event.GetLong2(), event.GetText1())))
</t>
<t tx="edream.110203113231.227">def OnBeforeNavigate2(self, evt):
    self.logEvt('OnBeforeNavigate2', evt)
</t>
<t tx="edream.110203113231.228">def OnNewWindow2(self, evt):
    self.logEvt('OnNewWindow2', evt)
    evt.Veto() # don't allow it
</t>
<t tx="edream.110203113231.229">def OnDocumentComplete(self, evt):
    self.logEvt('OnDocumentComplete', evt)
    self.current = evt.GetText1()
    self.location.SetValue(self.current)
</t>
<t tx="edream.110203113231.230">def OnTitleChange(self, evt):
    self.logEvt('OnTitleChange', evt)
    if self.frame:
        self.frame.SetTitle(self.titleBase + ' -- ' + evt.GetText1())
</t>
<t tx="edream.110203113231.231">def OnStatusTextChange(self, evt):
    self.logEvt('OnStatusTextChange', evt)
    if self.frame:
        self.frame.SetStatusText(evt.GetText1())
</t>
<t tx="edream.110203113231.232"># for the demo framework...

def runTest(frame, nb, log):
    if wxPlatform == '__WXMSW__':
        win = TestPanel(nb, log, frame)
        return win
    else:
        dlg = wxMessageDialog(frame, 'This demo only works on MSW.',
                          'Sorry', wxOK | wxICON_INFORMATION)
        dlg.ShowModal()
        dlg.Destroy()</t>
<t tx="edream.110203113231.233">@ To do:
	
*** WARNING: problems with locking out event handlers could cause Leo to drop Text!
	- Do not trust this version of Leo with important data !!!
	
- The find logic doesn't properly show the found selection (or the correct body text).
	- Remove traces.

- Replace body widget with something better.

- Update joined headlines when any headline changes.

- Minor:
	- Finish all callbacks.
	- Finish dragging code.
	- Handle exception when starting by double-clicking LeoPy.leo.</t>
<t tx="edream.110203113231.234">@nocolor</t>
<t tx="edream.110203113231.235"></t>
<t tx="edream.110203113231.236">
</t>
<t tx="edream.110203113231.237">

- Almost all events connected properly.
- Code draws the screen (after the file has been read in!)
- Removed idle-time pollution: created onUpdateAllMenus.</t>
<t tx="edream.110203113231.238"></t>
<t tx="edream.110203113231.242"></t>
<t tx="edream.110203113231.243"># Used 10/11/03 to convert old wxLeo code 

if 0: # This script calls c2py on the current node and all nodes of its subtree.
	import c2py
	c2py.convertCurrentTree()</t>
<t tx="edream.110203113231.257"># This updates the text of joined _headlines_, not body text.

if 0: # no longer used

	def updateJoinedHeadlines(self,text,v):
		guard = 0
		if guard &gt; 0: return
		guard += 1
		v2 = v.joinList()
		while v2 and v2 != v:
			id = v2.treeID()
			assert(id)
			self.tree.SetItemText(id,text)
			v2 = v2.joinList()
		guard -= 1</t>
<t tx="edream.110203113231.259">cSplitterWidth = 600

const_dict = {}
const_lastVal = 100 # Starting wx id.

def const(name):
	
	"""Return the wx id associated with name"""
	
	# Should this canonicalize the label?  Just remove '&amp;' ??
	
	id = const_dict.get(name)
	if id != None:
		return id
	else:
		global const_lastVal
		const_lastVal += 1
		const_dict[name] = const_lastVal
		# trace(name,const_lastVal)
		return const_lastVal</t>
<t tx="edream.110203113231.260">def finishCreate (self,c):
	
	frame = self
	frame.c = c
	c.frame = frame
	
	# Init the wxFrame base class.  The leoFrame base class has already been inited.
	wx.wxFrame.__init__(self, None, -1, self.title) # wx.wxNO_3D # hangs.
	#self.outerPanel = wx.wxPanel(self,-1)
	#self.iconPanel = wx.wxPanel(self.outerPanel, -1, "iconPanel")

	self.CreateStatusBar()

	&lt;&lt; create the splitters &gt;&gt;
	frame.tree = wxLeoTree(frame,self.splitter2)
	frame.log = wxLeoLog(frame,self.splitter2)
	frame.body = wxLeoBody(frame,self.splitter1)
	frame.bodyCtrl = frame.body
	# Attach the controls to the splitter.
	self.splitter1.SplitHorizontally(self.splitter2,self.body.bodyCtrl,0)
	self.splitter2.SplitVertically(self.tree.treeCtrl,self.log.logCtrl,cSplitterWidth/2)
	
	self.menu = wxLeoMenu(frame)
	self.menu.createMenuBar()
	
	&lt;&lt; set the window icon &gt;&gt;
	&lt;&lt; declare event handlers for frame &gt;&gt;
	
	if 0: # Not ready yet...
		self.wxApp.SetTopWindow(self.wxFrame)
		self.wxFrame.Show(true)
		if not app.root:
			app.root = self.wxFrame
			
	self.colorizer = leoColor.colorizer(c)
			
	c.initVersion()
	self.signOnWithVersion()
	
	self.injectCallbacks()

	# Add the frame to the global window list.
	app.windowList.append(self)
	self.tree.redraw()
	self.Show(true) # required on some platforms: a cross-platform bug.</t>
<t tx="edream.110203113231.261">self.splitter1 = wx.wxSplitterWindow(self,
	const("cSplitterWindow"),
	wx.wxDefaultPosition, wx.wxDefaultSize,
	wx.wxSP_NOBORDER)

# No effect, except to create a red flash.
if 0:
	self.splitter1.SetForegroundColour(wx.wxRED)
	self.splitter1.SetBackgroundColour(wx.wxRED)

self.splitter2 = wx.wxSplitterWindow(self.splitter1, -1,
	wx.wxDefaultPosition, wx.wxDefaultSize,
	wx.wxSP_NOBORDER)
	# wx.wxSP_BORDER | wx.wxSP_3D, "splitterWindow");

self.splitter1.SetMinimumPaneSize(4)
self.splitter2.SetMinimumPaneSize(4)</t>
<t tx="edream.110203113231.264">if wx.wxPlatform == "__WXMSW__": # Activate events exist only on Windows.
	wx.EVT_ACTIVATE(self,self.onActivate)
else:
	wx.EVT_SET_FOCUS(self,self.OnSetFocus)

wx.EVT_CLOSE(self,self.onCloseLeoFrame)

wx.EVT_MENU_OPEN(self,self.updateAllMenus) 

if 0: # Causes problems at present.  The screen isn't drawn properly.
	wx.EVT_SIZE(self,self.onResize)</t>
<t tx="edream.110203113231.265">if wx.wxPlatform == "__WXMSW__":

	path = os.path.join(app.loadDir,"..","Icons","LeoApp16.ico")
	icon = wx.wxIcon(path,wx.wxBITMAP_TYPE_ICO,16,16)
	self.SetIcon(icon)
</t>
<t tx="edream.110203113231.266">def __init__ (self,title):
	
	# Init the leoFrame base class.
	# We will init the wxFrame base class in finishCreate.
	leoFrame.leoFrame.__init__(self)
	
	self.c = None # set in finishCreate.
	self.bodyCtrl = None # set in finishCreate
	self.title = title
	
	# trace("wxLeoFrame",title)
	self.activeFrame = None
	self.lockout = 0 # Suppress further events
	self.quitting = false
	self.updateCount = 0
	self.treeIniting = false
	self.drawing = false # Lockout recursive draws.
	self.menuIdDict = {}
	self.menuBar = None
	self.ratio = 0.5
	self.secondary_ratio = 0.5
	self.startupWindow=false
	self.use_coloring = false # set true to enable coloring
	
	# These vars have corresponding getters/setters.
	if 0: # now defined in base tree class.
		self.mDragging = false
		self.mRootVnode = None
		self.mTopVnode = None
		self.mCurrentVnode = None</t>
<t tx="edream.110203113231.267"></t>
<t tx="edream.110203113231.268"></t>
<t tx="edream.110203113231.269">if wx.wxPlatform == '__WXMSW__':
	
	def onActivate(self,event):
		if event.GetActive():
			self.activeFrame = self
			if self.c:
				pass ## self.c.checkAllFileDates()
else:
	
	def OnSetFocus(self,event):
		self.activeFrame = self
		if self.c:
			self.c.checkAllFileDates()
</t>
<t tx="edream.110203113231.270">def onCloseLeoFrame(self,event):

	frame = self
	
	# The app class does all the hard work now.
	if not app.closeLeoWindow(frame):
		if event.CanVeto():
			event.Veto()</t>
<t tx="edream.110203113231.273">def onResize(self,event):

	if mIniting:
		return # Can be called during initialization.

	# Resize splitter1 with equal sized panes.
	size = self.splitter1.GetClientSize()
	self.splitter1.SetClientSize(size)
	w = size.GetWidth() ; h = size.GetHeight()
	if self.splitter1.GetSplitMode()== wx.wxSPLIT_VERTICAL:
		self.splitter1.SetSashPosition(w/2,true)
	else:
		self.splitter1.SetSashPosition(h/2,true)

	# Resize splitter2 with equal sized panes.
	size = self.splitter2.GetClientSize()
	w = size.GetWidth() ; h = size.GetHeight()
	if self.splitter2.GetSplitMode()== wx.wxSPLIT_VERTICAL:
		self.splitter2.SetSashPosition((3*w)/5,true)
	else:
		self.splitter2.SetSashPosition((3*h)/5,true)
</t>
<t tx="edream.110203113231.275">def onBodyTextUpdated(self,event):

	frame = self.frame ; c = self.c
	if not c:  return
	v = c.currentVnode()
	if not v: return
	if self.frame.lockout &gt; 0: return
	
	# Similar to idle_body_key
	self.frame.lockout += 1

	s = frame.body.bodyCtrl.GetValue()
	v.t.setTnodeText(s)
	v.t.insertSpot = c.frame.body.getInsertionPoint()
	&lt;&lt; recolor the body &gt;&gt;
	if not c.changed:
		c.setChanged(true)
	&lt;&lt; redraw the screen if necessary &gt;&gt;
	if 0: # ch, etc. are not defined.
		doHook("bodykey2",c=c,v=v,ch=ch,oldSel=oldSel,undoType=undoType)
		
	self.frame.lockout -= 1</t>
<t tx="edream.110203113231.278"></t>
<t tx="edream.110203113231.279"></t>
<t tx="edream.110203113231.280">def onTreeCollapsed(self,event):
	
	"""Prepare to collapse the tree."""

	pass # No need to redraw the tree.

def onTreeExpanded (self,event):
	
	"""Redraw the tree when a tree collapses."""

	if not self.frame.lockout and not self.drawing:

		self.redraw()</t>
<t tx="edream.110203113231.281">def onTreeCollapsing(self,event):
	
	"""Call v.contract for a later redraw."""

	tree = self.treeCtrl
	id = event.GetItem()
	if id.IsOk and not self.frame.lockout:
		v = tree.GetItemData(id).GetData()
		if v:
			#trace(v)
			v.contract()
	
def onTreeExpanding (self,event):
	
	"""Call v.expand for a later redraw."""
	
	tree = self.treeCtrl
	id = event.GetItem()
	if id.IsOk and not self.frame.lockout:
		v = tree.GetItemData(id).GetData()
		if v:
			#trace(v)
			v.expand()</t>
<t tx="edream.110203113231.282"></t>
<t tx="edream.110203113231.283">def onTreeChanged(self,event):

	frame = self ; c = self.c ; tree = self.treeCtrl
	
	if self.frame.lockout &gt; 0: return 
 	new_id = event.GetItem()
	if not new_id.IsOk(): return
	v = tree.GetItemData(new_id).GetData()
	if not v: return

	self.frame.lockout += 1 # MUST prevent further events.
	
	c.selectVnode(v)
	s = v.t.bodyString
	s = toUnicode(s,"utf-8")  # No app.tkEncoding or similar yet.
	t = self.frame.body.bodyCtrl
	t.Clear()
	t.WriteText(s)
	self.frame.body.recolor(v)
	
	self.frame.lockout -= 1</t>
<t tx="edream.110203113231.284">def onTreeChanging(self,event):
	
	"""Event handler gets called whenever a new node gets selected"""

	# trace()
	pass</t>
<t tx="edream.110203113231.285"></t>
<t tx="edream.110203113231.286"># Editing is allowed only if this routine exists.

def onTreeBeginLabelEdit(self,event):

	# Disallow editing of the dummy root node.
	id = event.GetItem()
	if id == self.root_id:
		event.Veto()</t>
<t tx="edream.110203113231.287"># Editing will be allowed only if this routine exists.

def onTreeEndLabelEdit(self,event):

	tree = self.treeCtrl
	s = event.GetLabel()
	id = event.GetItem()
	v = tree.GetItemData(id).GetData()

	return # Not yet: c.setChanged uses frame.top.

	# Set the dirty bit and the file-changed mark if the headline has changed.
	if not v.isDirty()and s != v.headString():
		v.setDirty()
		if not self.c.isChanged():
			self.c.setChanged(true)

	# Update all joined headlines.
	j = v.joinList()
	while j != v:
		j.setHeadString(s)
		j = j.joinList()</t>
<t tx="edream.110203113231.288">def onTreeKeyDown(self,event):
	
	pass # Don't do anything until the end-edit event.</t>
<t tx="edream.110203113231.289">def onTreeBeginDrag(self,event):

	trace() ; return

	if event.GetItem()!= self.treeCtrl.GetRootItem():
		mDraggedItem = event.GetItem()
		event.Allow()
</t>
<t tx="edream.110203113231.290">def onTreeEndDrag(self,event):
	
	trace() ; return

	&lt;&lt; Define onTreeEndDrag vars &gt;&gt;
	if  src == 0 or dst == 0:  return
	cookie = None
	if (
		# dst is the root
		not parent.IsOk()or
		# dst has visible children and dst isn't the first child.
		self.tree.ItemHasChildren(dst)and self.tree.IsExpanded(dst)and
		self.tree.GetFirstChild(dst,cookie) != src or
		# back(src)== dst(would otherwise be a do-nothing)
		self.tree.GetPrevSibling(src) == dst):
		&lt;&lt; Insert src as the first child of dst &gt;&gt;
	else:
		# Not the root and no visible children.
		&lt;&lt; Insert src after dst &gt;&gt;
	self.c.selectVnode(src_v)
	self.c.setChanged(true)
</t>
<t tx="edream.110203113231.291">assert(self.tree)
assert(self.c)

dst = event.GetItem()
src = mDraggedItem
mDraggedItem = 0

if not dst.IsOk() or not src.IsOk():
	return

src_v = self.tree.GetItemData(src)
if src_v == None:
	return

dst_v =self.tree.GetItemData(dst)
if dst_v == None:
	return

parent = self.tree.GetParent(dst)
parent_v = None</t>
<t tx="edream.110203113231.292"># Make sure the drag will be valid.
parent_v = self.tree.GetItemData(dst)

if not self.c.checkMoveWithParentWithWarning(src_v,parent_v,true):
	return

src_v.moveToNthChildOf(dst_v,0)</t>
<t tx="edream.110203113231.293"># Do nothing if dst is a child of src.
p = parent
while p.IsOk():
	if p == src:
		return
	p = self.tree.GetParent(p)

# Do nothing if dst is joined to src.
if dst_v.isJoinedTo(src_v):
	return

# Make sure the drag will be valid.
parent_v = self.tree.GetItemData(parent)
if not self.c.checkMoveWithParentWithWarning(src_v,parent_v,true):
	return

src_v.moveAfter(dst_v)</t>
<t tx="edream.110203113231.295">def beginUpdate (self):
	
	if self.updateCount == 0:
		pass # self.Freeze() # Seems not to work...

	self.updateCount += 1</t>
<t tx="edream.110203113231.296">def endUpdate (self,flag=true):

	assert(self.updateCount &gt; 0)

	self.updateCount -= 1
	if flag and self.updateCount == 0:
		## self.Thaw()
		self.redraw()</t>
<t tx="edream.110203113231.298">def redraw (self):

	# trace(self.drawing)
	self.drawing = true # Tell event handlers not to call us.

	c = self.c ; tree = self.treeCtrl
	if c is None: return
	v = c.rootVnode()
	if v is None: return

	tree.DeleteAllItems()
	self.root_id = root_id = tree.AddRoot("Leo Outline Pane")
	while v:
		self.redraw_subtree(root_id,v)
		v = v.next()
	tree.Expand(root_id)
	
	self.drawing = false
		
def redraw_now(self):
	trace()
	self.redraw()</t>
<t tx="edream.110203113231.299">def redraw_node(self,parent_id,v):
	
	# trace(v)
	tree = self.treeCtrl
	data = wx.wxTreeItemData(v)
	id = tree.AppendItem(parent_id,v.headString(),data=data)
	v.wxTreeId = id # Inject the ivar into the vnode.
	assert (v == tree.GetItemData(id).GetData())
	return id
	</t>
<t tx="edream.110203113231.300">def redraw_subtree(self,parent_id,v):
	
	# trace(v)
	tree = self.treeCtrl
	id = self.redraw_node(parent_id,v)
	child = v.firstChild()
	
	if v.isExpanded():
		while child:
			self.redraw_subtree(id,child)
			child = child.next()
		tree.Expand(id)
	else:
		if 1: # tree.SetItemHasChildren changes the event handler logic.  So this is good enough.
			while child:
				self.redraw_node(id,child)
				child = child.next()
		else:
			if child:
				tree.SetItemHasChildren(id)
		tree.Collapse(id)</t>
<t tx="edream.110203113231.302">@first # -*- coding: utf-8 -*-

"""A plugin to use wxPython as Leo's gui."""

from leoPlugins import *
from leoGlobals import *

&lt;&lt; imports for wx plugin &gt;&gt;
&lt;&lt; constants for wx plugin &gt;&gt;

if wx and 0: # Enable the plugin (only if wxPython has been imported)...

	@others

	if app.gui is None:
		&lt;&lt; Set app.gui &gt;&gt;
		__version__ = "0.1" # Set version for the plugin handler.
		plugin_signon(__name__)
	else:
		s = "Can't install wxPython gui: previous gui installed"
		print s ; es(s,color="red")</t>
<t tx="edream.110203113231.303">import leoColor,leoCommands,leoFind,leoFrame,leoGui,leoMenu,leoNodes,leoTree
import os,sys,traceback

try:    from wxPython import wx
except: wx = None</t>
<t tx="edream.110203113231.304">app.gui = wxGui()
app.root = app.gui.createRootWindow()
app.gui.finishCreate()
</t>
<t tx="edream.110203113231.305">class wxGui(leoGui.leoGui):
	
	@others</t>
<t tx="edream.110203113231.306"></t>
<t tx="edream.110203113231.307">def __init__ (self):
	
	# trace("wxGui")
	
	# Initialize the base class.
	if 1: # in plugin
		leoGui.leoGui.__init__(self,"wxPython")
	else:
		leoGui.__init__(self,"wxPython")
		
	self.bitmap_name = None
	self.bitmap = None</t>
<t tx="edream.110203113231.308">def createRootWindow(self):

	self.wxApp = wxLeoApp(None) # This redirects stdout &amp; stderr to stupid console.
	self.wxFrame = None
	
	if 0: # Not ready yet.
		self.setDefaultIcon()
		self.getDefaultConfigFont(app.config)
		self.setEncoding()
		self.createGlobalWindows()

	return self.wxFrame</t>
<t tx="edream.110203113231.309">def setDefaultIcon(self):
	
	"""Set the icon to be used in all Leo windows.
	
	This code does nothing for Tk versions before 8.4.3."""
	
	gui = self

	try:
		version = gui.root.getvar("tk_patchLevel")
		if CheckVersion(version,"8.4.3"):
			# tk 8.4.3 or greater: load a 16 by 16 icon.
			path = os.path.join(app.loadDir,"..","Icons")
			if os.path.exists(path):
				file = os.path.join(path,"LeoApp16.ico")
				if os.path.exists(path):
					self.bitmap = Tkinter.BitmapImage(file)
				else:
					es("LeoApp16.ico not in Icons directory", color="red")
			else:
				es("Icons directory not found: "+path, color="red")
	except:
		print "exception setting bitmap"
		traceback.print_exc()</t>
<t tx="edream.110203113231.310">@ According to Martin v. Löwis, getdefaultlocale() is broken, and cannot be fixed. The workaround is to copy the getpreferredencoding() function from locale.py in Python 2.3a2.  This function is now in leoGlobals.py.
@c

def setEncoding (self):

	for (encoding,src) in (
		(app.config.tkEncoding,"config"),
		#(locale.getdefaultlocale()[1],"locale"),
		(getpreferredencoding(),"locale"),
		(sys.getdefaultencoding(),"sys"),
		("utf-8","default")):
	
		if isValidEncoding (encoding): # 3/22/03
			app.tkEncoding = encoding
			# trace(app.tkEncoding,src)
			break
		elif encoding and len(encoding) &gt; 0:
			trace("ignoring invalid " + src + " encoding: " + `encoding`)
			
	# trace(app.tkEncoding)</t>
<t tx="edream.110203113231.311">def getDefaultConfigFont(self,config):
	
	"""Get the default font from a new text widget."""

	t = Tkinter.Text()
	fn = t.cget("font")
	font = tkFont.Font(font=fn)
	config.defaultFont = font
	config.defaultFontFamily = font.cget("family")</t>
<t tx="edream.110203113231.312">def createGlobalWindows (self):
	
	"""Create the global windows for the application."""
	
	app.findFrame = wxFindFrame()
	app.findFrame.top.withdraw()
	app.globalWindows.append(app.findFrame)</t>
<t tx="edream.110203113231.314">def finishCreate (self):

	pass
	
</t>
<t tx="edream.110203113231.315">def killGui(self,exitFlag=true):
	
	"""Destroy a gui and terminate Leo if exitFlag is true."""

	pass # Not ready yet.

</t>
<t tx="edream.110203113231.316">def recreateRootWindow(self):
	"""A do-nothing base class to create the hidden root window of a gui

	after a previous gui has terminated with killGui(false)."""
	pass

</t>
<t tx="edream.110203113231.317">def runMainLoop(self):

	"""Run tkinter's main loop."""
	
	# trace("wxGui")
	self.wxApp.MainLoop()
	# trace("done")</t>
<t tx="edream.110203113231.318"></t>
<t tx="edream.110203113231.319">def getFontFromParams(self,family,size,slant,weight):
	
	## trace(app.config.defaultFont)
	
	return app.config.defaultFont ##
	
	family_name = family
	
	try:
		font = tkFont.Font(family=family,size=size,slant=slant,weight=weight)
		#print family_name,family,size,slant,weight
		#print "actual_name:",font.cget("family")
		return font
	except:
		es("exception setting font from " + `family_name`)
		es("family,size,slant,weight:"+
			`family`+':'+`size`+':'+`slant`+':'+`weight`)
		es_exception()
		return app.config.defaultFont</t>
<t tx="edream.110203113231.320">def replaceClipboardWith (self,s):

	cb = wx.wxTheClipboard
	if cb.Open():
		cb.Clear()
		cb.SetData(s)
		cb.Flush()
		cb.Close()
	
def getTextFromClibboard (self):
	
	return None
	
	# This code doesn't work yet.
	
	cb = wx.wxTheClipboard ; data = None
  	if cb.Open():
		data = wx.wxDataObject()
		cb.GetData(data)
		data = data.GetDataHere()
		cb.Close()
	return data</t>
<t tx="edream.110203113231.321"></t>
<t tx="edream.110203113231.322">def runAboutLeoDialog(self,version,copyright,url,email):
	
	"""Create and run a wxPython About Leo dialog."""

	message = "%s\n\n%s\n\n%s\n\n%s" % (
		version.strip(),copyright.strip(),url.strip(),email.strip())
	
	wx.wxMessageBox(message,"About Leo",wx.wxCenter,self.root)</t>
<t tx="edream.110203113231.323">def runAskOkDialog(self,title,message=None,text="Ok"):
	
	"""Create and run a wxPython askOK dialog ."""
	
	d = wx.wxMessageDialog(self.root,message,"Leo",wx.wxOK)
	d.ShowModal()
	return "ok"</t>
<t tx="edream.110203113231.324">def runAskOkCancelNumberDialog(self,title,message):

	"""Create and run a wxPython askOkCancelNumber dialog ."""

	trace()
	return 666</t>
<t tx="edream.110203113231.325">def runAskYesNoDialog(selftitle,message=None):

	"""Create and run a wxPython askYesNo dialog."""
	
	d = wx.wxMessageDialog(self.root,message,"Leo",wx.wxYES_NO)
	answer = d.ShowModal()

	return choose(answer==wx.wxYES,"yes","no")</t>
<t tx="edream.110203113231.326">def runAskYesNoCancelDialog(self,title,
	message=None,yesMessage="Yes",noMessage="No",defaultButton="Yes"):

	"""Create and run a wxPython askYesNoCancel dialog ."""
	
	d = wx.wxMessageDialog(self.root,message,"Leo",wx.wxYES_NO | wx.wxCANCEL)
	answer = d.ShowModal()
	
	if answer == wx.wxID_YES:
		return "yes"
	elif answer == wx.wxID_NO:
		return "no"
	else:
		assert(answer == wx.wxID_CANCEL)
		return "cancel"</t>
<t tx="edream.110203113231.327">def runOpenFileDialog(self,title,filetypes,defaultextension):

	"""Create and run a wxPython open file dialog ."""
	
	wildcard = self.getWildcardList(filetypes)

	d = wx.wxFileDialog(
		parent=None, message=title,
		defaultDir="", defaultFile="",
		wildcard=wildcard,
		style= wx.wxOPEN | wx.wxCHANGE_DIR | wx.wxHIDE_READONLY)

	val = d.ShowModal()
	if val == wx.wxID_OK:
		file = d.GetFilename()
		return file
	else:
		return None 
</t>
<t tx="edream.110203113231.328">def runSaveFileDialog(self,initialfile,title,filetypes,defaultextension):

	"""Create and run a wxPython save file dialog ."""

	wildcard = self.getWildcardList(filetypes)

	d = wx.wxFileDialog(
		parent=None, message=title,
		defaultDir="", defaultFile="",
		wildcard=wildcard,
		style= wx.wxSAVE | wx.wxCHANGE_DIR | wx.wxOVERWRITE_PROMPT)

	val = d.ShowModal()
	if val == wx.wxID_OK:
		file = d.GetFilename()
		return file
	else:
		return None</t>
<t tx="edream.110203113231.329"></t>
<t tx="edream.110203113231.333">def destroyLeoFrame (self,frame):

	trace(frame.title)
	frame.Close()</t>
<t tx="edream.110203113231.335"></t>
<t tx="edream.110203113231.336">def get_focus(self,top):
	
	"""Returns the widget that has focus, or body if None."""

	pass # wx code not ready yet.</t>
<t tx="edream.110203113231.337">def set_focus(self,c,widget):
	
	"""Set the focus of the widget in the given commander if it needs to be changed."""
	
	pass # wx code not ready yet.</t>
<t tx="edream.110203113231.339"></t>
<t tx="edream.110203113231.340">def attachLeoIcon (self,w):
	
	"""Try to attach a Leo icon to the Leo Window.
	
	Use tk's wm_iconbitmap function if available (tk 8.3.4 or greater).
	Otherwise, try to use the Python Imaging Library and the tkIcon package."""
	
	trace(w)

	if self.bitmap != None:
		# We don't need PIL or tkicon: this is tk 8.3.4 or greater.
		try:
			w.wm_iconbitmap(self.bitmap)
		except:
			self.bitmap = None
	
	if self.bitmap == None:
		try:
			&lt;&lt; try to use the PIL and tkIcon packages to draw the icon &gt;&gt;
		except:
			# traceback.print_exc()
			self.leoIcon = None</t>
<t tx="edream.110203113231.341">@ This code requires Fredrik Lundh's PIL and tkIcon packages:

Download PIL    from http://www.pythonware.com/downloads/index.htm#pil
Download tkIcon from http://www.effbot.org/downloads/#tkIcon

Many thanks to Jonathan M. Gilligan for suggesting this code.
@c

import Image,tkIcon,_tkicon

# Wait until the window has been drawn once before attaching the icon in OnVisiblity.
def visibilityCallback(event,self=self,w=w):
	try: self.leoIcon.attach(w.winfo_id())
	except: pass
w.bind("&lt;Visibility&gt;",visibilityCallback)
if not self.leoIcon:
	# Load a 16 by 16 gif.  Using .gif rather than an .ico allows us to specify transparency.
	icon_file_name = os.path.join(app.loadDir,'..','Icons','LeoWin.gif')
	icon_file_name = os.path.normpath(icon_file_name)
	icon_image = Image.open(icon_file_name)
	if 1: # Doesn't resize.
		self.leoIcon = self.createLeoIcon(icon_image)
	else: # Assumes 64x64
		self.leoIcon = tkIcon.Icon(icon_image)</t>
<t tx="edream.110203113231.342"># This code is adapted from tkIcon.__init__
# Unlike the tkIcon code, this code does _not_ resize the icon file.

def createLeoIcon (self,icon):
	
	try:
		import Image,tkIcon,_tkicon
		
		i = icon ; m = None
		# create transparency mask
		if i.mode == "P":
			try:
				t = i.info["transparency"]
				m = i.point(lambda i, t=t: i==t, "1")
			except KeyError: pass
		elif i.mode == "RGBA":
			# get transparency layer
			m = i.split()[3].point(lambda i: i == 0, "1")
		if not m:
			m = Image.new("1", i.size, 0) # opaque
		# clear unused parts of the original image
		i = i.convert("RGB")
		i.paste((0, 0, 0), (0, 0), m)
		# create icon
		m = m.tostring("raw", ("1", 0, 1))
		c = i.tostring("raw", ("BGRX", 0, -1))
		return _tkicon.new(i.size, c, m)
	except:
		return None</t>
<t tx="edream.110203113231.343">def get_window_info(self,window):

	# Get the information about top and the screen.
	x,y = window.GetPosition()
	w,h = window.GetSize()
	
	return w,h,x,y</t>
<t tx="edream.110203113231.344">def center_dialog(window):
	
	window.Center()</t>
<t tx="edream.110203113231.346">class wxLeoApp (wx.wxApp):
	
	@others
</t>
<t tx="edream.110203113231.347">def OnInit(self):
	
	#trace("wx.wxPlatform",wx.wxPlatform)
	
	self.SetAppName("Leo")
	app.findFrame = wxFindFrame()
	app.globalWindows.append(app.findFrame)
	return true</t>
<t tx="edream.110203113231.348">def OnExit(self):
	
	# trace()
	return true
</t>
<t tx="edream.110203113231.349">class wxLeoFrame(wx.wxFrame,leoFrame.leoFrame):
	
	"""A class to create a wxPython from for the main Leo window."""

	@others</t>
<t tx="edream.110203113231.350"></t>
<t tx="edream.110203113231.351">def __repr__ (self):
	
	return "wxLeoFrame: " + self.title</t>
<t tx="edream.110203113231.378"></t>
<t tx="edream.110203113231.379">def after_idle(*args):
	pass

def get_window_info (self):
	"""Return the window information."""
	return app.gui.get_window_info(self)

def resizePanesToRatio(self,ratio1,ratio2):
	pass

def setInitialWindowGeometry (self):
	pass

def setTopGeometry(self,geom):
	pass

def lift (self):
	self.Raise()

def update (self):
	pass</t>
<t tx="edream.110203113231.380">def deiconify (self):

	self.Iconize(false)</t>
<t tx="edream.110203113231.381">def getTitle (self):
	
	return self.title
</t>
<t tx="edream.110203113231.384">def updateAllMenus(self,event):
	
	"""Called whenever any menu is pulled down."""
	
	# We define this routine to strip off the even param.
	
	self.menu.updateAllMenus()</t>
<t tx="edream.110203113231.539">class wxLeoBody (leoFrame.leoBody):
	
	"""A class to create a wxPython body pane."""
	
	@others</t>
<t tx="edream.110203113231.540"></t>
<t tx="edream.110203113231.541">def __init__ (self,frame,parentFrame):

	# Init the base class: calls createControl.
	leoFrame.leoBody.__init__(self,frame,parentFrame)
	
	self.bodyCtrl = self.createControl(frame,parentFrame)
	self.colorizer = leoColor.colorizer(self.c)

	self.styles = {} # For syntax coloring.

	wx.EVT_TEXT(self.bodyCtrl,const("cBodyCtrl"),self.onBodyTextUpdated)</t>
<t tx="edream.110203113231.542">def createControl (self,frame,parentFrame):
	
	trace()
	
	ctrl = wx.wxTextCtrl(parentFrame,
		const("cBodyCtrl"), "",
		wx.wxDefaultPosition, wx.wxDefaultSize,
		wx.wxTE_RICH | wx.wxTE_RICH2 | wx.wxTE_MULTILINE)
		
	return ctrl</t>
<t tx="edream.110203113231.543">def bbox (self,index):
	
	return self.bodyCtrl.GetClientSizeTuple()  </t>
<t tx="edream.110203113231.544">def setBodyFontFromConfig (self):
	
	pass # trace()</t>
<t tx="edream.110203113231.545">def hasFocus (self):
	
	return self.bodyCtrl == self.bodyCtrl.FindFocus()

def setFocus (self):
	
	self.bodyCtrl.SetFocus()
</t>
<t tx="edream.110203113231.548">def scheduleIdleTimeRoutine (self,function,*args,**keys):
	trace()
</t>
<t tx="edream.110203113231.549">def getBodyPaneHeight (self):
	return self.bodyCtrl.GetCharHeight()
	
def getBodyPaneWidth (self):
	return self.bodyCtrl.GetCharWidth()</t>
<t tx="edream.110203113231.552">def makeIndexVisible (self,index):
	self.bodyCtrl.ShowPosition()
	
def setFirstVisibleIndex (self,index):
	trace()
	
def getFirstVisibleIndex (self):
	trace()
	
def scrollUp (self):
	trace()
	
def scrollDown (self):
	trace()
</t>
<t tx="edream.110203113231.553">class wxLeoLog (leoFrame.leoLog):
	
	"""The base class for the log pane in Leo windows."""
	
	@others</t>
<t tx="edream.110203113231.554">def __init__ (self,frame,parentFrame):
	
	self.frame = frame
	self.c = frame.c
	self.newlines = 0

	self.logCtrl = self.createControl(parentFrame)
	self.setFontFromConfig()
</t>
<t tx="edream.110203113231.555">def configure (self,*args,**keys):
	
	trace(args,keys)</t>
<t tx="edream.110203113231.556">def configureBorder(self,border):
	
	trace(border)
</t>
<t tx="edream.110203113231.557">def createControl (self,parentFrame):

	ctrl = wx.wxTextCtrl(parentFrame,
		const("cLogCtrl"), "",
		wx.wxDefaultPosition, wx.wxDefaultSize,
		wx.wxTE_MULTILINE )
		
	return ctrl</t>
<t tx="edream.110203113231.558">def setFontFromConfig (self):
	
	pass # trace()</t>
<t tx="edream.110203113231.559"># All output to the log stream eventually comes here.

def put (self,s,color=None):

	if self.logCtrl:
		self.logCtrl.AppendText(s)

def putnl (self):

	if self.logCtrl:
		self.logCtrl.AppendText('\n')</t>
<t tx="edream.110203113231.560"></t>
<t tx="edream.110203113231.561">class wxFindFrame (wx.wxFrame,leoFind.leoFind):

	@others</t>
<t tx="edream.110203113231.563">def __init__ (self):

	# Init the base classes
	wx.wxFrame.__init__(self,None,-1,"Leo Find/Change",
		wx.wxPoint(50,50), wx.wxDefaultSize,
		wx.wxMINIMIZE_BOX | wx.wxTHICK_FRAME | wx.wxSYSTEM_MENU | wx.wxCAPTION)

	leoFind.leoFind.__init__(self)
	
	self.dict = {} # For communication between panel and frame.
	self.findPanel = wxFindPanel(self)
	
	self.s_text = wxSearchWidget() # wx.wxTextCtrl(self,-1) # Working text widget.

	&lt;&lt; resize the frame to fit the panel &gt;&gt;

	# Set the window icon.
	if wx.wxPlatform == '__WXMSW__':
		pass ## self.SetIcon(wx.wxIcon("LeoIcon"))

	# Set the focus.
	self.findPanel.findText.SetFocus()

	&lt;&lt; define event handlers &gt;&gt;
</t>
<t tx="edream.110203113231.564">wx.EVT_CLOSE(self,self.onCloseFindFrame)

&lt;&lt; create event handlers for buttons &gt;&gt;

&lt;&lt; create event handlers for check boxes and text &gt;&gt;</t>
<t tx="edream.110203113231.588">class wxFindPanel (wx.wxPanel):

	@others</t>
<t tx="edream.110203113231.589">def __init__(self,frame):
	 
	# Init the base class.
	wx.wxPanel.__init__(self,frame,-1)
	self.frame = frame

	topSizer = wx.wxBoxSizer(wx.wxVERTICAL)
	topSizer.Add(0,10)

	&lt;&lt; Create the find text box &gt;&gt;
	&lt;&lt; Create the change text box &gt;&gt;
	&lt;&lt; Create all the find check boxes &gt;&gt;
	&lt;&lt; Create all the find buttons &gt;&gt;

	self.SetAutoLayout(true) # tell dialog to use sizer
	self.SetSizer(topSizer) # actually set the sizer
	topSizer.Fit(self)# set size to minimum size as calculated by the sizer
	topSizer.SetSizeHints(self)# set size hints to honour mininum size</t>
<t tx="edream.110203113231.590">findSizer = wx.wxBoxSizer(wx.wxHORIZONTAL)
findSizer.Add(5,5)# Extra space.

# Label.
findSizer.Add(
	wx.wxStaticText(self,-1,"Find:",
		wx.wxPoint(-1,10), wx.wxSize(50,25),0,""),
	0, wx.wxBORDER | wx.wxTOP,15) # Vertical offset.

findSizer.Add(10,0) # Width.

# Text.
id = const("find_text")
self.findText = wx.wxTextCtrl(self,
	id,"",
	wx.wxDefaultPosition, wx.wxSize(500,60),
	wx.wxTE_PROCESS_TAB | wx.wxTE_MULTILINE,
	wx.wxDefaultValidator,"")

findSizer.Add(self.findText)
findSizer.Add(5,0)# Width.
topSizer.Add(findSizer)
topSizer.Add(0,10)

self.frame.dict["find_text"] = self.findText,id</t>
<t tx="edream.110203113231.591">changeSizer = wx.wxBoxSizer(wx.wxHORIZONTAL)
changeSizer.Add(5,5)# Extra space.

# Label.
changeSizer.Add(
	wx.wxStaticText(self,-1,"Change:",
		wx.wxPoint(-1,10),wx.wxSize(50,25),0,""),
	0, wx.wxBORDER | wx.wxTOP,15)# Vertical offset.

changeSizer.Add(10,0) # Width.

# Text.
id = const("change_text")
self.changeText = wx.wxTextCtrl(self,
	id,"",
	wx.wxDefaultPosition, wx.wxSize(500,60),
	wx.wxTE_PROCESS_TAB | wx.wxTE_MULTILINE,
	wx.wxDefaultValidator,"")

changeSizer.Add(self.changeText)
changeSizer.Add(5,0)# Width.
topSizer.Add(changeSizer)
topSizer.Add(0,10)

self.frame.dict["change_text"] = self.findText,id</t>
<t tx="edream.110203113231.592">col1Sizer = wx.wxBoxSizer(wx.wxVERTICAL)
&lt;&lt; Create the first column of widgets &gt;&gt;

col2Sizer = wx.wxBoxSizer(wx.wxVERTICAL)
&lt;&lt; Create the second column of widgets &gt;&gt;

col3Sizer = wx.wxBoxSizer(wx.wxVERTICAL)
&lt;&lt; Create the third column of widgets &gt;&gt;

col4Sizer = wx.wxBoxSizer(wx.wxVERTICAL)
&lt;&lt; Create the fourth column of widgets &gt;&gt;

# Pack the columns
columnSizer = wx.wxBoxSizer(wx.wxHORIZONTAL)
columnSizer.Add(col1Sizer)
columnSizer.Add(col2Sizer)
columnSizer.Add(col3Sizer)
columnSizer.Add(col4Sizer)

topSizer.Add(columnSizer)
topSizer.Add(0,10)</t>
<t tx="edream.110203113231.593"># The var names must match the names in leoFind class.
table = (
	("plain-search-flag","Plain Search",wx.wxRB_GROUP),
	("pattern_match_flag","Pattern Match",0),
	("script_search_flag","Script Search",0))

for var,label,style in table:
	
	id = const(var)
	box = wx.wxRadioButton(self,id,label,
		wx.wxDefaultPosition,(100,25),
		style,wx.wxDefaultValidator,"group1")
		
	if style == wx.wxRB_GROUP:
		box.SetValue(true) # The default entry.

	col1Sizer.Add(box,0,wx.wxBORDER | wx.wxLEFT,60)
	self.frame.dict[var] = box,id
	
table = (("script_change_flag","Script Change"),)

for var,label in table:
	
	id = const(var)
	box = wx.wxCheckBox(self,id,label,
		wx.wxDefaultPosition,(100,25),
		0,wx.wxDefaultValidator,"")

	col1Sizer.Add(box,0,wx.wxBORDER | wx.wxLEFT,60)
	self.frame.dict[var] = box,id</t>
<t tx="edream.110203113231.594"># The var names must match the names in leoFind class.
table = (
	("whole_word_flag","Whole Word"),
	("ignore_case_flag","Ignore Case"),
	("wrap_flag","Wrap Around"),
	("reverse_flag","Reverse"))

for var,label in table:

	id = const(var)
	box = wx.wxCheckBox(self,id,label,
		wx.wxDefaultPosition,(100,25),
		0,wx.wxDefaultValidator,"")

	col2Sizer.Add(box,0,wx.wxBORDER | wx.wxLEFT,20)
	self.frame.dict[var] = box,id</t>
<t tx="edream.110203113231.595"># The row sizers are a bit dim:  they should distribute the buttons automatically.

row1Sizer = wx.wxBoxSizer(wx.wxHORIZONTAL)
&lt;&lt; Create the first row of buttons &gt;&gt;

row2Sizer = wx.wxBoxSizer(wx.wxHORIZONTAL)
&lt;&lt; Create the second row of buttons &gt;&gt;

# Pack the two rows
buttonSizer = wx.wxBoxSizer(wx.wxVERTICAL)
buttonSizer.Add(row1Sizer)
buttonSizer.Add(0,10)

buttonSizer.Add(row2Sizer)
topSizer.Add(buttonSizer)
topSizer.Add(0,10)</t>
<t tx="edream.110203113231.596">row1Sizer.Add(90,0)

table = (
	("findButton","Find",true),
	("batch_flag","Show Context",false), # Old batch_flag now means Show Context.
	("findAllButton","Find All",true))

for var,label,isButton in table:
	
	id = const(var)
	if isButton:
		widget = button = wx.wxButton(self,id,label,
			wx.wxDefaultPosition,(100,25),
			0,wx.wxDefaultValidator,"")
	else:
		widget = box = wx.wxCheckBox(self,id,label,
			wx.wxDefaultPosition,(100,25),
			0,wx.wxDefaultValidator,"")
		
		self.frame.dict[var] = box,id

	row1Sizer.Add(widget)
	row1Sizer.Add((25,0),)</t>
<t tx="edream.110203113231.597">row2Sizer.Add(90,0)

table = (
	("changeButton","Change"),
	("changeThenFindButton","Change,Then Find"),
	("changeAllButton","Change All"))

for var,label in table:

	id = const(var)
	button = wx.wxButton(self,id,label,
		wx.wxDefaultPosition,(100,25),
		0,wx.wxDefaultValidator,"")
	
	row2Sizer.Add(button)
	row2Sizer.Add((25,0),)</t>
<t tx="edream.110203113231.598">class wxLeoPrefs (wx.wxFrame):
	@others
</t>
<t tx="edream.110203113231.599">def __init__(c):
	
	# Init the base frame.
	wxFrame.__init__(None,-1,"Leo Preferences",
		wx.wxPoint(50,50),wxDefaultSize,
		wxMINIMIZE_BOX | wxTHICK_FRAME | wxSYSTEM_MENU | wxCAPTION)

	self.c = c
	mPrefsPanel = PrefsPanel(self)

	# Resize to fit the panel.
	sizer = wxBoxSizer(wxVERTICAL)
	sizer.Add(mPrefsPanel)
	SetAutoLayout(true)# tell dialog to use sizer
	SetSizer(sizer) # actually set the sizer
	sizer.Fit(self)# set size to minimum size as calculated by the sizer
	sizer.SetSizeHints(self)# set size hints to honour mininum size

	# Set the window icon.
	if wx.wxPlatform == '__WXMSW__':
		self.SetIcon(wxIcon("LeoIcon"))
		
	&lt;&lt; define event handlers for wxLeoPrefsFrame &gt;&gt;</t>
<t tx="edream.110203113231.600">wx.EVT_ACTIVATE(self,self.OnActivatePrefsFrame)
wx.EVT_CLOSE(self,self.OnClosePrefsFrame)

# Global options panel...
wx.EVT_TEXT(self,cPrefsPageWidthText,self.OnPageWidthText)
wx.EVT_CHECKBOX(self,cPrefsDoneBatCheckBox,self.OnDoneBatCheckBox)
wx.EVT_CHECKBOX(self,cPrefsUnBatCheckBox,self.OnUnBatCheckBox)

# Tangle options panel...
wx.EVT_TEXT(self,cPrefsTangleDirectoryText,self.OnTangleDirectoryText)
wx.EVT_CHECKBOX(self,cPrefsHeaderCheckBox,self.OnHeaderCheckBox)
wx.EVT_CHECKBOX(self,cPrefsDocChunksCheckBox,self.OnDocChunksCheckBox)

# Target language panel...
wx.EVT_RADIOBOX(self,cPrefsTargetLanguageRadioBox,self.OnTargetLanguageRadioBox)</t>
<t tx="edream.110203113231.601">def initialize (self,void):
	
	# This may be called during construction.
	if not gPrefsFrame:  return
	s = ""
	if self.activeFrame:
		s += "%d" % self.activeFrame.mPageWidth
		mPrefsPanel.mPrefsPageWidthText.SetValue(s)
		mPrefsPanel.mPrefsDoneBatCheckBox.SetValue(self.activeFrame.mTangleBatchFlag)
		mPrefsPanel.mPrefsUnBatCheckBox.SetValue(self.activeFrame.mUntangleBatchFlag)
		mPrefsPanel.mPrefsTangleDirectoryText.SetValue(self.activeFrame.mDefaultDirectory)
		mPrefsPanel.mPrefsHeaderCheckBox.SetValue(self.activeFrame.mUseHeaderFlag)
		mPrefsPanel.mPrefsDocChunksCheckBox.SetValue(self.activeFrame.mOutputDocFlag)
		mPrefsPanel.mTargetLanguageRadioBox.SetSelection(languageToTarget(self.activeFrame.mTargetLanguage))
	else:
		s += "%d" % arg_page_width
		mPrefsPanel.mPrefsPageWidthText.SetValue(s)
		mPrefsPanel.mPrefsDoneBatCheckBox.SetValue(arg_tangle_batch)
		mPrefsPanel.mPrefsUnBatCheckBox.SetValue(arg_untangle_batch)
		# No global setting for director.
		mPrefsPanel.mPrefsHeaderCheckBox.SetValue(arg_use_header_flag)
		mPrefsPanel.mPrefsDocChunksCheckBox.SetValue(arg_output_doc_flag)
		mPrefsPanel.mTargetLanguageRadioBox.SetSelection(languageToTarget(arg_target_language))</t>
<t tx="edream.110203113231.602">if 0:
	def targetToLanguage(self,target):
		
		pass

		# switch(target)
		# case c_target: return c_language
		# case cweb_target: return cweb_language
		# case html_target: return html_language
		# case java_target: return java_language
		# case perl_target: return perl_language
		# case perlpod_target: return perlpod_language
		# case pascal_target: return pascal_language
		# case plain_text_target: return plain_text_language
		# case python_target: return python_language
		# default: return plain_text_language
</t>
<t tx="edream.110203113231.603">def languageToTarget(self,language):
	
	pass

	# switch(language)
	# case c_language: return c_target
	# case cweb_language: return cweb_target
	# case html_language: return html_target
	# case java_language: return java_target
	# case pascal_language: return pascal_target
	# case perl_language: return perl_target
	# case perlpod_language: return perlpod_target
	# case plain_text_language: return plain_text_target
	# case python_language: return python_target
	# default: return plain_text_target</t>
<t tx="edream.110203113231.604"></t>
<t tx="edream.110203113231.605">def OnActivatePrefsFrame(self,event):

	if gPrefsFrame and event.GetActive():
		gPrefsFrame.initialize()
</t>
<t tx="edream.110203113231.606">@ This is an event handler function called when the user has tried to close a frame or dialog box.

It is called via the  wxWindow::Close function, so that the application can also invoke the handler programmatically.  You should check whether the application is forcing the deletion of the window using CanVeto. If CanVeto returns FALSE, it is  not possible to skip window deletion; destroy the window using wxWindow::Destroy. If not, it is up to you whether you respond  by destroying the window.  If you don't destroy the window, you should call wxCloseEvent::Veto to let the calling code know that you did not destroy the  window. This allows the wxWindow::Close function to return TRUE or FALSE depending on whether the close instruction was  honoured or not.
@c

def OnClosePrefsFrame(self,event):

	if event.CanVeto():
		event.Veto()# Did not destroy the window.
		self.Show(false) # Just hide the window.
	else:
		self.Destroy()
		gPrefsFrame = None
</t>
<t tx="edream.110203113231.607">def OnPageWidthText(self,event):
	
	text = event.GetEventObject()
	s = text.GetValue()

	try:
		n = int(s)
		arg_page_width = default_page_width = n
		if self.activeFrame:
			self.activeFrame.mPageWidth = arg_page_width
	except: pass

</t>
<t tx="edream.110203113231.608">def OnDoneBatCheckBox(self,event):
	
	box =event.GetEventObject()
	arg_tangle_batch = default_tangle_batch = box.GetValue()
	if self.activeFrame:
		self.activeFrame.mTangleBatchFlag = arg_tangle_batch

</t>
<t tx="edream.110203113231.609">def OnUnBatCheckBox(self,event):
	
	box = event.GetEventObject()
	arg_untangle_batch = default_untangle_batch = box.GetValue()
	if self.activeFrame:
		self.activeFrame.mUntangleBatchFlag = arg_untangle_batch

</t>
<t tx="edream.110203113231.610">def OnTangleDirectoryText(self,event):

	text = event.GetEventObject()
	s = text.GetValue()
	if self.activeFrame:
		self.activeFrame.mDefaultDirectory = s
		if self.activeFrame.mDefaultDirectory.Length()&gt; 0:
			wxSetWorkingDirectory(self.activeFrame.mDefaultDirectory)
		elif self.activeFrame.mOpenDirectory.Length()&gt; 0:
			wxSetWorkingDirectory(self.activeFrame.mOpenDirectory)</t>
<t tx="edream.110203113231.611">def OnHeaderCheckBox(self,event):
	
	box = event.GetEventObject()
	arg_use_header_flag = default_use_header_flag = box.GetValue()
	if self.activeFrame:
		self.activeFrame.mUseHeaderFlag = arg_use_header_flag

</t>
<t tx="edream.110203113231.612">def OnDocChunksCheckBox(self,event):
	
	box = event.GetEventObject()
	arg_output_doc_flag = default_output_doc_flag = box.GetValue()
	if self.activeFrame:
		self.activeFrame.mOutputDocFlag = arg_output_doc_flag

</t>
<t tx="edream.110203113231.613">def OnTargetLanguageRadioBox(self,event):
	
	box = event.GetEventObject()
	targetIndex = box.GetSelection()
	default_target_language = arg_target_language = targetToLanguage(targetIndex)

	# Careful:  The @language or @nocolor will override this.
	if self.activeFrame:
		self.activeFrame.mTargetLanguage = arg_target_language
		c = self.activeFrame.c
		v = c.currentVnode()
		self.activeFrame.c.scanAllDirectives(v,cDontRequirePath,cDontIssueErrors)</t>
<t tx="edream.110203113231.614">def __init__(frame):
	
	# Init the base class.
	wxPanel.__init__(frame,-1)
	
	topSizer = wxBoxSizer(wxVERTICAL)
	&lt;&lt; Create the Global Options static box &gt;&gt;
	topSizer.Add(sizer)
	topSizer.Add(0,10)
	&lt;&lt; Create the Default Tangle Options static box &gt;&gt;
	topSizer.Add(sizer2)
	topSizer.Add(0,10)
	&lt;&lt; Create the Default Target Language radio buttons &gt;&gt;
	topSizer.Add(mTargetLanguageRadioBox)
	SetAutoLayout(true)# tell dialog to use sizer
	SetSizer(topSizer) # actually set the sizer
	topSizer.Fit(self)# set size to minimum size as calculated by the sizer
	topSizer.SetSizeHints(self)# set size hints to honour mininum size</t>
<t tx="edream.110203113231.615">globalOptionsBox = wxStaticBox(self,-1,
	"Global Options",(10,10),(250,110),0,"")
sizer = wxStaticBoxSizer(globalOptionsBox,wxVERTICAL)
lineSizer = wxBoxSizer(wxHORIZONTAL)
sizer.Add(0,5)# Extra vertical space.

# Text control.
mPrefsPageWidthText = wxTextCtrl(self,
	cPrefsPageWidthText,"132",
	wxDefaultPosition,wx.wxSize(50,25),0,wxDefaultValidator,"")

lineSizer.Add(mPrefsPageWidthText)
lineSizer.Add(20,0)# Width.

# Label for text control.
lineSizer.Add(
	wxStaticText(self,-1,"Page Width",
		(-1,10),(100,25),0,""),
	0,wxBORDER | wxTOP,5)# Vertical offset 5.
sizer.Add(lineSizer)

mPrefsDoneBatCheckBox = wxCheckBox(self,
	cPrefsDoneBatCheckBox,
	"Execute Leo_done.bat after Tangle",
	wxDefaultPosition,(235,25),0,wxDefaultValidator,"")
sizer.Add(mPrefsDoneBatCheckBox)

mPrefsUnBatCheckBox = wxCheckBox(self,
	cPrefsUnBatCheckBox,
	"Execute Leo_un.bat after Untangle",
	wxDefaultPosition,(235,25),0,wxDefaultValidator,"")
sizer.Add(mPrefsUnBatCheckBox)</t>
<t tx="edream.110203113231.616">optionsBox = wxStaticBox(self,-1,
	"Default Tangle Options",
	wxDefaultPosition,wx.wxSize(250,210),
	0,"zzzz")

sizer2 = wxStaticBoxSizer(optionsBox,wxVERTICAL)
sizer2.Add(0,10)# Vertical space.
# Label.
sizer2.Add(
	wxStaticText(self,-1,
		"Default Tangle directory",
		wxDefaultPosition,wx.wxSize(165,25),0,""),
	0,wxBORDER | wxLEFT,30)# Indent 30.

mPrefsTangleDirectoryText = wxTextCtrl(self,
	cPrefsTangleDirectoryText,"",
	wxDefaultPosition,wx.wxSize(230,25),0,
	wxDefaultValidator,"")
sizer2.Add(mPrefsTangleDirectoryText)

mPrefsHeaderCheckBox = wxCheckBox(self,
	cPrefsHeaderCheckBox,
	"Tangle outputs header line",
	wxDefaultPosition,wx.wxSize(235,25),0,
	wxDefaultValidator,"")
sizer2.Add(mPrefsHeaderCheckBox)

mPrefsDocChunksCheckBox = wxCheckBox(self,
	cPrefsDocChunksCheckBox,
	"Tangle outputs document chunks",
	wxDefaultPosition,wx.wxSize(235,25),0,
	wxDefaultValidator,"")
sizer2.Add(mPrefsDocChunksCheckBox)</t>
<t tx="edream.110203113231.617">targetLanguageChoices= [
	"C/C++","CWEB","HTML","Java",
	"Pascal","Perl","Perl + POD","Plain text","Python"]
	
# We specify rows so that items will be sorted down the columns.
mTargetLanguageRadioBox = wxRadioBox(self,
	cPrefsTargetLanguageRadioBox,
	"Default Target Language",
	wxDefaultPosition,wx.wxSize(245,145),
	WXSIZEOF(targetLanguageChoices),
	targetLanguageChoices,
	5,wxRA_SPECIFY_ROWS)</t>
<t tx="edream.110203113231.618">@ It is usually best not to catch exceptions in plugins:
doHook catches all exceptions and disables further calls to plugins.
@c

@language python</t>
<t tx="edream.110203113231.619">@ These were contributed by Bernhard Mulder, bwm@acm.org.</t>
<t tx="edream.110203113231.620">"""
Calculate foldersizes; generate XML file for leo to display results.

Parameters:
   foldersize_leo.py &lt;xmlfile&gt; [directory] *
   
Returns for each directory:
	- the number of directories.
	- the number of files.
	- the total size.
	
Only tested on Windows.

Does not take into account compression on Windows.

Ignores non-ascii filenames.
"""

@language python

import getopt,os,stat,string,sys
import leo_interface

comma = ','
intsize = 20

@others

if __name__ == '__main__':
   test()</t>
<t tx="edream.110203113231.621">def normalize(filename):
	
	"""This should probably be changed for Linux"""
	return string.replace(os.path.normpath(string.lower(filename)), '\\', '/')

</t>
<t tx="edream.110203113231.622">def filesize(fullname):
	return long(os.stat(fullname) [stat.ST_SIZE])
</t>
<t tx="edream.110203113231.623">def format(value, size):

	"""Insert 'comma' into the representation of value for easier reading"""
	if value==0:
		result = '0'
	else:
		result = ''
		negative = value &lt; 0
		if negative:
		  value = - value
		underbar = 4
		while value != 0:
			underbar = underbar - 1
			if underbar == 0:
				result = comma + result
				underbar = 3
			newvalue = value / 10
			rest     = int(value - newvalue*10)
			result = `rest` + result
			value = newvalue
		if negative:
			result = '-' + result
	if len(result) &lt; size:
		result = ' ' * (size - len(result)) + result
	return result
</t>
<t tx="edream.110203113231.624">class TreeItem(leo_interface.leo_node):
	
	"""Create a tree node for each directory.
	
	Put the information about the files in the directory
	into the body text of the tree node."""

	@others</t>
<t tx="edream.110203113231.625">def __init__(self, path):
	leo_interface.leo_node.__init__(self)
	self.path = path
	self.filecount, self.dircount, self.filesize = 0, 1, 0
	filenames, subdirs = self.GetSubList()
	if subdirs:
		for subdir in subdirs:
			self.filecount += subdir.filecount
			self.dircount  += subdir.dircount
			self.filesize  += subdir.filesize
			self.add_child(subdir)
	body_lines = []
	self.filecount += len(filenames)
	for filename in filenames:
		try:
			size = filesize(filename)
		except EnvironmentError, value:
			print "Sorry:, could not stat %s" % self.path, value
			size = 0
		self.filesize += size
		body_lines.append((size, filename))
	body_lines.sort()
	body_lines.reverse()
	body_lines = [self.format_file(name, size) for size, name in body_lines]
	self.set_headline(self.format_directory(
		name      = os.path.basename(path),
		dircount  = self.dircount,
		filecount = self.filecount,
		filesize  = self.filesize))
	self.set_body(string.join(body_lines, "\n"))
</t>
<t tx="edream.110203113231.626">def format_directory(self, name, dircount, filecount, filesize):

	name = os.path.basename(name)
	return ("%s %s %s %s" % (name,
							format(filesize, intsize),
							format(filecount, intsize),
							format(dircount, intsize),
							))

</t>
<t tx="edream.110203113231.627">def format_file(self, name, filesize):

	name = os.path.basename(name)
	return "%s %s" % (format(filesize, intsize), name)
</t>
<t tx="edream.110203113231.628">def GetSubList(self):
	"""
	Look into the directory.

	Visit all subdirectories, and create
	nodes for them.

	Create strings for all files in the current directory.

	Returns a list of files, and a list of node representing
	the subdirectories."""
	files, directory_nodes = [], []
	try:
		names = os.listdir(self.path)
	except os.error:
		return files, directory_nodes
	join = os.path.join
	isdir = os.path.isdir
	for name in names:
		skip = False
		for ch in name:
			if ord(ch) &gt; 127:
				print "Skipping ", name
				# Such names seem to be able to cause trouble
				# during reading...
				skip = True
		if skip:
			continue
		normpath = normalize(join(self.path, name))
		if isdir(normpath):
			directory_nodes.append(TreeItem(normpath))
		else:
			files.append(normpath)
	directory_nodes.sort(lambda a, b: cmp(b.filesize, a.filesize))
	return files, directory_nodes
</t>
<t tx="edream.110203113231.629">def test():

	try:
		opts, values = getopt.getopt(sys.argv[1:], '', [])
	except:
		print __doc__
		return

	if len(values) &lt; 1:
		print __doc__
		return

	resultfile = values[0]
	leotree  = leo_interface.leotree()
	roots = [TreeItem(root) for root in values[1:]]
	for root in roots:
		leotree.add_child(root)
	file = open(resultfile, "w")
	leotree.gen(file)
	file.close()</t>
<t tx="edream.110203113231.630">"""
This file implements an interface to XML generation,
so that the resulting file can be processed by leo.

It can be used to browse tree structured data in leo.

class file represents the whole leo file.
class leo_node has a headline and body text.

See the end of this file for a minimal example on
how to use these classes.
"""

@language python

from string import replace

@others

if __name__ == "__main__":
	import sys
	f = leotree()
	r = leo_node("Some headline", "some Body")
	f.add_child(r)
	f.gen(sys.stdout)</t>
<t tx="edream.110203113231.631">def escape(s):

	s = replace(s, '&amp;', "&amp;amp;")
	s = replace(s, '&lt;', "&amp;lt;")
	s = replace(s, '&gt;', "&amp;gt;")
	return s
</t>
<t tx="edream.110203113231.632">error_count = 0

class node:

	"""Abstrace class for generating xml."""

	@others
</t>
<t tx="edream.110203113231.633">def __init__(self):
	self.children = []
</t>
<t tx="edream.110203113231.634">def gen(self, file):
	pass
</t>
<t tx="edream.110203113231.635">def add_child(self, child):
	self.children.append(child)
</t>
<t tx="edream.110203113231.636">def mark(self, file, marker, func, newline=True):
	file.write("&lt;%s&gt;" % marker)
	if newline:
		file.write("\n")
	func(file)
	file.write("&lt;/%s&gt;\n" % marker)
</t>
<t tx="edream.110203113231.637">def mark_with_attributes(self, file, marker, attribute_list, func, newline=True):
	write = file.write
	write("&lt;")
	write(marker)
	write(" ")
	for name, value in attribute_list:
		write('%s="%s" ' % (name, value))
	write("&gt;")
	if newline:
		write("\n")
	func(file)
	write("&lt;/%s&gt;" % marker)
	if newline:
		write("\n")
</t>
<t tx="edream.110203113231.638">def mark_with_attributes_short(self, file, marker, attribute_list):
	write = file.write
	write("&lt;")
	write(marker)
	write(" ")
	for name, value in attribute_list:
		write('%s="%s" ' % (name, value))
	write("/&gt;\n")
</t>
<t tx="edream.110203113231.639">def gen_children(self, file):
	for child in self.children:
		child.gen(file)
</t>
<t tx="edream.110203113231.640">class file(node):

	"""Leo specific class representing a file."""

	@others
</t>
<t tx="edream.110203113231.641">def header(self, file):
	self.mark_with_attributes_short(file, "leo_header",
							  (("file_format", "1"),
							   ("tnodes", `self.nr_tnodes()`),
							   ("max_tnode_index", `self.max_tnode_index()`),
							   ("clone_windows", "0")))
</t>
<t tx="edream.110203113231.642">def sss(self, file):
	file.write("sss")
</t>
<t tx="edream.110203113231.643">def preferences(self, file):
	pass
</t>
<t tx="edream.110203113231.644">def empty(self, file):
	pass
</t>
<t tx="edream.110203113231.645">def find_panel_settings(self, file):
	self.mark(file, "find_string", self.empty, newline=False)
	self.mark(file, "change_string", self.empty, newline=False)
</t>
<t tx="edream.110203113231.646">def gen(self, file):
	global error_count
	error_count = 0
	file.write('&lt;?xml version="1.0" encoding="UTF-8"?&gt;\n')
	self.mark(file, "leo_file", self.gen1)
</t>
<t tx="edream.110203113231.647">def gen1(self, file):
	self.header(file)

	# This is a shortcut.
	file.write("""&lt;globals body_outline_ratio="0.5"&gt;
&lt;global_window_position top="0" left="2" height="400" width="700"/&gt;
&lt;global_log_window_position top="0" left="0" height="0" width="0"/&gt;
&lt;/globals&gt;
	""")
	self.mark(file, "preferences", self.preferences)
	self.mark(file, "find_panel_settings", self.find_panel_settings)
	self.mark(file, "vnodes", self.gen_vnodes)
	self.mark(file, "tnodes", self.gen_tnodes)
</t>
<t tx="edream.110203113231.648">def gen_vnodes(self, file):
	for child in self.children:
		child.gen_vnodes(file)
</t>
<t tx="edream.110203113231.649">def gen_tnodes(self, file):
	for child in self.children:
		child.gen_tnodes(file)
</t>
<t tx="edream.110203113231.650">def nr_tnodes(self):
	return leo_node.count
</t>
<t tx="edream.110203113231.651">def max_tnode_index(self):
	return leo_node.count
</t>
<t tx="edream.110203113231.652">class leo_node(node):

	"""Leo specific class representing a node."""

	count = 0

	@others</t>
<t tx="edream.110203113231.653">def __init__(self, headline='', body=''):

	node.__init__(self)
	leo_node.count += 1
	self.nr = leo_node.count
	self.headline =  headline
	self.body = body
</t>
<t tx="edream.110203113231.654">def set_headline(self, headline):

	self.headline = headline
</t>
<t tx="edream.110203113231.655">def set_body(self, body):

	self.body = body
</t>
<t tx="edream.110203113231.656">def get_headline(self, headline):

	return self.headline
</t>
<t tx="edream.110203113231.657">def get_body(self, body):

	return self.body
</t>
<t tx="edream.110203113231.658">def gen_vnodes(self, file):

	self.mark_with_attributes(file, "v", (
		("t", "T" + `self.nr`),
		), self.gen_vnodes1)
</t>
<t tx="edream.110203113231.659">def gen_vnodes1(self, file):

	self.mark(file, "vh", self.write_headline_escaped, newline=False)
	for child in self.children:
		child.gen_vnodes(file)
</t>
<t tx="edream.110203113231.660">def write_headline(self, file):

	file.write(self.headline) 
</t>
<t tx="edream.110203113231.661">def gen_tnodes(self, file):

	self.mark_with_attributes(file, "t", (
		("tx", "T" + `self.nr`),
		), self.gen_tnodes1, newline=False)
	for child in self.children:
		child.gen_tnodes(file)
</t>
<t tx="edream.110203113231.662">def gen_tnodes1(self, file):

	self.write_body_escaped(file)
</t>
<t tx="edream.110203113231.663">def write_body(self, file):

	file.write(self.body) 
</t>
<t tx="edream.110203113231.664">def write_headline_escaped(self, file):

	"For now, do not escape"
	file.write(escape(self.headline))
</t>
<t tx="edream.110203113231.665">def write_body_escaped(self, file):

	"For now, do not escape"

	escaped = escape(self.body)
	try:
		file.write(escaped)
	except UnicodeError:
		# Skip the characters which can not
		# be written out
		global error_count
		for ch in escaped:
			try:
				file.write(ch)
			except UnicodeError:
				error_count += 1
</t>
<t tx="edream.110203113231.666">def leotree():

	f = file()
	return f
</t>
<t tx="edream.110203113231.667"></t>
<t tx="edream.110203113231.668"></t>
<t tx="edream.110203113231.669">"""Import cisco configuration files"""

from leoPlugins import *
from leoGlobals import *

try:
	import tkFileDialog
except ImportError:
	tkFileDialog = None

&lt;&lt; about this plugin &gt;&gt;

if tkFileDialog:
	
	@others
	
	if app.gui is None:
		app.createTkGui(__file__)

	if app.gui.guiName() == "tkinter":

		# Register the handlers...
		registerHandler(("start2","open2","command2"),
			create_import_cisco_menu)

		__version__ = "1.3" 
		plugin_signon(__name__)
</t>
<t tx="edream.110203113231.670">@ This plugin adds a menu item under the File-&gt;Import menu to import
Cisco configuration files.

The plugin will:

1) create a new node, under the current node, where the configuration will be
written. This node will typically have references to several sections (see below).

2) create sections (child nodes) for the indented blocks present in the original
config file. These child nodes will have sub-nodes grouping similar blocks (e.g.
there will be an 'interface' child node, with as many sub-nodes as there are real
interfaces in the configuration file).

3) create sections for the custom keywords specified in the customBlocks[] list in
importCiscoConfig(). You can modify this list to specify different keywords. DO
NOT put keywords that are followed by indented blocks (these are taken care of by
point 2 above). The negated form of the keywords (for example, if the keyword is
'service', the negated form is 'no service') is also included in the sections.

4) not display consecutive empty comment lines (lines with only a '!').

All created sections are alphabetically ordered.

Feedback on this plugin can be sent to Davide Salomoni (dsalomoni@yahoo.com).
</t>
<t tx="edream.110203113231.671">def create_import_cisco_menu(tag, keywords):
	if	(tag=="open2" or
		(tag=="start2" and not keywords.has_key('c')) or
		(tag=="command2" and keywords.get("label")=="new")):

		c = top()
		importMenu = c.frame.menu.getMenu('import')
		newEntries = (
			("-", None, None),
			("Import C&amp;isco Configuration", "Shift+Ctrl+I", importCiscoConfig))
		
		c.frame.menu.createMenuEntries(importMenu, newEntries)</t>
<t tx="edream.110203113231.672">def importCiscoConfig(event=None):
	c = top(); current = c.currentVnode()
	if current == None: return
	&lt;&lt; open file &gt;&gt;

	# define which additional child nodes will be created
	# these keywords must NOT be followed by indented blocks
	customBlocks = ['aaa','ip as-path','ip prefix-list','ip route',
					'ip community-list','access-list','snmp-server','ntp',
					'boot','service','logging']
	out = []
	blocks = {}
	children = []
	lines = len(linelist)
	i = 0
	skipToNextLine = 0
	# create level-0 and level-1 children
	while i&lt;(lines-1):
		for customLine in customBlocks:
			if (linelist[i].startswith(customLine) or
				linelist[i].startswith('no %s' % customLine)):
				&lt;&lt; process custom line &gt;&gt;
				skipToNextLine = 1
				break
		if skipToNextLine:
			skipToNextLine = 0
		else:
			if linelist[i+1].startswith(' '):
				&lt;&lt; process indented block &gt;&gt;
			else:
				out.append(linelist[i])
		i=i+1
	# process last line
	out.append(linelist[i])
	
	&lt;&lt; complete outline &gt;&gt;</t>
<t tx="edream.110203113231.673">name = tkFileDialog.askopenfilename(
	title="Import Cisco Configuration File",
	filetypes=[("All files", "*")]
	)
if name == "":	return

v = current.insertAsNthChild(0)
c.beginUpdate()
v.setHeadString("cisco config: %s" % name)
c.endUpdate()

try:
	fh = open(name)
	es("importing: %s" % name)
	linelist = fh.read().splitlines()
	fh.close()
except IOError,msg:
	es("error reading %s: %s" % (name, msg))
	return</t>
<t tx="edream.110203113231.674">if not blocks.has_key(customLine):
	blocks[customLine] = []
	out.append(angleBrackets(customLine))
	# create first-level child
	child = v.insertAsNthChild(0)
	child.setHeadStringOrHeadline(angleBrackets(customLine))
	children.append(child)

blocks[customLine].append(linelist[i])</t>
<t tx="edream.110203113231.675">space = linelist[i].find(' ')
if space == -1:
	space = len(linelist[i])
key = linelist[i][:space]
if not blocks.has_key(key):
	blocks[key] = []
	out.append(angleBrackets(key))
	# create first-level child
	child = v.insertAsNthChild(0)
	child.setHeadStringOrHeadline(angleBrackets(key))
	children.append(child)

value = [linelist[i]]
# loop through the indented lines
i = i+1
try:
	while linelist[i].startswith(' '):
		value.append(linelist[i])
		i = i+1
except:
	# EOF
	pass
i = i-1 # restore index
# now add the value to the dictionary
blocks[key].append(value)</t>
<t tx="edream.110203113231.676"># first print the level-0 text
outClean = []
prev = ''
for line in out:
	if line=='!' and prev=='!':
		pass # skip repeated comment lines
	else:
		outClean.append(line)
	prev = line
v.setBodyStringOrPane('\n'.join(outClean))

# scan through the created outline and add children
for child in children:
	# extract the key from the headline. Uhm... :)
	key = child.headString().split('&lt;&lt;'
		)[1].split('&gt;&gt;')[0].strip()
	if blocks.has_key(key):
		if type(blocks[key][0]) == type(''):
			# it's a string, no sub-children, so just print the text
			child.setBodyStringOrPane('\n'.join(blocks[key]))
		else:
			# it's a multi-level node
			for value in blocks[key]:
				# each value is a list containing the headline and then the text
				subchild = child.insertAsNthChild(0)
				subchild.setHeadStringOrHeadline(value[0])
				subchild.setBodyStringOrPane('\n'.join(value))
		child.sortChildren()
	else:
		# this should never happen
		es("Unknown key: %s" % key)
v.sortChildren()</t>
<t tx="edream.110203113231.677">@ignore
@language plain
@comment !
@ This node has an example of a flat configuration file (i.e. just the output of a 
'show running' command on a cisco router), and of the same configuration file 
imported by the plugin.
</t>
<t tx="edream.110203113231.678">rpr1#sh runn    
Building configuration...

Current configuration : 4927 bytes
!
! Last configuration change at 13:28:04 CET Wed Feb 19 2003
! NVRAM config last updated at 16:56:51 CET Fri Feb 14 2003
!
version 12.0
no service pad
service timestamps debug datetime localtime show-timezone
service timestamps log datetime localtime show-timezone
service password-encryption
no service single-slot-reload-enable
!
hostname rpr1
!
boot system flash rsp-k3pv-mz.120-21.S4.bin
boot system flash rsp-pv-mz.120-21.S1.bin
boot bootldr bootflash:rsp-boot-mz.120-11.S3
logging buffered 100000 debugging
enable secret 5 somepassword
!
clock timezone CET 1
ip subnet-zero
ip cef
ip name-server 10.10.10.1
ip multicast-routing
ip ssh time-out 120
ip ssh authentication-retries 3
clns routing
frame-relay switching
!
!
controller SONET 1/0/0
 framing sdh
!
controller E1 5/0/0
 framing NO-CRC4 
 clock source internal
 channel-group 1 timeslots 1
 channel-group 2 timeslots 2
!
controller E1 5/0/1
 framing NO-CRC4 
 channel-group 0 timeslots 1
!
controller E1 5/0/2
!
controller E1 5/0/3
!
controller E1 5/0/4
!
controller E1 5/0/5
!
controller E1 5/0/6
!
controller E1 5/0/7
!
!
interface Loopback0
 ip address 192.168.20.1 255.255.255.255
 no ip directed-broadcast
!
interface FastEthernet0/0/0
 description *to 2600-1 via switch*
 bandwidth 10000
 ip address 192.168.3.1 255.255.255.0
 no ip directed-broadcast
 ip pim sparse-mode
 ip route-cache flow
 no ip route-cache distributed
 no ip mroute-cache
 delay 750
 full-duplex
!
interface FastEthernet0/0/1
 description **trunk link**
 no ip address
 no ip directed-broadcast
 no ip route-cache distributed
 no ip mroute-cache
 full-duplex
!
interface FastEthernet0/0/1.1
 encapsulation dot1Q 25
 ip address 192.168.25.1 255.255.255.252
 no ip directed-broadcast
!
interface FastEthernet0/0/1.2
 no ip directed-broadcast
!
interface FastEthernet0/0/1.3
 encapsulation dot1Q 3
 ip address 192.168.4.1 255.255.255.252
 ip access-group 173 in
 no ip directed-broadcast
 ip pim sparse-mode
!
interface FastEthernet0/0/1.5
 encapsulation dot1Q 5
 ip address 192.168.5.1 255.255.255.252
 no ip directed-broadcast
!
interface FastEthernet0/0/1.50
 description to KPN-test
 encapsulation dot1Q 50
 ip address 192.168.40.1 255.255.255.252
 no ip directed-broadcast
!
interface POS4/1/0
 no ip address
 no ip directed-broadcast
 no ip route-cache distributed
 no ip mroute-cache
 loopback internal
!
interface Serial5/0/0:1
 ip address 10.31.9.1 255.255.255.252
 no ip directed-broadcast
 no ip route-cache distributed
!
interface Serial5/0/0:2
 ip address 10.10.10.1 255.255.255.252
 no ip directed-broadcast
 no ip route-cache distributed
!
interface Serial5/0/1:0
 ip address 10.31.9.5 255.255.255.252
 no ip directed-broadcast
 no ip route-cache distributed
!
interface Serial5/1/0
 no ip address
 no ip directed-broadcast
 no ip route-cache distributed
 no ip mroute-cache
 shutdown
 framing g751
 dsu bandwidth 34010
!
interface Serial5/1/1
 ip address 192.168.6.1 255.255.255.252
 no ip directed-broadcast
 encapsulation frame-relay IETF
 no ip route-cache distributed
 no ip mroute-cache
 loopback local
 framing g751
 dsu bandwidth 34010
!
interface Async1
 no ip address
 no ip directed-broadcast
 async mode interactive
 no peer default ip address
!
interface Dialer0
 no ip address
 no ip directed-broadcast
 pulse-time 0
 no cdp enable
!
router ospf 1
 log-adjacency-changes
 passive-interface FastEthernet0/0/0
 network 192.168.3.1 0.0.0.0 area 0
 network 192.168.4.0 0.0.0.3 area 0
!
router bgp 65001
 no synchronization
 redistribute static
 neighbor 192.168.3.2 remote-as 65000
 neighbor 192.168.3.2 remove-private-AS
 neighbor 192.168.3.3 remote-as 65002
 neighbor 192.168.3.3 next-hop-self
 neighbor 192.168.4.2 remote-as 65001 nlri unicast multicast
 neighbor 192.168.4.2 next-hop-self
 neighbor 192.168.4.2 default-originate
 neighbor 192.168.4.2 soft-reconfiguration inbound
 no auto-summary
!
ip classless
ip route 0.0.0.0 0.0.0.0 192.168.3.2 tag 3
ip bgp-community new-format
ip community-list 1 permit 65001:1
ip community-list 100 permit 65001:3
ip ospf name-lookup
ip pim rp-address 192.168.4.1
ip pim send-rp-discovery scope 1
!
logging facility local6
logging 10.10.10.1
access-list 173 deny   ip 224.0.0.0 31.255.255.255 any
access-list 173 permit ip any any
route-map only permit 2
 match community 65001:2
 set origin igp
!
route-map only1 permit 10
 match community 1 65001:1
 set origin igp
!
route-map only3 permit 10
 match community 100
!
route-map tag_com permit 10
 match tag 1
 set community 65001:1
!
route-map tag_com permit 20
 match tag 3
 set community 65001:3
!
!
tacacs-server host 10.10.10.1
tacacs-server key somepassword
!
line con 0
line aux 0
 transport input all
 stopbits 1
 flowcontrol hardware
line vty 0 4
 exec-timeout 0 0
 password 7 somepassword
 logging synchronous
 login
 length 0
!
ntp clock-period 17179348
ntp update-calendar
ntp peer 192.168.3.2 prefer
end

rpr1#
</t>
<t tx="edream.110203113231.679">rpr1#sh runn    
Building configuration...

Current configuration : 4927 bytes
!
! Last configuration change at 13:28:04 CET Wed Feb 19 2003
! NVRAM config last updated at 16:56:51 CET Fri Feb 14 2003
!
version 12.0
&lt;&lt;service&gt;&gt;
!
hostname rpr1
!
&lt;&lt;boot&gt;&gt;
&lt;&lt;logging&gt;&gt;
enable secret 5 somepassword
!
clock timezone CET 1
ip subnet-zero
ip cef
ip name-server 10.10.10.1
ip multicast-routing
ip ssh time-out 120
ip ssh authentication-retries 3
clns routing
frame-relay switching
!
&lt;&lt;controller&gt;&gt;
!
controller E1 5/0/2
!
controller E1 5/0/3
!
controller E1 5/0/4
!
controller E1 5/0/5
!
controller E1 5/0/6
!
controller E1 5/0/7
!
&lt;&lt;interface&gt;&gt;
!
&lt;&lt;router&gt;&gt;
!
ip classless
&lt;&lt;ip route&gt;&gt;
ip bgp-community new-format
&lt;&lt;ip community-list&gt;&gt;
ip ospf name-lookup
ip pim rp-address 192.168.4.1
ip pim send-rp-discovery scope 1
!
&lt;&lt;access-list&gt;&gt;
&lt;&lt;route-map&gt;&gt;
!
tacacs-server host 10.10.10.1
tacacs-server key somepassword
!
line con 0
&lt;&lt;line&gt;&gt;
!
&lt;&lt;ntp&gt;&gt;
end

rpr1#</t>
<t tx="edream.110203113231.680">access-list 173 deny   ip 224.0.0.0 31.255.255.255 any
access-list 173 permit ip any any</t>
<t tx="edream.110203113231.681">boot system flash rsp-k3pv-mz.120-21.S4.bin
boot system flash rsp-pv-mz.120-21.S1.bin
boot bootldr bootflash:rsp-boot-mz.120-11.S3</t>
<t tx="edream.110203113231.682"></t>
<t tx="edream.110203113231.683">controller E1 5/0/0
 framing NO-CRC4 
 clock source internal
 channel-group 1 timeslots 1
 channel-group 2 timeslots 2</t>
<t tx="edream.110203113231.684">controller E1 5/0/1
 framing NO-CRC4 
 channel-group 0 timeslots 1</t>
<t tx="edream.110203113231.685">controller SONET 1/0/0
 framing sdh</t>
<t tx="edream.110203113231.686"></t>
<t tx="edream.110203113231.687">interface Async1
 no ip address
 no ip directed-broadcast
 async mode interactive
 no peer default ip address</t>
<t tx="edream.110203113231.688">interface Dialer0
 no ip address
 no ip directed-broadcast
 pulse-time 0
 no cdp enable</t>
<t tx="edream.110203113231.689">interface FastEthernet0/0/0
 description *to 2600-1 via switch*
 bandwidth 10000
 ip address 192.168.3.1 255.255.255.0
 no ip directed-broadcast
 ip pim sparse-mode
 ip route-cache flow
 no ip route-cache distributed
 no ip mroute-cache
 delay 750
 full-duplex</t>
<t tx="edream.110203113231.690">interface FastEthernet0/0/1
 description **trunk link**
 no ip address
 no ip directed-broadcast
 no ip route-cache distributed
 no ip mroute-cache
 full-duplex</t>
<t tx="edream.110203113231.691">interface FastEthernet0/0/1.1
 encapsulation dot1Q 25
 ip address 192.168.25.1 255.255.255.252
 no ip directed-broadcast</t>
<t tx="edream.110203113231.692">interface FastEthernet0/0/1.2
 no ip directed-broadcast</t>
<t tx="edream.110203113231.693">interface FastEthernet0/0/1.3
 encapsulation dot1Q 3
 ip address 192.168.4.1 255.255.255.252
 ip access-group 173 in
 no ip directed-broadcast
 ip pim sparse-mode</t>
<t tx="edream.110203113231.694">interface FastEthernet0/0/1.5
 encapsulation dot1Q 5
 ip address 192.168.5.1 255.255.255.252
 no ip directed-broadcast</t>
<t tx="edream.110203113231.695">interface FastEthernet0/0/1.50
 description to KPN-test
 encapsulation dot1Q 50
 ip address 192.168.40.1 255.255.255.252
 no ip directed-broadcast</t>
<t tx="edream.110203113231.696">interface Loopback0
 ip address 192.168.20.1 255.255.255.255
 no ip directed-broadcast</t>
<t tx="edream.110203113231.697">interface POS4/1/0
 no ip address
 no ip directed-broadcast
 no ip route-cache distributed
 no ip mroute-cache
 loopback internal</t>
<t tx="edream.110203113231.698">interface Serial5/0/0:1
 ip address 10.31.9.1 255.255.255.252
 no ip directed-broadcast
 no ip route-cache distributed</t>
<t tx="edream.110203113231.699">interface Serial5/0/0:2
 ip address 10.10.10.1 255.255.255.252
 no ip directed-broadcast
 no ip route-cache distributed</t>
<t tx="edream.110203113231.700">interface Serial5/0/1:0
 ip address 10.31.9.5 255.255.255.252
 no ip directed-broadcast
 no ip route-cache distributed</t>
<t tx="edream.110203113231.701">interface Serial5/1/0
 no ip address
 no ip directed-broadcast
 no ip route-cache distributed
 no ip mroute-cache
 shutdown
 framing g751
 dsu bandwidth 34010</t>
<t tx="edream.110203113231.702">interface Serial5/1/1
 ip address 192.168.6.1 255.255.255.252
 no ip directed-broadcast
 encapsulation frame-relay IETF
 no ip route-cache distributed
 no ip mroute-cache
 loopback local
 framing g751
 dsu bandwidth 34010</t>
<t tx="edream.110203113231.703">ip community-list 1 permit 65001:1
ip community-list 100 permit 65001:3</t>
<t tx="edream.110203113231.704">ip route 0.0.0.0 0.0.0.0 192.168.3.2 tag 3</t>
<t tx="edream.110203113231.705"></t>
<t tx="edream.110203113231.706">line aux 0
 transport input all
 stopbits 1
 flowcontrol hardware</t>
<t tx="edream.110203113231.707">line vty 0 4
 exec-timeout 0 0
 password 7 somepassword
 logging synchronous
 login
 length 0</t>
<t tx="edream.110203113231.708">logging buffered 100000 debugging
logging facility local6
logging 10.10.10.1</t>
<t tx="edream.110203113231.709">ntp clock-period 17179348
ntp update-calendar
ntp peer 192.168.3.2 prefer</t>
<t tx="edream.110203113231.710"></t>
<t tx="edream.110203113231.711">route-map only permit 2
 match community 65001:2
 set origin igp</t>
<t tx="edream.110203113231.712">route-map only1 permit 10
 match community 1 65001:1
 set origin igp</t>
<t tx="edream.110203113231.713">route-map only3 permit 10
 match community 100</t>
<t tx="edream.110203113231.714">route-map tag_com permit 10
 match tag 1
 set community 65001:1</t>
<t tx="edream.110203113231.715">route-map tag_com permit 20
 match tag 3
 set community 65001:3</t>
<t tx="edream.110203113231.716"></t>
<t tx="edream.110203113231.717">router bgp 65001
 no synchronization
 redistribute static
 neighbor 192.168.3.2 remote-as 65000
 neighbor 192.168.3.2 remove-private-AS
 neighbor 192.168.3.3 remote-as 65002
 neighbor 192.168.3.3 next-hop-self
 neighbor 192.168.4.2 remote-as 65001 nlri unicast multicast
 neighbor 192.168.4.2 next-hop-self
 neighbor 192.168.4.2 default-originate
 neighbor 192.168.4.2 soft-reconfiguration inbound
 no auto-summary</t>
<t tx="edream.110203113231.718">router ospf 1
 log-adjacency-changes
 passive-interface FastEthernet0/0/0
 network 192.168.3.1 0.0.0.0 area 0
 network 192.168.4.0 0.0.0.3 area 0</t>
<t tx="edream.110203113231.719">no service pad
service timestamps debug datetime localtime show-timezone
service timestamps log datetime localtime show-timezone
service password-encryption
no service single-slot-reload-enable</t>
<t tx="edream.110203113231.720">"""Modify the way exported outlines are displayed"""

from leoPlugins import *
from leoGlobals import *

def onStart (tag,keywords):
	import leoNodes
	funcToMethod(newMoreHead,leoNodes.vnode,"moreHead")

@others

# Register the handlers...
registerHandler("start2", onStart)

__version__ = "1.2" # Set version for the plugin handler.
plugin_signon(__name__)</t>
<t tx="edream.110203113231.721"># Returns the headline string in MORE format.

def newMoreHead (self,firstLevel,useVerticalBar=true):

	useVerticalBar = true # Force the vertical bar

	v = self
	level = self.level() - firstLevel
	if level &gt; 0:
		if useVerticalBar:
			s = " |\t" * level
		else:
			s = "\t"
	else:
		s = ""
	s += choose(v.hasChildren(), "+ ", "- ")
	s += v.headString()
	return s
</t>
<t tx="edream.110203113231.722"></t>
<t tx="edream.110203113231.723">[Main]
active = Yes
interval = 20</t>
<t tx="edream.110203113231.724">"""Autosave the Leo document every so often"""

# By Paul Paterson.

from leoPlugins import *
from leoGlobals import *

import ConfigParser
import time, os

@others

# Register the handlers...
AUTOSAVE_INTERVAL = 600
ACTIVE = "Yes"
LAST_AUTOSAVE = time.time()
applyConfiguration()

# Register the handlers...
registerHandler("idle", autosave)

__version__ = "0.2"
es("auto save enabled",color="orange")</t>
<t tx="edream.110203113231.725">def applyConfiguration(config=None):
	
	"""Called when the user presses the "Apply" button on the Properties form"""

	global LAST_AUTOSAVE, ACTIVE, AUTOSAVE_INTERVAL

	if config is None:
		fileName = os.path.join(app().loadDir,"../","plugins","mod_autosave.ini")
		config = ConfigParser.ConfigParser()
		config.read(fileName)

	ACTIVE = config.get("Main", "Active")
	AUTOSAVE_INTERVAL = int(config.get("Main", "Interval"))</t>
<t tx="edream.110203113231.726">def autosave(tag, keywords):
	
	"""Save the current document if it has a name"""

	global LAST_AUTOSAVE

	if ACTIVE == "Yes":
		if time.time() - LAST_AUTOSAVE &gt; AUTOSAVE_INTERVAL:
			c = top()
			if c.mFileName and c.changed:
				es("Autosave: %s" % time.ctime(),color="orange")
				c.fileCommands.save(c.mFileName)
			LAST_AUTOSAVE = time.time()</t>
<t tx="edream.110203113231.727">"""Timestamp all save operations to show when they occur"""

# By Paul Paterson.

from leoPlugins import *
from leoGlobals import *

import time
	
@others

# Register the handlers...
registerHandler("command1", timestamp)
__version__ = "0.1"
plugin_signon(__name__)</t>
<t tx="edream.110203113231.728">def timestamp(tag=None, keywords=None):
	
	cmd = keywords.get('label', 'save')

	if cmd.startswith("save") or cmd.startswith("tangle"):
		es("%s: %s" % (cmd, time.ctime()))
</t>
<t tx="edream.110203113231.729"></t>
<t tx="edream.110203113231.730">"""Dump globals at startup"""

from leoPlugins import *
from leoGlobals import *

@others

# Register the handlers...
registerHandler("start2", onStart)

__version__ = "1.2"
plugin_signon(__name__)</t>
<t tx="edream.110203113231.731">def onStart (tag,keywords):

	print "\nglobals..."
	for s in globals():
		if s not in __builtins__:
			print s
	
	print "\nlocals..."
	for s in locals():
		if s not in __builtins__:
			print s
</t>
<t tx="edream.110203113231.732">"""Enable debugging for garbage collector"""

from leoPlugins import *
from leoGlobals import *

@others

# Register the handlers...
registerHandler("start2", onStart)

__version__ = "1.2"
plugin_signon(__name__)</t>
<t tx="edream.110203113231.733">def onStart (tag,keywords):

	try:
		import gc
		gc.set_debug(gc.DEBUG_LEAK)
	except: pass</t>
<t tx="edream.110203113231.734">"""A plugin showing how to force Leo to quit."""

from leoPlugins import *
from leoGlobals import *

def forceLeoToQuit(tag,keywords):
	if not app.initing:
		print "forceLeoToQuit",tag
		app.forceShutdown()

if 0: # Force a shutdown during startup.
	print "quitting during startup"
	app.forceShutdown()

if 0: # Force a shutdown at any other time, even "idle" time.

	# Exception: do not call app.forceShutdown in a "start2" hook.

	print __doc__
	registerHandler("idle",forceLeoToQuit)

	__version__ = "1.2"
	plugin_signon(__name__)</t>
<t tx="edream.110203113231.735">"""Trace changes to objects at idle time"""

from leoPlugins import *
from leoGlobals import *

import leoGlobals
leoGlobals.debugGC = true # Force debugging on.

def printIdleRefs(tag,keywords):
	printGcRefs(verbose=false)
	
gcCount = 0

def printIdleGC(tag,keywords):
	
	# Calling printGc is too expensive to do on every idle call.
	if tag == "idle":
		global gcCount ; gcCount += 1
		if (gcCount % 20) == 0:
			printGc(tag,onlyPrintChanges=true)
	else:
		printGc(tag,onlyPrintChanges=false)

# Register the handlers...
if 1: # Very effective.
	registerHandler("idle", printIdleGC)
else: # Very precise.
	registerHandler("all", printIdleGC)
if 0: # Another idea.
	registerHandler("command2", printIdleRefs)

__version__ = "1.3"
plugin_signon(__name__)</t>
<t tx="edream.110203113231.736">"""Trace keystrokes in the outline and body panes"""

from leoPlugins import *
from leoGlobals import *

@others

# Register the handlers...
registerHandler(("bodykey1","bodykey2","headkey1","headkey2"), onKey)

__version__ = "1.2"
plugin_signon(__name__)</t>
<t tx="edream.110203113231.737">def onKey (tag,keywords):

	ch = keywords.get("ch")
	if ch and len(ch) &gt; 0:
		es("key",`ch`)</t>
<t tx="edream.110203113231.738">"""Trace most comment events, but not key, drag or idle events"""

from leoPlugins import *
from leoGlobals import *

tagCount = 0

@others

# Register the handlers...
registerHandler("all", trace_tags)

__version__ = "1.2" # Set version for the plugin handler.
plugin_signon(__name__)</t>
<t tx="edream.110203113231.739">def trace_tags (tag,keywords):
	
	global tagCount # 8/28/03

	# Almost all tags have both c and v keys in the keywords dict.
	if tag not in ("start1","end1","open1","open2"):
		c = keywords.get("c")
		v = keywords.get("v")
		if not c:
			print tagCount,tag, "c = None"
		if not v:
			if tag not in ("select1","select2","unselect1","unselect2"):
				print tagCount,tag, "v = None"
	
	if tag not in (
		"bodykey1","bodykey2","dragging1","dragging2",
		"headkey1","headkey2","idle"):
	
		tagCount += 1 # Count all other hooks.
	
		if tag in ("command1","command2"):
			print tagCount,tag,keywords.get("label")
		elif tag in ("open1","open2"):
			print tagCount,tag,keywords.get("fileName")
		else:
			if 1: # Brief
				print tagCount,tag
			else: # Verbose
				keys = keywords.items()
				keys.sort()
				for key,value in keys:
					print tagCount,tag,key,value
				print</t>
<t tx="edream.110203113231.740"></t>
<t tx="edream.110203113231.741">"""Support new @direcives"""

from leoPlugins import *
from leoGlobals import *

if 1:
	directives = "markup", # A tuple with one string.
else:
	directives = ("markup","markup2")
	
@others

# Register the handlers...
registerHandler("start1",addPluginDirectives)
registerHandler("scan-directives",scanPluginDirectives)

__version__ = "1.1"
plugin_signon(__name__)</t>
<t tx="edream.110203113231.742">def addPluginDirectives (tag,keywords):
	
	"""Add all new directives to globalDirectivesList"""
	
	global directives

	if 0:
		s = ""
		for d in directives:
			s += '@' + d + ' '
		es(s,color="blue")

	for d in directives:
		if d not in globalDirectiveList:
			globalDirectiveList.append(d)</t>
<t tx="edream.110203113231.743">def scanPluginDirectives (tag, keywords):
	
	"""Add a tuple (d,v,s,k) to list for every directive d found"""
	
	global directives

	keys = ("c","v","s","old_dict","dict","pluginsList")
	c,v,s,old_dict,dict,pluginsList = [keywords.get(key) for key in keys]

	for d in directives:
		if not old_dict.has_key(d) and dict.has_key(d):
			# Point k at whatever follows the directive.
			k = dict[d]
			k += 1 + len(d) # Skip @directive
			k = skip_ws(s,k) # Skip whitespace
			# trace(`d`,`k`)
			pluginsList.append((d,v,s,k),)
</t>
<t tx="edream.110203113231.744"></t>
<t tx="edream.110203113231.753">"""Handle images in body text"""

from leoPlugins import *
from leoGlobals import *
try:
	import Tkinter
except ImportError:
	Tkinter = None
import os

if Tkinter: # Register the handlers...

	@others

	if app.gui is None:
		app.createTkGui(__file__)

	if app.gui.guiName() == "tkinter":
		
		registerHandler("select2", onSelect)
		registerHandler("unselect1", onUnselect)
		
		__version__ = "1.2" # Set version for the plugin handler.
		plugin_signon(__name__)
</t>
<t tx="edream.110203113231.754">def onSelect (tag,keywords):

	new_v = keywords.get("new_v")
	h = new_v.headString()
	if h[:7] == "@image ":
		filename = h[7:]
		&lt;&lt; Select Image &gt;&gt;</t>
<t tx="edream.110203113231.755"># Display the image file in the text pane, if you can find the file
a = app()
c = keywords.get("c")
body = c.frame.body

if os.path.isfile(filename):
	try:
		# Note that Tkinter only understands GIF
		photo = Tkinter.PhotoImage(master=a.root, file=filename)
	except:
		es("error: cannot load image")
		return
	# Nicely display the image at the center top and push the text below.
	a.gsphoto = photo # This is soooo important.
	photoWidth = photo.width()
	bodyWidth = body.bodyCtrl.winfo_width()
	padding = int((bodyWidth - photoWidth - 16) / 2)
	padding = max(0,padding)
	a.gsimage = body.bodyCtrl.image_create("1.0",image=photo,padx=padding)
else:
	es("warning: missing image file")</t>
<t tx="edream.110203113231.756">def onUnselect (tag,keywords):

	a = app()
	old_v = keywords.get("old_v")
	if old_v:
		h = old_v.headString()
		if h[:7] == "@image ":
			&lt;&lt; Unselect Image &gt;&gt;
	else: # Leo is initializing.
		a.gsphoto = None # Holds our photo file
		a.gsimage = None # Holds our image instance within the text pane</t>
<t tx="edream.110203113231.757"># Erase image if it was previously displayed
a = app() ; c = keywords.get("c")

if a.gsimage:
	try:
		 c.frame.body.bodyCtrl.delete(a.gsimage)
	except:
		es("info: no image to erase")

# And forget about it
a.gsimage = None
a.gsphoto = None
</t>
<t tx="edream.110203113231.758">"""Adds navigation buttons to icon bar"""

from leoPlugins import *
from leoGlobals import *
from leoTkinterDialog import tkinterListBoxDialog

try:
	import Tkinter
except ImportError:
	Tkinter = None
Tk = Tkinter

import os

if Tkinter: # Register the handlers...

	@others
	
	globalInfo = globalInfoClass()

	if app.gui is None:
		app.createTkGui(__file__)

	if app.gui.guiName() == "tkinter":

		registerHandler("after-create-leo-frame", globalInfo.addNavWidgets)
		registerHandler("select2",globalInfo.updateRecentSections)
		registerHandler("command2",globalInfo.updateMarksAfterCommand)
		registerHandler(("set-mark","clear-mark"),globalInfo.updateMarks)
		registerHandler("close-frame",globalInfo.destroyFrame)
		registerHandler("destroy-all-global-windows",globalInfo.destroyAllFrames)

		__version__ = "1.2"
		plugin_signon(__name__)</t>
<t tx="edream.110203113231.759">class commanderInfoClass:
	@others</t>
<t tx="edream.110203113231.760">def __init__ (self,c,globalInfo):
	
	self.c = c
	self.globalInfo = globalInfo
	
	# The icon frame in c.
	self.iconFrame = c.frame.iconFrame
	
	# Dialogs.
	self.marksDialog = None
	self.recentSectionsDialog = None

	# Images for arrow buttons.
	self.lt_nav_disabled_image = self.lt_nav_enabled_image = None
	self.rt_nav_disabled_image = self.rt_nav_enabled_image = None
	
	# The arrow and text buttons.
	self.lt_nav_button = self.rt_nav_button = None
	sections_button = self.marks_button = None
	
	self.nav_buttons = None
</t>
<t tx="edream.110203113231.761">def addWidgets (self):
	
	c = self.c ; d = self
	
	d.lt_nav_disabled_image = self.createImage("../Icons/lt_arrow_disabled.gif")
	d.lt_nav_enabled_image  = self.createImage("../Icons/lt_arrow_enabled.gif")
	
	d.rt_nav_disabled_image = self.createImage("../Icons/rt_arrow_disabled.gif")
	d.rt_nav_enabled_image  = self.createImage("../Icons/rt_arrow_enabled.gif")
	
	for image in (
		self.lt_nav_disabled_image, self.lt_nav_enabled_image,
		self.rt_nav_disabled_image, self.rt_nav_enabled_image):
		if not image:
			return
	
	# It's so nice to be able to add ivars to classes at any time!
	self.lt_nav_button = c.frame.addIconButton(
		image=self.lt_nav_disabled_image,
		command=c.goPrevVisitedNode)
		
	&lt;&lt; define callbacks &gt;&gt;

	self.sections_button = c.frame.addIconButton(
		text="Recent",command=onRecentButton)
		
	self.marks_button = c.frame.addIconButton(
		text="Marks",command=onMarksButton)
	
	self.rt_nav_button = c.frame.addIconButton(
		image=self.rt_nav_disabled_image,
		command=c.goNextVisitedNode)
		
	# Don't dim the button when it is inactive.
	for b in (self.lt_nav_button,self.rt_nav_button):
		fg = b.cget("foreground")
		b.configure(disabledforeground=fg)
		
	# Package these buttons for the recentSectionsDialog class in leoTkinterDialog.py
	self.nav_buttons = (self.lt_nav_button, self.rt_nav_button)</t>
<t tx="edream.110203113231.762"># These are functions, not methods, so we must bind self at definition time.

def onMarksButton(self=self):

	self.marksButtonCallback()
	
def onRecentButton(self=self):

	self.recentButtonCallback()</t>
<t tx="edream.110203113231.763">def createImage (self,path):
	
	path = os.path.join(app().loadDir,path)
	path = os.path.normpath(path)
	
	try:
		image = Tkinter.PhotoImage(master=app().root,file=path)
	except:
		es("can not load icon: " + shortFileName(path))
		image = None
	return image

</t>
<t tx="edream.110203113231.764">def updateNavButtons (self):	

	d = self ; c = self.c
	
	# Make sure we have initialized properly.
	if not hasattr(d,"lt_nav_button") or not hasattr(d,"rt_nav_button"):
		return
		
	if not d.lt_nav_button or not d.rt_nav_button: # 6/30/03
		return
	
	b = d.lt_nav_button
	if c.beadPointer &gt; 1: # 10/19/03: A bit of a kludge.
		image = self.lt_nav_enabled_image
		state = "normal"
	else:
		image = d.lt_nav_disabled_image
		state = "normal" # "disabled" makes the icon look bad.
	b.configure(image=image,state=state)
	
	b = d.rt_nav_button
	if c.beadPointer + 1 &lt; len(c.beadList):
		image =self.rt_nav_enabled_image
		state = "normal"
	else:
		image = self.rt_nav_disabled_image
		state = "normal" # "disabled" makes the icon look bad.
	b.configure(image=image,state=state)</t>
<t tx="edream.110203113231.765"></t>
<t tx="edream.110203113231.766">def marksButtonCallback(self,event=None):
	
	c = self.c ; d = self.marksDialog

	if d:
		d.top.deiconify()
	else:
		# Create and run the dialog.
		title = "Marks"
		label = "Marks: " + shortFileName(c.mFileName)
		d = marksDialog(c,title,label)
		self.marksDialog = d
		d.root.wait_window(d.top)
</t>
<t tx="edream.110203113231.767">def recentButtonCallback(self,event=None):
	
	c = self.c ; d = self.recentSectionsDialog
	
	if d:
		d.top.deiconify()
		d.fillbox()
	else:
		# Create and run the dialog.]
		title = "Recent Nodes"
		label = "Recent nodes: " + shortFileName(c.mFileName)
		d = recentSectionsDialog(c,self.nav_buttons,title,label)
		self.recentSectionsDialog = d
		d.root.wait_window(d.top)
</t>
<t tx="edream.110203113231.768">class globalInfoClass:
	@others</t>
<t tx="edream.110203113231.769">def __init__ (self):
	
	self.commanderInfo = {} # keys are commanders, values are navCommanderInfo objects
</t>
<t tx="edream.110203113231.770">def addNavWidgets(self,tag,keywords):
	
	c = keywords.get("c")
	
	# Create the commanderInfo object.
	d = commanderInfoClass(c,self)
	self.commanderInfo[c] = d
	
	# Add the widgets.
	d.addWidgets()
	
</t>
<t tx="edream.110203113231.771">def destroyAllFrames(self,tag,keywords):
	
	for d in self.commanderInfo.values():
		self.destroyOneFrame(d)
		
def destroyFrame(self,tag,keywords):

	c = keywords.get("c")
	d = self.commanderInfo.get(c)
	if d:
		self.destroyOneFrame(d)
		
def destroyOneFrame(self,d):

	if d.marksDialog:
		d.marksDialog.top.destroy()
	if d.recentSectionsDialog:
		d.recentSectionsDialog.top.destroy()
	del self.commanderInfo[d.c]</t>
<t tx="edream.110203113231.772">def updateRecentSections (self,tag,keywords):
	
	c = keywords.get("c")
	info = self.commanderInfo.get(c)

	if info:
		info.updateNavButtons()
		d = info.recentSectionsDialog
		if d:
			d.fillbox()
</t>
<t tx="edream.110203113231.773">def updateMarksAfterCommand (self,tag,keywords):
	
	"""Update the marks dialog when a new window is opened."""
	
	name = keywords.get("label")
	
	if name and name.lower() in ("open","new"):
		self.updateMarks(tag,keywords)
	
def updateMarks (self,tag,keywords):
	
	"""Update the marks dialog."""
	
	c = keywords.get("c")
	# trace()
	info = self.commanderInfo.get(c)
	if info and info.marksDialog:
		info.marksDialog.fillbox()</t>
<t tx="edream.110203113231.774">def updateNavButtons (self,tag,keywords):

	"""Update the colors of c's nav buttons"""
	
	c = keywords.get("c")
	info = self.commanderInfo.get(c)
	
	if info:
		info.updateNavButtons()
</t>
<t tx="edream.110203113231.775">class marksDialog (tkinterListBoxDialog):
	
	"""A class to create the marks dialog"""

	@others</t>
<t tx="edream.110203113231.776">def __init__ (self,c,title,label):
	
	"""Create a Marks listbox dialog."""

	tkinterListBoxDialog.__init__(self,c,title,label)
</t>
<t tx="edream.110203113231.777">def createFrame(self):
	
	"""Create the frame for a Marks listbox dialog."""

	tkinterListBoxDialog.createFrame(self)
	self.addButtons()</t>
<t tx="edream.110203113231.778">def addButtons (self):
	
	"""Add buttons to a Marks listbox dialog."""
	
	f = Tk.Frame(self.outerFrame)
	f.pack()
	self.addStdButtons(f)</t>
<t tx="edream.110203113231.779">def fillbox(self,event=None):

	"""Update a Marks listbox dialog and update the listbox and update vnodeList &amp; tnodeList ivars"""

	self.box.delete(0,"end")
	self.vnodeList = []
	self.tnodeList = []

	# Make sure the node still exists.
	# Insert only the last cloned node.
	c = self.c ; v = c.rootVnode()
	i = 0
	while v:
		if v.isMarked() and v.t not in self.tnodeList:
			self.box.insert(i,v.headString().strip())
			self.tnodeList.append(v.t)
			self.vnodeList.append(v)
			i += 1
		v = v.threadNext()</t>
<t tx="edream.110203113231.780">class recentSectionsDialog (tkinterListBoxDialog):
	
	"""A class to create the recent sections dialog"""

	@others</t>
<t tx="edream.110203113231.781">def __init__ (self,c,buttons,title,label):
	
	"""Create a Recent Sections listbox dialog."""
	
	self.lt_nav_iconFrame_button, self.rt_nav_iconFrame_button = buttons

	tkinterListBoxDialog.__init__(self,c,title,label)

</t>
<t tx="edream.110203113231.782">def addButtons (self):
	
	"""Add buttons for a Recent Sections listbox dialog."""

	self.buttonFrame = f = Tk.Frame(self.outerFrame)
	f.pack()
	
	row1 = Tk.Frame(f)
	row1.pack()
	
	# Create the back and forward buttons, cloning the images &amp; commands of the already existing buttons.
	image   = self.lt_nav_iconFrame_button.cget("image")
	command = self.lt_nav_iconFrame_button.cget("command")

	self.lt_nav_button = b = Tk.Button(row1,image=image,command=command)
	b.pack(side="left",pady=2,padx=5)
	
	image   = self.rt_nav_iconFrame_button.cget("image")
	command = self.rt_nav_iconFrame_button.cget("command")

	self.rt_nav_button = b = Tk.Button(row1,image=image,command=command)
	b.pack(side="left",pady=2,padx=5)
	
	row2 = Tk.Frame(f)
	row2.pack()
	self.addStdButtons(row2)
	
	row3 = Tk.Frame(f)
	row3.pack()
	
	self.clear_button = b =  Tk.Button(row3,text="Clear All",
		width=6,command=self.clearAll)
	b.pack(side="left",pady=2,padx=5)
	
	self.delete_button = b =  Tk.Button(row3,text="Delete",
		width=6,command=self.deleteEntry)
	b.pack(side="left",pady=2,padx=5)
</t>
<t tx="edream.110203113231.783">def clearAll (self,event=None):

	"""Handle clicks in the "Delete" button of the Recent Sections listbox dialog."""

	self.c.visitedList = []
	self.vnodeList = []
	self.fillbox()
</t>
<t tx="edream.110203113231.784">def createFrame(self):
	
	"""Create the frame of a Recent Sections listbox dialog."""
	
	tkinterListBoxDialog.createFrame(self)	
	self.addButtons()
</t>
<t tx="edream.110203113231.785">def deleteEntry (self,event=None):

	"""Handle clicks in the "Delete" button of a Recent Sections listbox dialog."""
	
	c = self.c ; box = self.box
	
	# Work around an old Python bug.  Convert strings to ints.
	items = box.curselection()
	try:
		items = map(int, items)
	except ValueError: pass

	if items:
		n = items[0]
		v = self.vnodeList[n]
		del self.vnodeList[n]
		if v in c.visitedList:
			c.visitedList.remove(v)
		self.fillbox()
</t>
<t tx="edream.110203113231.786">def destroy (self,event=None):
	
	"""Hide a Recent Sections listbox dialog and mark it inactive.
	
	This is an escape from possible performace penalties"""
		
	# This is enough to disable fillbox.
	self.top.withdraw()
</t>
<t tx="edream.110203113231.787">def fillbox(self,event=None):

	"""Update a Recent Sections listbox dialog and update vnodeList &amp; tnodeList ivars"""

	# Only fill the box if the dialog is visible.
	# This is an important protection against bad performance.

	if self.top.state() == "normal":
		&lt;&lt; reconstruct the contents of self.box &gt;&gt;
		self.synchButtons()</t>
<t tx="edream.110203113231.788">c = self.c

self.box.delete(0,"end")
self.vnodeList = []
self.tnodeList = []

# Make sure the node still exists.
# Insert only the last cloned node.
i = 0
for v in c.visitedList:
	if v.exists(self.c) and v.t not in self.tnodeList:
		self.box.insert(i,v.headString().strip())
		self.tnodeList.append(v.t)
		self.vnodeList.append(v)
		i += 1
</t>
<t tx="edream.110203113231.789">def synchButtons (self):
	
	"""Synchronize the arrow boxes of a Recent Sections listbox dialog."""

	image = self.lt_nav_iconFrame_button.cget("image")
	self.lt_nav_button.configure(image=image)
	
	image = self.rt_nav_iconFrame_button.cget("image")
	self.rt_nav_button.configure(image=image)</t>
<t tx="edream.110203113231.790"></t>
<t tx="edream.110203113231.791">"""Create menu for Open With command and handle the resulting commands"""

from leoPlugins import *
from leoGlobals import *

try:
	import Tkinter
except ImportError:
	Tkinter = None

if Tkinter: # Register the handlers...

	@others

	if app.gui is None:
		app.createTkGui(__file__)

	if app.gui.guiName() == "tkinter":

		app().hasOpenWithMenu = true
		registerHandler("idle", on_idle)
		registerHandler(("start2","open2","command2"), create_open_with_menu)
	
		__version__ = "1.4" # Set version for the plugin handler.
		plugin_signon(__name__)</t>
<t tx="edream.110203113231.792"># frame.OnOpenWith creates the dict with the following entries:
# "body", "c", "encoding", "f", "path", "time" and "v".

def on_idle (tag,keywords):

	import os
	a = app()
	for dict in a.openWithFiles:
		path = dict.get("path")
		c = dict.get("c")
		encoding = dict.get("encoding",None)
		v = dict.get("v")
		old_body = dict.get("body")
		if path and os.path.exists(path):
			try:
				time = os.path.getmtime(path)
				if time and time != dict.get("time"):
					dict["time"] = time # inhibit endless dialog loop.
					# The file has changed.
					&lt;&lt; update v's body text &gt;&gt;
			except:
				es_exception() ## testing
				pass</t>
<t tx="edream.110203113231.793">&lt;&lt; set s to the file text &gt;&gt;

# Convert body and s to whatever encoding is in effect.
body = v.bodyString()
body = toEncodedString(body,encoding,reportErrors=true)
s = toEncodedString(s,encoding,reportErrors=true) # 10/13/03

conflict = body != old_body and body != s

# Set update if we should update the outline from the file.
if conflict:
	# See how the user wants to resolve the conflict.
	es("conflict in " + shortFileName(path),color="red")
	message = "Replace changed outline with external changes?"
	result = app.gui.runAskYesNoDialog("Conflict!",message)
	update = result.lower() == "yes"
else:
	update = s != body

if update:
	es("updated from: " + shortFileName(path),color="blue")
	v.setBodyStringOrPane(s,encoding) # 10/16/03
	c.selectVnode(v)
	dict["body"] = s
elif conflict:
	es("not updated from: " + shortFileName(path),color="blue")</t>
<t tx="edream.110203113231.794">try:
	# Update v from the changed temp file.
	f=open(path)
	s=f.read()
	f.close()
except:
	es("can not open " + shortFileName(path))
	break
</t>
<t tx="edream.110203113231.795">def create_open_with_menu (tag,keywords):

	if  (tag in ("start2","open2") or
		(tag=="command2" and keywords.get("label")=="new")):

		&lt;&lt; create the Open With menu &gt;&gt;
		# Enable the idle-time hook so we can check temp files created by Open With.
		from leoGlobals import enableIdleTimeHook
		enableIdleTimeHook(idleTimeDelay=500)
</t>
<t tx="edream.110203113231.796">@ Entries in the following table are the tuple (commandName,shortcut,data).

- data is the tuple (command,arg,ext).
- command is one of "os.system", "os.startfile", "os.spawnl", "os.spawnv" or "exec".

Leo executes command(arg+path) where path is the full path to the temp file.
If ext is not None, the temp file has the extension ext,
Otherwise, Leo computes an extension based on what @language directive is in effect.
@c

idle_arg = "c:/python22/tools/idle/idle.py -e "

if 1: # Default table.
	table = (
		# Opening idle this way doesn't work so well.
		# ("&amp;Idle",   "Alt+Shift+I",("os.system",idle_arg,".py")),
		("&amp;Word",   "Alt+Shift+W",("os.startfile",None,".doc")),
		("Word&amp;Pad","Alt+Shift+T",("os.startfile",None,".txt")))
elif 1: # Test table.
	table = ("&amp;Word","Alt+Shift+W",("os.startfile",None,".doc")),
else: # David McNab's table.
	table = ("X&amp;Emacs", "Ctrl+E", ("os.spawnl","/usr/bin/gnuclient", None)),

top().frame.menu.createOpenWithMenuFromTable(table)</t>
<t tx="edream.110203113231.797">"""emacs handler"""

from leoPlugins import *
from leoGlobals import *

# path = "/usr/bin/gnuclient"
path = r"c:\Program Files\XEmacs\XEmacs-21.4.13\i586-pc-win32\xemacs.exe"

def open_in_emacs (tag,keywords):
	top() and top().openWith(("os.spawnl",path,None),)

# Register the handlers...

if 1: # Edit when double-clicking a node's icon.
	registerHandler("icondclick2", open_in_emacs) # 1/29/03: activate on _double_ click.
else: # Edit when selecting any node. That's a bit much for my taste.
	registerHandler("select2", open_in_emacs)

__version__ = "1.4"
plugin_signon(__name__)</t>
<t tx="edream.110203113231.799">"""vim handler"""

# Contributed by Andrea Galimberti.
# Edited by Felix Breuer.

#  To use this plugin do the following:
#
# - Start VIM as server: vim --servername "LEO"
#   The name of the server *must* be "LEO".
#   If you wish to use a different server with LEO, change the
#   variable _vim_cmd below. If you want Leo to start the VIM server
#   uncomment the corresponding line below.
#
# - Single-click on a node's icon to open that node in VIM.
#
# - Leo will update the node in the outline when you save the file in VIM.

from leoPlugins import *
from leoGlobals import *

# This command is used to communicate with the vim server. If you use gvim
# you can leave the command as is, you do not need to change it to "gvim ..."
# Note: _vim_cmd must end with a space.

_vim_cmd = r"c:\vim\vim61\gvim --servername LEO"
_vim_cmd = "vim --servername LEO "

@others

# Register the handlers...
registerHandler("iconclick2", open_in_vim)

# if you want to start a (g)vim server when leo is started
# uncomment this line:
# os.system("gvim --servername LEO")

__version__ = "1.4" # Set version for the plugin handler.
plugin_signon(__name__)
</t>
<t tx="edream.110203113231.800">def open_in_vim (tag,keywords):
	if not top():
		return

	v=keywords['v']
	# Find dictionary with infos about this node
	this=filter(lambda x: id(x['v'])==id(v), app().openWithFiles)
	
	# Retrieve the name of the temporary file (if any).
	if this != []:
		path=this[0]['path']
	else:
		path=''
	
	# if the body has changed we need to open a new 
	# temp file containing the new body in vim
	if  not os.path.exists(path) or \
		not hasattr(v,'OpenWithOldBody') or \
		v.bodyString!=v.OpenWithOldBody:
		# if there is an old temp file we need to delete it,
		# remove it from the dictionary and delete the old
		# buffer from vim
		if path != '':
			os.remove(path)
			app().openWithFiles=filter(lambda x: x['path']!=path,app().openWithFiles)
			os.system(_vim_cmd+"--remote-send '&lt;C-\\&gt;&lt;C-N&gt;:bd! "+path+"&lt;CR&gt;'")
		# update old body with new contents
		v.OpenWithOldBody=v.bodyString()
		# open the node in vim (note the space after --remote)
		top().openWith(("os.system", _vim_cmd+"--remote ", None),) # 6/27/03: add comma.
	# else, display the old temp file in vim because other files 
	# may have been opened in the meantime
	else:
		# We reopen the file. if it is still open, the buffer is raised
		# if the changes to the current buffer were not saved, vim will
		# notify the user of that fact at this point
		os.system(_vim_cmd+"--remote-send '&lt;C-\\&gt;&lt;C-N&gt;:e "+path+"&lt;CR&gt;'")
</t>
<t tx="edream.110203113231.803"></t>
<t tx="edream.110203113231.804">"""Exports an outline to a word document.

Make sure word is running with an open (empty) document.

Click "plugins ... word export ... export"
to export the selected outline to Word."""

@language python

from leoPlugins import *
from leoGlobals import *
try:
	import win32com.client # From win32 extensions: http://www.python.org/windows/win32/
	client = win32com.client
except ImportError:
	client = None
import ConfigParser

@others

if client: # Register the handlers...

	# No hooks, we just use the cmd_Export to trigger an export
	__version__ = "0.1"
	__name__ = "Word Export"

	plugin_signon("word_export")</t>
<t tx="edream.110203113231.805">def getConfiguration():
	
	"""Called when the user presses the "Apply" button on the Properties form"""

	fileName = os.path.join(app().loadDir,"../","plugins","word_export.ini")
	config = ConfigParser.ConfigParser()
	config.read(fileName)
	return config
</t>
<t tx="edream.110203113231.806">def getWordConnection():
	
	"""Get a connection to Word"""

	es("Trying to connect to Word")
	try:
		word = win32com.client.Dispatch("Word.Application")
		return word
	except Exception, err:
		# es("Failed to connect to Word: %s", err)
		es("Failed to connect to Word",color="blue")
		es("Please make sure word is running with an open (empty) document.")
		return None</t>
<t tx="edream.110203113231.807">def doPara(word, text, style=None):
	
	"""Write a paragraph to word"""
	
	doc = word.Documents(word.ActiveDocument)
	sel = word.Selection
	if style:
		try:
			sel.Style = doc.Styles(style)
		except:
			es("Unknown style: '%s'" % style)
	sel.TypeText(text)
	sel.TypeParagraph()</t>
<t tx="edream.110203113231.808">def writeNodeAndTree(word, header_style, level, maxlevel=3, usesections=1, sectionhead="", vnode=None):
	
	"""Write a node and its children to Word"""

	c = top()
	if vnode is None:
		vnode = top().currentVnode()
	#
	dict = scanDirectives(c,v=vnode)
	encoding = dict.get("encoding",None)
	if encoding == None:
		encoding = app().config.default_derived_file_encoding
	# 
	s = vnode.bodyString()
	s = toEncodedString(s,encoding,reportErrors=true)
	doPara(word, s)
	#
	for i in range(vnode.numberOfChildren()):
		if usesections:
			thishead = "%s%d." % (sectionhead, i+1)
		else:
			thishead = ""
		child = vnode.nthChild(i)
		h = child.headString()
		h = toEncodedString(h, encoding, reportErrors=true)
		doPara(word, "%s %s" % (thishead, h), "%s %d" % (header_style, min(level, maxlevel)))
		writeNodeAndTree(word, header_style, level+1, maxlevel, usesections, thishead, child)
</t>
<t tx="edream.110203113231.809">def cmd_Export(event=None):

	"""Export the current node to Word"""

	try:
		word = getWordConnection()
		if word:
			header_style = getConfiguration().get("Main", "Header_Style")
			# Based on the rst plugin
			es("Writing tree to Word",color="blue")
			config = getConfiguration()
			writeNodeAndTree(word,
				config.get("Main", "header_style").strip(),
				1,
				int(config.get("Main", "max_headings")),
				config.get("Main", "use_section_numbers") == "Yes",
				"")						 
			es("Done!")
	except Exception,err:
		es("Failed to connect to Word",color="blue")
		es("Please make sure an empty word document is open.")</t>
<t tx="edream.110203113231.810">[Main]
use_styles = Yes
use_section_numbers = Yes
use_current_document = Yes
max_headings = 6
header_style = Heading

</t>
<t tx="edream.110203113231.811"></t>
<t tx="edream.110203113231.812">"""Open any empty file as a minimal .leo file"""

from leoPlugins import *
from leoGlobals import *

&lt;&lt; define minimal .leo file &gt;&gt;
@others

# Register the handlers...
registerHandler("open1", onOpen)

__version__ = "1.2"
plugin_signon(__name__)</t>
<t tx="edream.110203113231.813">empty_leo_file = """&lt;?xml version="1.0" encoding="iso-8859-1"?&gt;
&lt;leo_file&gt;
&lt;leo_header file_format="2" tnodes="0" max_tnode_index="0" clone_windows="0"/&gt;
&lt;globals body_outline_ratio="0.5"&gt;
	&lt;global_window_position top="145" left="110" height="24" width="80"/&gt;
	&lt;global_log_window_position top="0" left="0" height="0" width="0"/&gt;
&lt;/globals&gt;
&lt;preferences allow_rich_text="0"&gt;
&lt;/preferences&gt;
&lt;find_panel_settings&gt;
	&lt;find_string&gt;&lt;/find_string&gt;
	&lt;change_string&gt;&lt;/change_string&gt;
&lt;/find_panel_settings&gt;
&lt;vnodes&gt;
&lt;v a="V"&gt;&lt;vh&gt;NewHeadline&lt;/vh&gt;&lt;/v&gt;
&lt;/vnodes&gt;
&lt;tnodes&gt;
&lt;/tnodes&gt;
&lt;/leo_file&gt;"""</t>
<t tx="edream.110203113231.814">def onOpen (tag,keywords):

	import os
	file_name = keywords.get('fileName')

	if file_name and os.path.getsize(file_name)==0:
		# Rewrite the file before really opening it.
		es("rewriting empty .leo file: %s" % (file_name))
		file = open(file_name,'w')
		file.write(empty_leo_file)
		file.flush()
		file.close()

</t>
<t tx="edream.110203113231.815">@language python

"""Opens up cmd and explorer window to same directory 
as @file nodes or children ..."""

&lt;&lt; about the open shell plugin &gt;&gt;

import leo,os,os.path,sys
from leoPlugins import *
from leoGlobals import *

pathToExplorer = 'c:/windows/explorer.exe'
pathToCmd = 'c:/windows/system32/cmd.exe'

@others

# Register the handlers...
registerHandler("after-create-leo-frame", load_menu)

__version__ = "1.4"
plugin_signon(__name__)</t>
<t tx="edream.110203113231.816">@ Written by Ed Taekema.  Modified by E.K.Ream

Please submit bugs / feature requests to etaekema@earthlink.net"""

This is a simple plugin for leo 3.12 that allows the user to open either an xterm on linux or a cmd windows/explorer window on win32 in the directory of the current @file.  This allows quick navigation to facilitate testing and navigating large systems with complex direcgtories.

Current limitations ...

1. Not tested on Mac OS X ...
2. On win32, the cmd window will not open in the right directory if the @file location is on a different drive than the .leo file that is being edited.
3. On linux, xterm must be in your path.
</t>
<t tx="edream.110203113231.817">def load_menu(tag,keywords):
	
	if sys.platform=="win32":
		table = (
			("&amp;Open Console Window",None,launchCmd),
			("Open &amp;Explorer",None,launchExplorer)) 
	else:
		table = ( ("Open &amp;xterm",None,launchxTerm), ) 
	
	top().frame.menu.createNewMenu("E&amp;xtensions","top")
	top().frame.menu.createMenuItemsFromTable("Extensions",table)
</t>
<t tx="edream.110203113231.818">def _getpath(c,v):
	dict = scanDirectives(c,v)
	d = dict.get("path")

	if d == None:

		if v.isAtFileNode():
			filename = v.atFileNodeName()
		if v.isAtNoSentinelsFileNode():
			filename = v.atNoSentinelsFileNodeName()
		if v.isAtRawFileNode():
			filename = v.atRawFileNodeName()
		if v.isAtSilentFileNode():
			filename = v.atSilentFileNodeName()

		d = os.path.dirname(filename)

	d = os.path.normpath(d)
	return d
</t>
<t tx="edream.110203113231.819">def _getCurrentNodePath():
	c = leo.top()
	v = c.currentVnode()
	f = v.atFileNodeName()
	d = _getpath(c,v)
	return d
</t>
<t tx="edream.110203113231.820">def launchCmd(event=None):
	
	global pathToCmd

	d = _getCurrentNodePath()
	myCmd = 'cd ' + d
	os.spawnl(os.P_NOWAIT, pathToCmd, '/k ', myCmd)</t>
<t tx="edream.110203113231.821">def launchExplorer(event=None):
	
	global pathToExplorer

	d = _getCurrentNodePath()
	os.spawnl(os.P_NOWAIT,pathToExplorer, ' ', d)

</t>
<t tx="edream.110203113231.822">def launchxTerm(not_used):

	d = _getCurrentNodePath()
	curdir = os.getcwd()
	os.chdir(d)
	os.spawnlp(os.P_NOWAIT, 'xterm', '-title Leo')
	os.chdir(curdir)</t>
<t tx="edream.110203113231.823">In Python 2.3 the source files should declare the encoding.

See http://www.python.org/peps/pep-0263.html for full details.</t>
<t tx="edream.110203113231.824">@first # -*- coding: utf-8 -*-

"""Translate a few menu items into French"""

from leoPlugins import *
from leoGlobals import *

@others

# Register the handlers...
registerHandler("menu1", onMenu)
	
__version__ = "1.2"
plugin_signon(__name__)</t>
<t tx="edream.110203113231.825">@ The translation table used by setRealMenuNamesFromTable has entries of the form:

	("official name","translated name"),

Ampersands in the translated name indicate that the following character is to be underlined.

The official name can be any name equivalent to the standard English menu names.  Leo "canonicalizes" the official name by converting to lower case and removing any non-letters.  Thus, the following are  equivalent:
	("Open...","&amp;Ouvre"),
	("open",   "&amp;Ouvre"),
	("&amp;Open",  "&amp;Ouvre"),
@c
def onMenu (tag,keywords):
	trace(tag,keywords)
	c = keywords.get("c")
	table = (
		("Open...","&amp;Ouvre"),
		("OpenWith","O&amp;uvre Avec..."),
		("close","&amp;Ferme"),
		("Undo Typing","French &amp;Undo Typing"), # Shows you how much French I know ;-)
		("Redo Typing","French &amp;Redo Typing"),
		("Can't Undo", "French Can't Undo"),
		("Can't Redo", "French Can't Redo"))
	# Call the convenience routine to do the work.
	c.frame.menu.setRealMenuNamesFromTable(table)
</t>
<t tx="edream.110203113231.826">@first # -*- coding: utf-8 -*-
@language python

"""traduit les menus en Français"""

# French translation completed by Frédéric Momméja, Spring 2003

from leoPlugins import *
from leoGlobals import *

@others

# Register the handlers...
registerHandler("menu1", onMenu)

__version__ = "1.4" # Set version for the plugin handler.
plugin_signon(__name__)
</t>
<t tx="edream.110203113231.827">def onMenu (tag,keywords):
	c = keywords.get("c")
	table = (
		("File","&amp;Fichier"),
			("New","&amp;Nouveau"),
			("Open...","&amp;Ouvrir"),
			("OpenWith","Ouvrir Ave&amp;c..."),
			("Close","&amp;Fermer"),
			("Save","Enregi&amp;strer"),
			("Save As","Enre&amp;gistrer sous..."),
			("Save To","Enregistrer une co&amp;pie..."),
			("Revert To Saved","&amp;Version Enregistrée"),
			("Recent Files...","&amp;Fichiers récents..."),
			("Read/Write...", "&amp;Lire/Écrire..."),
				("Read Outline Only", "Relire &amp;Arborescence seule"),
				("Read @file Nodes", "Relire Structure @&amp;file seule"),
				("Write missing @file Nodes", "Écrire @file &amp;manquants sur Disque"),
				("Write Outline Only", "Écrire Arborescence &amp;seule"),
				("Write @file Nodes", "Écrire &amp;Noeuds @file seuls"),
			("Tangle...", "&amp;Transférer (Tangle)..."),
				("Tangle All", "&amp;Tout"),
				("Tangle Marked", "Noeuds &amp;Marqués"),
				("Tangle", "&amp;Sélection"),
			("Untangle...", "&amp;Ramener (Untangle)..."),
				("Untangle All", "&amp;Tout"),
				("Untangle Marked", "Noeuds &amp;Marqués"),
				("Untangle", "&amp;Sélection"),
			("Import...", "&amp;Importer..."),
				("Import To @file", "Dans Structure @&amp;file"),
				("Import To @root", "Dans Structure @&amp;root"),
				("Import CWEB Files", "Fichier &amp;CWEB"),
				("Import noweb Files", "Fichier &amp;Noweb"),
				("Import Flattened Outline", "Fichier &amp;MORE"),
			("Export...", "&amp;Exporter..."),
				("Export Headlines", "&amp;Entêtes Noeuds descendants vers .txt"),
				("Outline To CWEB", "Arborescence vers &amp;CWEB"),
				("Outline To Noweb", "Arborescence vers &amp;Noweb"),
				("Flatten Outline", "Arborescence vers &amp;MORE"),
				("Remove Sentinels", "En supprimant &amp;Sentinelles"),
				("Weave", "&amp;Arborescence descendante vers .txt"),
			("Exit","&amp;Quitter"),
		("Edit","&amp;Edition"),
			("Undo Typing","Ann&amp;uler saisie"),
			("Redo Typing","&amp;Répèter saisie"),
			("Can't Undo", "Impossible d'annuler"),
			("Can't Redo", "Impossible de répéter"),
			("Cut", "C&amp;ouper"),
			("Copy", "Co&amp;pier"),
			("Paste", "Co&amp;ller"),
			("Delete", "&amp;Supprimer"),
			("Select All", "&amp;Tout Sélectionner"),
			("Edit Body...", "Éditer &amp;Contenu..."),
				("Extract Section", "E&amp;xtraire Section"),
				("Extract Names", "Extraire &amp;Noms de Sections"),
				("Extract", "&amp;Extraire Sélection"),
				("Convert All Blanks", "Convertir Espaces &amp;Arborescence"),
				("Convert All Tabs", "Convertir Tabulations Ar&amp;borescence"),
				("Convert Blanks", "Convertir &amp;Espaces"),
				("Convert Tabs", "Convertir &amp;Tabulations"),
				("Insert Body Time/Date", "Insérer la &amp;Date/Heure"),
				("Reformat Paragraph", "Reformater &amp;Paragraphe"),
				("Indent", "&amp;Indenter"),
				("Unindent", "Dé&amp;sindenter"),
				("Match Brackets", "&amp;Vérifier Parité des Signes"), #  &lt;({["), #EKR
			("Edit Headline...", "Éditer &amp;Entête..."),
				("Edit Headline", "&amp;Modifier l'Entête"),
				("End Edit Headline", "Modification &amp;Terminée"),
				("Abort Edit Headline", "&amp;Annuler Modification"),
				("Insert Headline Time/Date", "Insérer la &amp;Date/Heure"),
				("Toggle Angle Brackets", "Ajouter/supprimer Marques de &amp;Section"),
			("Find...", "C&amp;hercher..."),
				("Find Panel", "Dialogue de Re&amp;cherche"),
				("Find Next", "Chercher &amp;Suivant"),
				("Find Previous", "Chercher &amp;Précédent"),
				("Replace", "&amp;Remplacer"),
				("Replace, Then Find", "Remplacer Chercher à &amp;Nouveau"),
			("Go To Line Number", "&amp;Atteindre Ligne No..."),
			("Execute Script", "E&amp;xécuter un Script Python"),
			("Set Font...", "&amp;Définir les Polices..."),
			("Set Colors...", "Dé&amp;finir les Couleurs..."),
			("Show Invisibles", "Afficher Caractères &amp;invisibles"),
			("Hide Invisibles", "Masquer Caractères &amp;invisibles"),
			("Preferences", "Préfére&amp;nces"),
		("Outline", "Arb&amp;orescence"),
			("Cut Node", "Co&amp;uper le Noeud"),
			("Copy Node", "C&amp;opier le Noeud"),
			("Paste Node", "Co&amp;ller le Noeud"),
			("Delete Node", "&amp;Supprimer le Noeud"),
			("Insert Node", "Insé&amp;rer un Noeud"),
			("Clone Node", "Clo&amp;ner le Noeud"),
			("Sort Children", "&amp;Trier les Noeuds Enfants"),
			("Sort Siblings", "Trier le Ni&amp;veau"),
			("Expand/Contract...", "&amp;Déployer/Refermer"),
				("Contract All", "&amp;Tout Refermer"),
				("Contract Node", "&amp;Refermer Noeud"),
				("Contract Parent", "Refermer Noeud &amp;Parent"),
				("Expand Prev Level", "Déployer Niveau pré&amp;cédent"),
				("Expand Next Level", "Déployer Niveau &amp;suivant"),
				("Expand To Level 1", "Déployer &amp;1 Niveau"),
				("Expand To Level 2", "Déployer &amp;2 Niveaux"),
				("Expand To Level 3", "Déployer &amp;3 Niveaux"),
				("Expand To Level 4", "Déployer &amp;4 Niveaux"),
				("Expand To Level 5", "Déployer &amp;5 Niveaux"),
				("Expand To Level 6", "Déployer &amp;6 Niveaux"),
				("Expand To Level 7", "Déployer &amp;7 Niveaux"),
				("Expand To Level 8", "Déployer &amp;8 Niveaux"),
				("Expand All", "Tout &amp;Déployer"),
				("Expand Node", "Déplo&amp;yer Noeud"),
			("Move...", "Dé&amp;placer..."),
				("Move Down", "Vers le &amp;Bas"),
				("Move Left", "Vers la &amp;Gauche"),
				("Move Right", "Vers la &amp;Droite"),
				("Move Up", "Vers le &amp;Haut"),
				("Promote", "&amp;Enfants vers la Gauche"),
				("Demote", "&amp;Noeuds suivants vers la Droite"),
			("Mark/Unmark...", "Mar&amp;quage..."),
				("Mark", "&amp;Marquer/Effacer Marque"),
				("Mark Subheads", "Marquer En&amp;fants"),
				("Mark Changed Items", "Marquer &amp;Noeuds modifiés"),
				("Mark Changed Roots", "Marquer @&amp;root modifiés"),
				("Mark Clones", "Marquer &amp;Clones"),
				("Unmark All", "&amp;Effacer toutes les Marques"),
			("Go To...", "Se Dépla&amp;cer vers..."),
				("Go To Next Marked", "&amp;Marque suivante"),
				("Go To Next Changed", "M&amp;odification suivante"),
				("Go To Next Clone", "&amp;Clone suivant"),
				("Go To First Node", "&amp;Premier Noeud"),
				("Go To Last Node", "&amp;Dernier Noeud"),
				("Go To Parent", "&amp;Noeud Parent"),
				("Go To Prev Sibling", "Noe&amp;ud précédent"),
				("Go To Next Sibling", "Noeud &amp;suivant"),
				("Go To Prev Visible", "Noeud &amp;Visible précédent"),
				("Go To Next Visible", "Noeud V&amp;isible suivant"),
				("Go Back", "De&amp;rnière Position"),
				("Go Next", "Posi&amp;tion suivante"),
		("Window", "Fenê&amp;tre"),
			("Equal Sized Panes", "Panneaux de &amp;même taille"),
			("Toggle Active Pane", "&amp;Bascule Panneau actif"),
			("Toggle Split Direction", "Bascule &amp;Horiz/Vert"),
			("Cascade", "Fenêtres Leo en &amp;Cascade"),
			("Minimize All", "&amp;Réduit toutes les Fenêtres"),
			("Open Compare Window", "Ouvrir Fenêtre de Com&amp;paraison..."),
			("Open Python Window", "Ouvrir Fenêtre Python (IDLE)..."),
		("Help", "&amp;Aide"),
			("About Leo...", "Au &amp;sujet de Leo..."),
			("Online Home Page", "&amp;Page d'Accueil en ligne"),
			("Open Online Tutorial", "Ouvrir &amp;Tutoriel en ligne"),
			("Open LeoDocs.leo", "Ouvrir Leo&amp;Docs.leo"),
			("Open LeoConfig.leo", "Ouvrir Leo&amp;Config.leo"),
			("Apply Settings", "Appliquer les &amp;Réglages"))
	# Call the convenience routine to do the work.
	c.frame.menu.setRealMenuNamesFromTable(table)

</t>
<t tx="edream.110203113231.828"></t>
<t tx="edream.110203113231.829">"""Rebind up/down arrow keys"""

from leoPlugins import *
from leoGlobals import *

try:
	import Tkinter
except ImportError:
	Tkinter = None

if Tkinter: # Register the handlers...

	@others

	if app.gui is None:
		app.createTkGui(__file__)

	if app.gui.guiName() == "tkinter":

		registerHandler("open2", onOpen)
	
		__version__ = "1.3"
		plugin_signon(__name__)</t>
<t tx="edream.110203113231.830"># Warning: the bindings created this way conflict with shift-arrow keys.

def onOpen (tag,keywords):

	c = keywords.get("new_c")
	body = c.frame.body
	tree = c.frame.tree

	# Add "hard" bindings to have up/down arrows move by visual lines.
	old_binding = body.bodyCtrl.bind("&lt;Up&gt;")
	if len(old_binding) == 0:
		body.bodyCtrl.bind("&lt;Up&gt;",tree.OnUpKey)

	old_binding = body.bodyCtrl.bind("&lt;Down&gt;")
	if len(old_binding) == 0:
		body.bodyCtrl.bind("&lt;Down&gt;",tree.OnDownKey)
</t>
<t tx="edream.110203113231.831"></t>
<t tx="edream.110203113231.832"></t>
<t tx="edream.110203113231.833">"""Create a Plugins menu"""

# Written by Paul A. Paterson.  Revised by Edward K. Ream.

## To do: add Revert button to each dialog.

from leoPlugins import *
from leoGlobals import *
import ConfigParser,glob,os,sys

try:
	import Tkinter
except ImportError:
	Tkinter = None
Tk = Tkinter

if Tkinter: # Register the handlers...

	@others

	if app.gui is None:
		app.createTkGui(__file__)

	if app.gui.guiName() == "tkinter":
		registerHandler("create-optional-menus",createPluginsMenu)
		
		__version__ = "1.2"
		plugin_signon(__name__)</t>
<t tx="edream.110203113231.834">class PlugIn:

	"""A class to hold information about one plugin"""

	@others
	
</t>
<t tx="edream.110203113231.835">def __init__(self, filename):

	"""Initialize the plug-in"""

	# Import the file to find out some interesting stuff
	# Do not use the imp module: we only want to import these files once!
	self.mod = self.doc = self.version = None
	try:
		self.mod = __import__(os.path.splitext(os.path.basename(filename))[0])
		if not self.mod:
			return
		self.name = self.mod.__name__
		self.doc = self.mod.__doc__
		self.version = self.mod.__dict__.get("__version__") # "&lt;unknown&gt;")
		# if self.version: print self.version,shortFileName(filename)
	except: return

	&lt;&lt; Check if this can be configured &gt;&gt;
	&lt;&lt; Check if this has an apply &gt;&gt;
	&lt;&lt; Look for additional commands &gt;&gt;</t>
<t tx="edream.110203113231.836"># Look for a configuration file
self.configfilename = "%s.ini" % os.path.splitext(filename)[0]
self.hasconfig = os.path.isfile(self.configfilename)
</t>
<t tx="edream.110203113231.837">@ Look for an apply function ("applyConfiguration") in the module.

This is used to apply changes in configuration from the properties window
@c

self.hasapply = hasattr(self.mod, "applyConfiguration")
</t>
<t tx="edream.110203113231.838">@ Additional commands can be added to the plugin menu by having functions in the module called "cmd_whatever". These are added to the main menu and will be called when clicked
@c

self.othercmds = {}

for item in self.mod.__dict__.keys():
	if item.startswith("cmd_"):
		self.othercmds[item[4:]] = self.mod.__dict__[item]
</t>
<t tx="edream.110203113231.839">def about(self,event=None):
	
	"""Put up an "about" dialog for this plugin"""

	PluginAbout(self.name, self.version, self.doc)</t>
<t tx="edream.110203113231.840">def properties(self, event=None):
	
	"""Create a modal properties dialog for this plugin"""

	PropertiesWindow(self.configfilename, self)</t>
<t tx="edream.110203113231.841">class PropertiesWindow:

	"""A class to create and run a Properties dialog for a plugin"""

	@others</t>
<t tx="edream.110203113231.842">def __init__(self, filename, plugin):

	"""Initialize the property window"""
	
	&lt;&lt; initialize all ivars &gt;&gt;
	&lt;&lt; create the frame from the configuration data &gt;&gt;</t>
<t tx="edream.110203113231.843"># config stuff.
config = ConfigParser.ConfigParser()
config.read(filename)
self.filename = filename
self.config = config
self.plugin = plugin

# self.entries is a list of tuples (section, option, e),
# where section and options are strings and e is a Tk.Entry widget.
# This list is used by writeConfiguration to write all settings.
self.entries = []
</t>
<t tx="edream.110203113231.844">root = app.root

&lt;&lt; Create the top level and the main frame &gt;&gt;
&lt;&lt; Create widgets for each section and option &gt;&gt;
&lt;&lt; Create Ok, Cancel and Apply buttons &gt;&gt;

app.gui.center_dialog(top) # Do this after packing.
top.grab_set() # Make the dialog a modal dialog.
top.focus_force() # Get all keystrokes.
root.wait_window(top)</t>
<t tx="edream.110203113231.845">self.top = top = Tk.Toplevel(root)
app.gui.attachLeoIcon(self.top)
top.title("Properties of "+ plugin.name)
top.resizable(0,0) # neither height or width is resizable.
	
self.frame = frame = Tk.Frame(top)
frame.pack(side="top")</t>
<t tx="edream.110203113231.846"># Create all the entry boxes on the screen to allow the user to edit the properties
sections = config.sections()
sections.sort()
for section in sections:
	# Create a frame for the section.
	f = Tk.Frame(top, relief="groove",bd=2)
	f.pack(side="top",padx=5,pady=5)
	Tk.Label(f, text=section.capitalize()).pack(side="top")
	# Create an inner frame for the options.
	b = Tk.Frame(f)
	b.pack(side="top",padx=2,pady=2)
	# Create a Tk.Label and Tk.Entry for each option.
	options = config.options(section)
	options.sort()
	row = 0
	for option in options:
		e = Tk.Entry(b)
		e.insert(0, config.get(section, option))
		Tk.Label(b, text=option).grid(row=row, column=0, sticky="e", pady=4)
		e.grid(row=row, column=1, sticky="ew", pady = 4)
		row += 1
		self.entries.append((section, option, e))</t>
<t tx="edream.110203113231.847">box = Tk.Frame(top, borderwidth=5)
box.pack(side="bottom")

list = [("OK",self.onOk),("Cancel",top.destroy)]
if plugin.hasapply:
	list.append(("Apply",self.onApply),)

for text,f in list:
	Tk.Button(box,text=text,width=6,command=f).pack(side="left",padx=5)</t>
<t tx="edream.110203113231.848">def onApply(self):
	
	"""Event handler for Apply button"""
	self.writeConfiguration()
	self.plugin.mod.applyConfiguration(self.config)

def onOk(self):

	"""Event handler for Ok button"""
	self.writeConfiguration()
	self.top.destroy()</t>
<t tx="edream.110203113231.849">def writeConfiguration(self):
	
	"""Write the configuration to disk"""

	# Set values back into the config item.
	for section, option, entry in self.entries:
		self.config.set(section, option, entry.get())

	# Write out to the file.
	f = open(self.filename, "w")
	self.config.write(f)
	f.close()
</t>
<t tx="edream.110203113231.850">class PluginAbout:
	
	"""A class to create and run an About Plugin dialog"""
	
	@others
</t>
<t tx="edream.110203113231.851">def __init__(self, name, version, about):
	
	"""# Create and run a modal dialog giving the name,
	version and description of a plugin.
	"""

	root = app().root
	self.top = top = Tk.Toplevel(root)
	app.gui.attachLeoIcon(self.top)
	top.title("About " + name)
	top.resizable(0,0) # neither height or width is resizable.
	
	frame = Tk.Frame(top)
	frame.pack(side="top")
	&lt;&lt; Create the contents of the about box &gt;&gt;
	&lt;&lt; Create the close button &gt;&gt;
	
	app.gui.center_dialog(top) # Do this after packing.
	top.grab_set() # Make the dialog a modal dialog.
	top.focus_force() # Get all keystrokes.
	root.wait_window(top)</t>
<t tx="edream.110203113231.852">if 0: # The name is now in the window's title.
	Tk.Label(frame, text="Name:").grid(row=0, column=0, sticky="E")
	Tk.Label(frame, text=name).grid(row=0, column=1, sticky="W")
	Tk.Label(frame, text="Version").grid(row=1, column=0, sticky="E")
	Tk.Label(frame, text=version).grid(row=1, column=1, sticky="W")
	Tk.Label(frame, text=about, borderwidth=10, justify="left").grid(columnspan=2)
else:
	Tk.Label(frame, text="Version " + version).pack()
	Tk.Label(frame, text=about, borderwidth=10).pack()</t>
<t tx="edream.110203113231.853">buttonbox = Tk.Frame(top, borderwidth=5)
buttonbox.pack(side="bottom")

self.button = Tk.Button(buttonbox, text="Close", command=top.destroy)
self.button.pack(side="bottom")</t>
<t tx="edream.110203113231.854">def createPluginsMenu (tag,keywords):

	c = keywords.get("c")
	old_path = sys.path[:] # Make a _copy_ of the path.

	path = os.path.join(app().loadDir,"..","plugins")
	sys.path = path
	
	if os.path.exists(path):
		# Create a list of all active plugins.
		files = glob.glob(os.path.join(path,"*.py"))
		files.sort()
		plugins = [PlugIn(file) for file in files]
		items = [(p.name,p) for p in plugins if p.version]
		if items:
			items.sort()
			c.pluginsMenu = pluginMenu = c.frame.menu.createNewMenu("&amp;Plugins")
			&lt;&lt; add items to the plugins menu &gt;&gt;
			
	sys.path = old_path


</t>
<t tx="edream.110203113231.855">for name,p in items:
	if p.hasconfig:
		m = c.frame.menu.createNewMenu(p.name, "&amp;Plugins")
		table = [("About...", None, p.about),
				 ("Properties...", None, p.properties)]
		if p.othercmds:
			table.append(("-", None, None))
			items = [(cmd,None,fn) for cmd,fn in p.othercmds.iteritems()]
			items.sort()
			table.extend(items)
		c.frame.menu.createMenuEntries(m, table)
	else:
		table = ((p.name, None, p.about),)
		c.frame.menu.createMenuEntries(pluginMenu, table)</t>
<t tx="edream.110203113231.856"># @ignore
@language python

"""Test file for Plugins menu protocols"""

from leoPlugins import *
from leoGlobals import *

try:
	import Tkinter
except ImportError:
	Tkinter = None

import os

if Tkinter: # Register the handlers...

	@others

	if app.gui is None:
		app.createTkGui(__file__)

	if app.gui.guiName() == "tkinter":

		registerHandler("select2", onSelect)
		registerHandler("unselect1", onUnselect)
		
		__version__ = "1.1"
		plugin_signon(__name__)</t>
<t tx="edream.110203113231.857">def applyConfiguration(config):
	
	sections = config.sections()
	sections.sort()

	for section in sections:
		options = config.options(section)
		options.sort()
		for option in options:
			print section, option, config.get(section, option)
</t>
<t tx="edream.110203113231.858">def cmd_fn1(event=None):
	es("Fn1",color="blue")

def cmd_fn2(event=None):
	es("Fn2",color="blue")

def cmd_fn3(event=None):
	es("Fn3",color="blue")
</t>
<t tx="edream.110203113231.859">def onSelect (tag,keywords):

	new_v = keywords.get("new_v")
	h = new_v.headString()
	if h[:7] == "@image ":
		filename = h[7:]
		&lt;&lt; Select Image &gt;&gt;</t>
<t tx="edream.110203113231.860"># Display the image file in the text pane, if you can find the file
a = app()
c = keywords.get("c")
body = c.frame.body

if os.path.isfile(filename):
	try:
		# Note that Tkinter only understands GIF
		photo = Tkinter.PhotoImage(master=a.root, file=filename)
	except:
		es("error: cannot load image")
		return
	# Nicely display the image at the center top and push the text below.
	a.gsphoto = photo # This is soooo important.
	photoWidth = photo.width()
	bodyWidth = body.bodyCtrl.winfo_width()
	padding = int((bodyWidth - photoWidth - 16) / 2)
	padding = max(0,padding)
	a.gsimage = body.bodyCtrl.image_create("1.0",image=photo,padx=padding)
else:
	es("warning: missing image file")</t>
<t tx="edream.110203113231.861">def onUnselect (tag,keywords):

	a = app()
	c = keywords.get("c")
	old_v = keywords.get("old_v")

	if old_v:
		h = old_v.headString()
		if h[:7] == "@image ":
			&lt;&lt; Unselect Image &gt;&gt;
	else: # Leo is initializing.
		a.gsphoto = None # Holds our photo file
		a.gsimage = None # Holds our image instance within the text pane</t>
<t tx="edream.110203113231.862"># Erase image if it was previously displayed
if a.gsimage:
	try:
		 c.frame.body.bodyCtrl.delete(a.gsimage)
	except:
		es("info: no image to erase")

# And forget about it
a.gsimage = None
a.gsphoto = None
</t>
<t tx="edream.110203113231.863">@nocolor</t>
<t tx="edream.110203113231.864">Reorganized the code so I can find various classes more easily.
Used @others to simply the outline.

Sorted all entries in dialogs.
Sorted all entries in Plugins menu, regardless of whether they are configurable.

For all dialogs:
	Added top ivar and removed root/master params and ivars.
	Added Leo icon and title.
	Centered dialogs.

Ctors now run all dialogs as modal dialogs: this could easily be undone.

Used a grid in the properties dialog to align widgets.</t>
<t tx="edream.110203113231.865">- We will use a new settings file called leoSettings.txt:
- Each setting will have its _own section_ in leoSettings.txt with the following items (most optional)
	val = present value of settings: Use parent setting if this does not exist.
	help = help string (displayed near setting if it exists)
	prompt = prompt string (defaults to setting name, i.e., the section name)
	group = name of group dialog containing this item (use general section if this does not exist)
	type = one of the following:
		value			meaning
		bool			followed by true/false prompts for radio buttons
		color			color picker
		font			font picker
		parent			name of parent config file (set/get setting in that file)
		entry			followed by arbitrary text in an entry widget
		text			followed by arbitrary text in a text widget
		number			any number, or followed by a range of valid values for an entry widget.
		numberlist  followed by a list valid values for a listbox.
		list			followed by a list of valid strings in a listbox.
Notes:
- We could use yaml or ConfigParser or Pickle.  yaml might be best.
- The options dialog will have a separate frame for each group or subgroup.
- We will want a Create Options file command (useful for converting old leoConfig.txt files)
- All options may have a use parent settings (for all widgets?)
- The separate "Groups" section may indicate which groups are subgroups of other groups for multi-level displays.</t>
<t tx="edream.110203113231.866">I wrote myself a plug-in which would automatically save the Leo file every so often and in doing so realized that it would be useful to be able to configure the interval between saves. Anyway, to cut a long story short, I generalized the idea and came up with the attached patch. 
 
All code resides under the "Plug in changes" node. The additions are all under the "create the plug-in menu" node with another couple of lines in "createMenuBar". Structurally this is ugly - but it helps keep all the changes in one place!
 
The basic idea is to allow plug-ins to be configured and also allow them to expose additional functions which can be accessed by a menu item. The advantage is that people don't have to mess with adding menus to Leo. Existing plug-ins don't need to be changed in any way to work with the new patch.
 
Ok, here's what it does....
 
1. A new "Plug-ins" menu item is added
 
2. Each plug-in gets an "About x...." entry.
 
    - clicking on "About x..." brings up an about box which shows name, version and documentation for the plug in
    - name comes from the module name
    - version is the module __version__ if present
    - documentation is the module docstring 
 
3. If the plug-in is configurable then a sub menu is created
 
    - configurable means that a corresponding ".ini" file is found with the same names as the plug-in (ie mod_image.py has mod_image.ini)
    - the sub menu contains
        - the "About x..." as before
        - a "Properties..." menu entry to edit the properties (*)
 
4. A further search is made for plug-in specific commands
 
    - we look for functions called "cmd_*" in the module
    - if found we add them to the plug-in menu
    - when you click on the menu item the function is called with a single parameter
 
(*) How does the property window work,
 
5. The property window reads the ini file which is assumed to be in standard ini file format (ie sections and parameters)
    - each section gets a frame in the window
    - each property gets an entry box
 
6. From the property window the user can "Cancel" or "OK", which saves changes
 
7. If the module contains an "applyConfiguration" function then there is also an "Apply" button on the form. The apply configuration function is called with the current configuration when the "Apply" button is pressed.
</t>
<t tx="edream.110203113231.867">"""Create a Scripts menu for LeoPy.leo"""

from leoPlugins import *
from leoGlobals import *
import glob,os

@others

# EKR:  I don't like the scripts menu now.
# The new Execute Script command seems much safer and more convenient.

# Register the handlers...
registerHandler("create-optional-menus",createScriptsMenu)

__version__ = "1.4"
plugin_signon(__name__)</t>
<t tx="edream.110203113231.868">def createScriptsMenu (tag,keywords):

	c = keywords.get("c")
	path = os.path.join(app().loadDir,"..","scripts")
	
	if os.path.exists(path):

		# Create lists of scripts and subdirectories.
		entries = glob.glob(os.path.join(path,"*"))
		top_scripts = glob.glob(os.path.join(path,"*.py"))
		dirs = [f for f in entries if os.path.isdir(f)]
		&lt;&lt; Return if no scripts exist anywhere &gt;&gt;
	
		scriptsMenu = c.frame.menu.createNewMenu("&amp;Scripts")
		table = []
		&lt;&lt; Create top-level entries for every script in top_scripts &gt;&gt;
		for dir in dirs:
			files = glob.glob(os.path.join(dir,"*.py"))
			if files:
				&lt;&lt; Create a submenu for dir containing each file in files &gt;&gt;</t>
<t tx="edream.110203113231.869">if not top_scripts:
	found = false
	for dir in dirs:
		scripts = glob.glob(os.path.join(dir,"*.py"))
		if scripts:
			found = true ; break
	if not found:
		return
</t>
<t tx="edream.110203113231.870">table = []
top_scripts.sort()
for script in top_scripts:
	name = shortFileName(script)
	def doScript(event=None,name=name):
		executeScript(name)
	table.append((name,None,doScript),)
	
c.frame.menu.createMenuEntries(scriptsMenu, table)
</t>
<t tx="edream.110203113231.871"># Create the submenu.
name = os.path.join("scripts",shortFileName(dir))
menu = c.frame.menu.createNewMenu(name,"&amp;Scripts")

# Populate the submenu.
table = []
for file in files:
	name = shortFileName(file)
	def doScript(event=None,name=name):
		from leoGlobals import executeScript
		executeScript(name)
	table.append((name,None,doScript),)

c.frame.menu.createMenuEntries(menu, table)</t>
<t tx="edream.110203113231.872"></t>
<t tx="edream.110203113231.873">"""Synchronize @folder nodes with folders"""

from leoPlugins import *
from leoGlobals import *

&lt;&lt; about this plugin &gt;&gt;
@others

def onSelect (tag,keywords):
	v = keywords.get("new_v")
	h = v.headString()
	if match_word(h,0,"@folder"):
		sync_node_to_folder(v,h[8:])

# Register the handlers...
registerHandler("select1", onSelect)

__version__ = "1.2" # Set version for the plugin handler.
plugin_signon(__name__)</t>
<t tx="edream.110203113231.874">@ If a node is named '@folder path_to_folder', the content (filenames) of the
folder and the children of that node will be sync. Whenever a new file is put
there, a new node will appear on top of the children list (with mark). So that
I can put my description (ie. annotation) as the content of that node. In this
way, I can find any files much easier from leo.

Moreover, I add another feature to allow you to group files(in leo) into
children of another group. This will help when there are many files in that
folder. You can logically group it in leo (or even clone it to many groups),
while keep every files in a flat/single directory on your computer.
</t>
<t tx="edream.110203113231.875">def sync_node_to_folder(parent,d):

	oldlist = {}
	newlist = []
	#get children info
	v = parent
	after_v = parent.nodeAfterTree()
	while v != after_v:
		if not v.hasChildren():
			oldlist[v.headString()] = v.bodyString()
		v = v.threadNext()
	#compare folder content to children
	for name in os.listdir(d):
		if name in oldlist:
			del oldlist[name]
		else:
			newlist.append(name)
	#insert newlist
	newlist.sort()
	newlist.reverse()
	for name in newlist:
		v = parent.insertAsNthChild(0)
		v.setHeadStringOrHeadline(name)
		v.setMarked()
	#warn for orphan oldlist
	if len(oldlist)&gt;0:
		es('missing: '+','.join(oldlist.keys()))
</t>
<t tx="edream.110203113231.876">"""Inhibit changes to @read-only nodes"""

# Contributed by Davide Salomoni &lt;dsalomoni@yahoo.com&gt;

from leoPlugins import *
from leoGlobals import *

import ftplib, urllib, urlparse, os, cStringIO
from formatter import AbstractFormatter, DumbWriter
from htmllib import HTMLParser

try:
	import tkFileDialog
except ImportError:
	tkFileDialog = None

if tkFileDialog: # Register the handlers...

	@others

	if app.gui is None:
		app().createTkGui(__file__)

	if app.gui.guiName() == "tkinter":

		registerHandler(("start2","open2"), on_open2)
		registerHandler("bodykey1", on_bodykey1)
		registerHandler("headkey2", on_headkey2)
		if 0: # doesn't work: the cursor stops blinking.
			registerHandler("select1", on_select1)
			registerHandler("select2", on_select2)
	
		__version__ = "1.5" # Set version for the plugin handler.
		plugin_signon(__name__)

</t>
<t tx="edream.110203113231.877">@ Dear Leo users,

Here's my first attempt at customizing leo. I wanted to have the ability to
import files in "read-only" mode, that is, in a mode where files could only
be read by leo (not tangled), and also kept in sync with the content on the
drive.

The reason for this is for example that I have external programs that generate
resource files. I want these files to be part of a leo outline, but I don't
want leo to tangle or in any way modify them. At the same time, I want them
to be up-to-date in the leo outline.

So I coded the directive plugin. It has the following characteristics:

- It reads the specified file and puts it into the node content.

- If the @read-only directive was in the leo outline already, and the file content
on disk has changed from what is stored in the outline, it marks the node as
changed and prints a "changed" message to the log window; if, on the other hand,
the file content has _not_ changed, the file is simply read and the node is
not marked as changed.

- When you write a @read-only directive, the file content is added to the node
immediately, i.e. as soon as you press Enter (no need to call a menu
entry to import the content).

- If you want to refresh/update the content of the file, just edit the headline
and press Enter. The file is reloaded, and if in the meantime it has changed,
a "change" message is sent to the log window.

- The body text of a @read-only file cannot be modified in leo.

Davide Salomoni
</t>
<t tx="edream.110203113231.878">@ The syntax to access files in @read-only via ftp/http is the following:

@read-only http://www.ietf.org/rfc/rfc0791.txt
@read-only ftp://ftp.someserver.org/filepath

If FTP authentication (username/password) is required, it can be specified as follows:

@read-only ftp://username:password@ftp.someserver.org/filepath

For more details, see the doc string for the class FTPurl.
</t>
<t tx="edream.110203113231.879">class FTPurl:
	"""An FTP wrapper class to store/retrieve files using an FTP URL.

    To create a connection, call the class with the constructor:

        FTPurl(url[, mode])

    The url should have the following syntax:
    
        ftp://[username:password@]remotehost/filename
    
    If username and password are left out, the connection is made using
    username=anonymous and password=realuser@host (for more information,
    see the documentation of module ftplib).
    
    The mode can be '' (default, for ASCII mode) or 'b' (for binary mode).
	This class raises an IOError exception if something goes wrong.
	"""
	
	@others
</t>
<t tx="edream.110203113231.880">def __init__(self, ftpURL, mode=''):
	parse = urlparse.urlparse(ftpURL)
	if parse[0] != 'ftp':
		raise IOError, "error reading %s: malformed ftp URL" % ftpURL

	# ftp URL; syntax: ftp://[username:password@]hostname/filename
	self.mode = mode
	authIndex = parse[1].find('@')
	if authIndex == -1:
		auth = None
		ftphost = parse[1]
	else:
		auth = parse[1][:authIndex]
		ftphost = parse[1][authIndex+1:]
	self.ftp = ftplib.FTP(ftphost)
	if auth == None:
		self.ftp.login()
	else:
		# the URL has username/password
		pwdIndex = auth.find(':')
		if pwdIndex == -1:
			raise IOError, "error reading %s: malformed ftp URL" % ftpURL
		user = auth[:pwdIndex]
		password = auth[pwdIndex+1:]
		self.ftp.login(user, password)
	self.path = parse[2][1:]
	self.filename = os.path.basename(self.path)
	self.dirname = os.path.dirname(self.path)
	self.isConnectionOpen = 1
	self.currentLine = 0
</t>
<t tx="edream.110203113231.881"></t>
<t tx="edream.110203113231.882">def read(self):
	"""Read the filename specified in the constructor and return it as a string.
    If the constructor specifies no filename, or if the URL ends with '/',
    return the list of files in the URL directory.
	"""
	self.checkParams()
	if self.filename=='' or self.path[-1]=='/':
		return self.dir()

	try:
		if self.mode == '':  # mode='': ASCII mode
			slist = []
			self.ftp.retrlines('RETR %s' % self.path, slist.append)
			s = '\n'.join(slist)
		else: # mode='b': binary mode
			file = cStringIO.StringIO()
			self.ftp.retrbinary('RETR %s' % self.path, file.write)
			s = file.getvalue()
			file.close()
		return s
	except:
		exception, msg, tb = sys.exc_info()
		raise IOError, msg

</t>
<t tx="edream.110203113231.883">def readline(self):
	"""Read one entire line from the remote file."""
	try:
		self.lst
	except AttributeError:
		self.lst = self.read().splitlines(1)
	
	if self.currentLine &lt; len(self.lst):
		s = self.lst[self.currentLine]
		self.currentLine = self.currentLine + 1
		return s
	else:
		return ''
</t>
<t tx="edream.110203113231.884"></t>
<t tx="edream.110203113231.885">def write(self, s):
	"""write(s) stores the string s to the filename specified in the
    constructor."""
	self.checkParams()
	if self.filename == '':
		raise IOError, 'filename not specified'
	
	try:
		file = cStringIO.StringIO(s)
		if self.mode == '':  # mode='': ASCII mode
			self.ftp.storlines('STOR %s' % self.path, file)
		else: # mode='b': binary mode
			self.ftp.storbinary('STOR %s' % self.path, file)
		file.close()
	except:
		exception, msg, tb = sys.exc_info()
		raise IOError, msg
</t>
<t tx="edream.110203113231.886"></t>
<t tx="edream.110203113231.887">def seek(offset=0):
	self.currentLine = 0  # we don't support fancy seeking via FTP
</t>
<t tx="edream.110203113231.888">def flush():
	pass # no fancy stuff here.</t>
<t tx="edream.110203113231.889">def dir(self, path=None):
	"""Issue a LIST command passing the specified argument and return output as a string."""
	s = []

	if path == None:
		path = self.dirname
	try:
		listcmd = 'LIST %s' % path
		self.ftp.retrlines(listcmd.rstrip(), s.append)
		return '\n'.join(s)
	except:
		exception, msg, tb = sys.exc_info()
		raise IOError, msg
</t>
<t tx="edream.110203113231.890">def exists(self, path=None):
	"""Return 1 if the specified path exists. If path is omitted, the current file name is tried."""
	if path == None:
		path = self.filename

	s = self.dir(path)
	if s.lower().find('no such file') == -1:
		return 1
	else:
		return 0
</t>
<t tx="edream.110203113231.891">def checkParams(self):
	if self.mode not in ('','b'):
		raise IOError, 'invalid mode: %s' % self.mode
	if not self.isConnectionOpen:
		raise IOError, 'ftp connection closed'
</t>
<t tx="edream.110203113231.892">def close(self):
	"""Close an existing FTPurl connection."""
	try:
		self.ftp.quit()
	except:
		self.ftp.close()
	del self.ftp
	self.isConnectionOpen = 0</t>
<t tx="edream.110203113231.893"># Alas, these do not seem to work on XP:
# disabling the body text _permanently_ stops the cursor from blinking.

def enable_body(body):
	global insertOnTime,insertOffTime
	if body.cget("state") == "disabled":
		try:
			es("enable")
			print insertOffTime,insertOnTime
			body.configure(state="normal")
			body.configure(insertontime=insertOnTime,insertofftime=insertOffTime)
		except: es_exception()
			
def disable_body(body):
	global insertOnTime,insertOffTime
	if body.cget("state") == "normal":
		try:
			es("disable")
			insertOnTime = body.cget("insertontime")
			insertOffTime = body.cget("insertofftime")
			print insertOffTime,insertOnTime
			body.configure(state="disabled")
		except: es_exception()
</t>
<t tx="edream.110203113231.894"># Sets v's body text from the file with the given name.
# Returns true if the body text changed.
def insert_read_only_node (c,v,name):
	if name=="":
		name = tkFileDialog.askopenfilename(
			title="Open",
			filetypes=[("All files", "*")]
			)
		c.beginUpdate()
		v.setHeadString("@read-only %s" % name)
		c.endUpdate()
	parse = urlparse.urlparse(name)
	try:
		if parse[0] == 'ftp':
			file = FTPurl(name)  # FTP URL
		elif parse[0] == 'http':
			file = urllib.urlopen(name)  # HTTP URL
		else:
			file = open(name,"r")  # local file
		# es("..." + name)
		new = file.read()
		file.close()
	except IOError,msg:
		# es("error reading %s: %s" % (name, msg))
		# es("...not found: " + name)
		v.setBodyStringOrPane("") # Clear the body text.
		return true # Mark the node as changed.
	else:
		ext = os.path.splitext(parse[2])[1]
		if ext.lower() in ['.htm', '.html']:
			&lt;&lt; convert HTML to text &gt;&gt;
		previous = v.t.bodyString
		v.setBodyStringOrPane(new)
		changed = (toUnicode(new,'ascii') != toUnicode(previous,'ascii'))
		if changed and previous != "":
			es("changed: %s" % name) # A real change.
		return changed</t>
<t tx="edream.110203113231.895">fh = cStringIO.StringIO()
fmt = AbstractFormatter(DumbWriter(fh))
# the parser stores parsed data into fh (file-like handle)
parser = HTMLParser(fmt)

# send the HTML text to the parser
parser.feed(new)
parser.close()

# now replace the old string with the parsed text
new = fh.getvalue()
fh.close()

# finally, get the list of hyperlinks and append to the end of the text
hyperlinks = parser.anchorlist
numlinks = len(hyperlinks)
if numlinks &gt; 0:
	hyperlist = ['\n\n--Hyperlink list follows--']
	for i in xrange(numlinks):
		hyperlist.append("\n[%d]: %s" % (i+1,hyperlinks[i])) # 3/26/03: was i.
	new = new + ''.join(hyperlist)</t>
<t tx="edream.110203113231.896">#  scan the outline and process @read-only nodes.
def on_open2 (tag,keywords):
	
	
	if tag == "start2":
		c = top()
	else:
		c = keywords.get("new_c")

	v = c.rootVnode()
	es("scanning for @read-only nodes...",color="blue")
	c.beginUpdate()
	while v:
		h = v.headString()
		if match_word(h,0,"@read-only"):
			changed = insert_read_only_node(c,v,h[11:])
			es("changing %s" % v.headString(),color="red")
			if changed:
				if not v.isDirty():
					v.setDirty()
				if not c.isChanged():
					c.setChanged(changed)
		v = v.threadNext()
	c.endUpdate()
</t>
<t tx="edream.110203113231.897"># override the body key handler if we are in an @read-only node.

def on_bodykey1 (tag,keywords):

	c = keywords.get("c")
	v = keywords.get("v")
	h = v.headString()
	if match_word(h,0,"@read-only"):
		# The following code causes problems with scrolling and syntax coloring.
		# Its advantage is that it makes clear that the text can't be changed,
		# but perhaps that is obvious anyway...
		if 0: # Davide Salomoni requests that this code be eliminated.
			# An @read-only node: do not change its text.
			body = c.frame.body.bodyCtrl
			body.delete("1.0","end")
			body.insert("1.0",v.bodyString())
		return 1 # Override the body key event handler.</t>
<t tx="edream.110203113231.898"># update the body text when we press enter

def on_headkey2 (tag,keywords):

	c = keywords.get("c")
	v = keywords.get("v")
	h = v.headString()
	ch = keywords.get("ch")
	if ch == '\r' and match_word(h,0,"@read-only"):
		# on-the-fly update of @read-only directives
		changed = insert_read_only_node(c,v,h[11:])
		c.setChanged(changed)</t>
<t tx="edream.110203113231.899">def on_select1 (tag,keywords):

	# Doesn't work: the cursor doesn't start blinking.
	# Enable the body text so select will work properly.
	c = keywords.get("c")
	enable_body(c.frame.body)
</t>
<t tx="edream.110203113231.900">def on_select2 (tag,keywords):

	c = keywords.get("c")
	v = c.currentVnode()
	h = v.headString()
	if match_word(h,0,"@read-only"):
		disable_body(c.frame.body)
	else:
		enable_body(c.frame.body)
</t>
<t tx="edream.110203113231.910">"""Lauches (starts) a file with the name of the headline on double-clicking it.
Uses the @folder path if the headline is under an @folder headline.
Otherwise the path is relative to the Leo file.
Headlines starting with an '@' are ignored.
This does not work on Linux (yet)."""

# By Josef Dalcolmo: contributed under the same license as Leo.py itself.

from leoPlugins import *
from leoGlobals import *
import os

&lt;&lt; about this plugin &gt;&gt;
&lt;&lt; change log &gt;&gt;

@others

# Register the handlers...
registerHandler("icondclick1",onIconDoubleClick)

__version__ = "1.1"
plugin_signon(__name__)

def unitTest ():
	pass
</t>
<t tx="edream.110203113231.911">@ This plugin starts a file with the name of a headline.


</t>
<t tx="edream.110203113231.912">@ Change log

- JD: 2003-03-11 separated out from rst plugin



</t>
<t tx="edream.110203113231.913"># @folder behavior after an idea and sample code by:
# korakot ( Korakot Chaovavanich ) @folder for files annotation 2002-11-27 02:39
# 
# open file (double-click = startfile) behavior added 
# nodes with @url, @folder, @rst are treated special
#
# by Josef Dalcolmo 2003-01-13
#
# this does not check for proper filename syntax.
# path is the current dir, or the place @folder points to
# this should probably be changed to @path or so.

def onIconDoubleClick(tag,keywords):

	v = keywords.get("v")
	c = keywords.get("c")
	h = v.headString().strip()
	if len(h)==0 or h[0]=='@':
		return # Let other plugins handle these
	else:
		# open file with associated application
		&lt;&lt; find path and start file &gt;&gt;</t>
<t tx="edream.110203113231.914"># Set the base directory by searching for @folder directives in ancestors.
try:
	basedir = os.curdir	# use current dir as default.
	parv = v.parent()	# start with parent
	while parv:	# stop when no more parent found
		p = parv.headString().strip()
		if match_word(p,0,'@folder'):
			basedir = p[8:]	# take rest of headline as pathname
			break	# we found the closest @folder
		else:
			parv = parv.parent()	# try the parent of the parent
	fname = os.path.join(basedir,h) # join path and filename
	os.startfile(fname)	# Try to open the file; it may not work for all file types.
except:
	es(os.path.join(os.getcwd(),fname)+' - file or application not found')
	es_exception()
</t>
<t tx="edream.110203113231.915"></t>
<t tx="edream.110203113231.916">from leoPlugins import *
from leoGlobals import *

@others

# Override classes &amp; methods...

if 0:
	&lt;&lt; override the LeoFrame class &gt;&gt;

if 0:
	&lt;&lt; override methods of the LeoApp class &gt;&gt;

__version__ = "1.2"
plugin_signon(__name__)</t>
<t tx="edream.110203113231.917"># print "overriding LeoFrame class"

import leoFrame

assert(leoFrame.leoCoreFrame.instances==0)

class myLeoFrame(leoFrame.leoCoreFrame):
	
	pass
	
	if 0:
		def __init__(self,title=None):
			print "myLeoFrame ctor",title
			leoFrame.leoCoreFrame.__init__(self,title)

leoFrame.LeoFrame = myLeoFrame</t>
<t tx="edream.110203113231.918">import leoApp

# print "overriding app.closeLeoWindow"

oldAppCloseLeoWindow = app().closeLeoWindow

def myAppCloseLeoWindow(self,frame):
	
	global oldAppCloseLeoWindow

	oldAppCloseLeoWindow(frame)
	print "after closeLeoWindow"

funcToMethod(myAppCloseLeoWindow,leoApp.LeoApp,"closeLeoWindow")</t>
<t tx="edream.110203113231.919">"""Override the Equal Sized Pane command"""

from leoPlugins import *
from leoGlobals import *

@others

# Register the handlers...
registerHandler("command1", onCommand)

__version__ = "1.2"
plugin_signon(__name__)</t>
<t tx="edream.110203113231.920">def onCommand (tag,keywords):

	if keywords.get("label")=="equalsizedpanes":
		es("over-riding Equal Sized Panes")
		return "override" # Anything other than None overrides.</t>
<t tx="edream.110203113231.921">"""Redefine the "put" and "put_nl" methods"""

from leoPlugins import *
from leoGlobals import *

try:
	import Tkinter
except ImportError:
	Tkinter = None

if Tkinter: # Register the handlers...

	@others

	# Register the handlers...
	registerHandler("start2", onStart)
	
	__version__ = "1.2"
	plugin_signon(__name__)</t>
<t tx="edream.110203113231.922">@ This code illustrates how to redefine _any_ method of Leo.
Python makes this is almost too easy :-)
@c

def onStart (tag,keywords):

	import leoTkinterFrame
	log = leoTkinterFrame.leoTkinterLog
	
	# Replace frame.put with newPut.
	funcToMethod(newPut,log,"put")
	
	# Replace frame.putnl with newPutNl.
	funcToMethod(newPutNl,log,"putnl")</t>
<t tx="edream.110203113231.923"># Contrived examples of how to redefine frame.put and frame.putnl

# Same as frame.put except converts everything to upper case.
def newPut (self,s,color="black"):
	print "newPut",s,
	if app().quitting &gt; 0: return
	s = s.upper()
	t = self.logCtrl
	if t:
			t.insert("end",s)
			t.see("end")
			t.update_idletasks()
	else: print s,

# Same as frame.putnl except writes two newlines.
def newPutNl (self):
	print "newPutNl"
	if app().quitting &gt; 0: return
	t = self.logCtrl
	if t:
		t.insert("end","\n\n")
		t.see("end")
		t.update_idletasks()
	else: print</t>
<t tx="edream.110203113231.924">"""Send all output to the log pane"""

from leoPlugins import *
from leoGlobals import *

def onStart (tag,keywords):
	from leoGlobals import redirectStdout,redirectStderr
	redirectStdout() # Redirect stdout
	redirectStderr() # Redirect stderr

# Register the handlers...
registerHandler("start2", onStart)

__version__ = "1.3"
plugin_signon(__name__)</t>
<t tx="edream.110203113231.925">"""Send output from the Execute Script command to the end of the body pane"""

from leoPlugins import *
from leoGlobals import *

try:
	import Tkinter
except ImportError:
	Tkinter = None

if Tkinter: # Register the handlers...

	@others

	if app.gui is None:
		app.createTkGui(__file__)

	if app.gui.guiName() == "tkinter":

		registerHandler("start1", onStart)
	
		__version__ = "1.3" # Contains Tk-specific code.
		plugin_signon(__name__)</t>
<t tx="edream.110203113231.926">def onStart (tag,keywords):
	
	# Replace frame.put with newPut.
	import leoTkinterFrame
	funcToMethod(newExecuteScript,leoTkinterFrame.leoTkinterFrame,"OnExecuteScript")
</t>
<t tx="edream.110203113231.927"># Execute the selected body text as a Python script and sends the output to the end of the body pane.

def newExecuteScript(self,event=None,v=None):
	
	c = self.c ; body = self.body ; s = None
	if v == None:
		v = c.currentVnode() 

	# Assume any selected body text is a script.
	start,end = body.getTextSelection() # EKR: 11/04/03
	if start and end and start != end: # 7/7/03
		s = body.bodyCtrl.get(start,end)
	else:
		s = body.bodyCtrl.get("1.0","end")
	s = s.strip()
	if s and len(s) &gt; 0:
		s += '\n' # Make sure we end the script properly.
		# Switch output.
		import leoTkinterFrame,leoGlobals
		oldput = leoTkinterFrame.leoTkinterLog.put # 11/7/03
		oldputnl = leoTkinterFrame.leoTkinterLog.putnl # 11/7/03
		oldes = leoGlobals.es
		oldenl = leoGlobals.enl
		oldecnl = leoGlobals.ecnl
		oldecnls = leoGlobals.ecnls
		leoGlobals.es = newEs
		leoGlobals.enl = newEnl
		leoGlobals.ecnl = newEcnl
		leoGlobals.ecnls = newEcnls
		funcToMethod(newPut,leoTkinterFrame.leoTkinterLog,"put") #  11/7/03
		funcToMethod(newPutNl,leoTkinterFrame.leoTkinterLog,"putNl") # 11/7/03
		redirectStderr()
		redirectStdout()
		try:
			exec s in {} # Use {} to get a pristine environment!
			ok = true
		except:
			ok = false
		# Restore output.
		funcToMethod(oldput,leoTkinterFrame.leoTkinterLog,"put") # 11/7/03
		funcToMethod(oldputnl,leoTkinterFrame.leoTkinterLog,"putNl") # 11/7/03
		leoGlobals.es = oldes
		leoGlobals.enl = oldenl
		leoGlobals.ecnl = oldecnl
		leoGlobals.ecnls = oldecnls
		restoreStderr()
		restoreStdout()
		if not ok:
			es("newExecuteScript: exception executing script")
			es_exception(full=false)
	else:
		es("newExecuteScript: empty script")</t>
<t tx="edream.110203113231.928"># Same as frame.put except sends output to the end of the body text.
def newPut (self,s):
	c = self.frame.c
	bodyCtrl = self.frame.body.bodyCtrl
	if bodyCtrl:
		bodyCtrl.insert("end",s)
		# bodyCtrl.see("end")
		v = c.currentVnode()
		self.frame.tree.onBodyChanged(v,"Typing")
	else: print s,

# Same as frame.putnl exceptsends output to the end of the body text.
def newPutNl (self):
	newPut (self,'\n')</t>
<t tx="edream.110203113231.929">def newEnl():
	print
	
def newEcnl():
	print
	
def newEcnls(n):
	while n &gt; 0:
		n -= 1
		print

def newEs(s,*args,**keys):
	newline = keys.get("newline",true)
	if type(s) != type("") and type(s) != type(u""):
		s = repr(s)
	for arg in args:
		if type(arg) != type("") and type(arg) != type(u""):
			arg = repr(arg)
		s = s + ", " + arg
	if newline:
		print s
	else:
		print s,
</t>
<t tx="edream.110203113231.930"></t>
<t tx="edream.110203113231.931">colour
colourful
coloured
</t>
<t tx="edream.110203113231.932"># Configuration file for mod_spelling plugin.

[main]

aspell_dir=c:\aspell\bin\aspell.exe

local_leo_dictionary=c:\prog\leoCVS\leo\plugins\mod_spelling.txt

local_language_code=en</t>
<t tx="edream.110203113231.933">"""Spell Checker Plugin

- Perfoms spell checking on nodes within a Leo document.
- Uses aspell.exe to do the checking and suggest alternatives."""

from leoPlugins import *
from leoGlobals import *
import leoTkinterFind

try:
	import Tkinter
except ImportError:
	Tkinter = None
Tk = Tkinter

import ConfigParser,os,popen2,re,sys,traceback

if Tkinter: # Register the handlers...

	@others

	if app.gui is None:
		app.createTkGui(__file__)

	if app.gui.guiName() == "tkinter":

		spellFrame = spellDialog()
		spellFrame.top.withdraw()
		app().globalWindows.append(spellFrame)
		
		registerHandler("create-optional-menus",createSpellMenu)
		registerHandler("select2",onSelect)
		registerHandler("command2",onCommand) # For any command that might change the text.
		registerHandler("bodykey2",onSelect) # For updating buttons.
		registerHandler(("bodyclick2","bodydclick2","bodyrclick2"),onSelect) # These affect selection.
		
		__version__ = "0.4.0" # EKR: 11/12/03: modified to use new leoTkinterFind class.
		plugin_signon(__name__)</t>
<t tx="edream.110203113231.934"></t>
<t tx="edream.110203113231.935">def createSpellMenu(tag,keywords):
	
	"""Create the Check Spelling menu item in the Edit menu."""
	
	c = keywords.get("c")

	table = (
		("-",None,None),
		("Check Spelling","Alt+Shift+A",spellFrame.checkSpelling))

	c.frame.menu.createMenuItemsFromTable("Edit",table)</t>
<t tx="edream.110203113231.936">def onSelect (tag,keywords):
	
	"""A new vnode has just been selected.  Update the Spell Check window."""

	c = keywords.get("c")
	v = keywords.get("new_v")
	global spellFrame
	
	if top() and c and c.currentVnode():
		if c.currentVnode() != spellFrame.v:
			# print "onSelect",tag,`c.currentVnode()`,`spellFrame.v`
			spellFrame.update(show=false,fill=true)
		else:
			spellFrame.updateButtons()</t>
<t tx="edream.110203113231.937">def onCommand (tag,keywords):
	
	"""Update the Spell Check window after any command that might change text."""

	global spellFrame
	
	if top() and top().currentVnode():
		
		# print "onCommand",tag
		spellFrame.update(show=false,fill=false)</t>
<t tx="edream.110203113231.938">class Aspell:
	
	"""A wrapper class for Aspell spell checker"""
	
	@others
</t>
<t tx="edream.110203113231.939"></t>
<t tx="edream.110203113231.940">def __init__(self,local_dictionary_file,local_language_code):
	
	"""Ctor for the Aspell class."""
	
	self.altre = re.compile(".\s(.+)\s(\d+)\s(\d+):(.*)")
	self.attached = None
	self.input,self.output = None,None
	self.signonGiven = false
	
	self.aspell_exe_loc = self.getAspellDirectory()
	self.local_language_code = local_language_code
	
	if local_dictionary_file:
		self.local_dictionary_file = local_dictionary_file
		self.local_dictionary = "%s.wl" % os.path.splitext(local_dictionary_file)[0]
	else:
		print "failed to set aspell.local_dictionary"
		self.local.dictionary_file = None
		self.local_dictionary = None</t>
<t tx="edream.110203113231.941">def getAspellDirectory(self):
	
	"""Get the directory containing aspell.exe from mod_spelling.ini"""

	try:
		fileName = os.path.join(app().loadDir,"../","plugins","mod_spelling.ini")
		config = ConfigParser.ConfigParser()
		config.read(fileName)
		return config.get("main","aspell_dir")
	except:
		es_exception()
		return None</t>
<t tx="edream.110203113231.942">def openPipes (self):
	
	"""Open the pipes to aspell.exe"""
	
	if self.input or self.output:
		print "pipes already open!"
		self.closePipes()
	
	&lt;&lt; Ensure local dictionary is present &gt;&gt;
	cmd = "%s pipe %s" % (self.aspell_exe_loc, add_dicts)
	if not self.local_dictionary:
		print "openPipes: command = " + cmd
	
	try:
		self.input, self.output = popen2.popen2(cmd)
	except:
		print "exception opening pipe"
		self.input = self.output = None
	
	if self.input:
		self.attached = self.input.readline()
	else:
		self.attached = None
		
	if not self.signonGiven:
		self.signonGiven = true
		if self.attached:
			print self.attached
			es(self.attached,color="blue")
		else:
			print "can not open aspell"
			es("can not open aspell",color="red")</t>
<t tx="edream.110203113231.943">add_dicts = ""

if self.local_dictionary:
	if self.updateDictionary():
		add_dicts = "--add-extra-dicts %s" % self.local_dictionary


</t>
<t tx="edream.110203113231.944">def closePipes (self):
	
	"""Close the pipes to aspell.exe"""
	
	# if self.input or self.output: print "closePipes"
	
	if self.input:
		self.input.close()
		self.input = None

	if self.output:
		self.output.close()
		self.output = None</t>
<t tx="edream.110203113231.945">def listAlternates(self, aspell_return):
	
	"""Return a list of alternates from aspell."""
	
	match = self.altre.match(aspell_return)

	if match:
		return [item.strip() for item in match.groups()[3].split(",")]
	else:
		return []</t>
<t tx="edream.110203113231.946">def processWord(self, word):

	"""Pass a word to aspell and return the list of alternatives."""
	
	if not self.attached:
		return None

	# print "processWord",`word`,`self.output`
	
	self.output.write("%s\n" % word)
	
	ret,junk = self.input.readline(),self.input.readline()

	if ret == "*\n":
		return None
	else:
		return self.listAlternates(ret)</t>
<t tx="edream.110203113231.947">def updateDictionary(self):
	
	"""Update the aspell dictionary from a list of words.
	
	Return true if the dictionary was update correctly."""

	try:
		# Create master list
		basename = os.path.splitext(self.local_dictionary)[0]
		cmd = (
			"%s --lang=%s create master %s.wl &lt; %s.txt" %
			(self.aspell_exe_loc,self.local_language_code,basename,basename))
		os.popen(cmd)
		return true

	except Exception, err:
		es("Unable to update local aspell dictionary: %s" % err)
		print err
		add_dicts = ""
		return false</t>
<t tx="edream.110203113231.948">class spellDialog (leoTkinterFind.leoTkinterFind):
	
	"""A class to create and manage Leo's Spell Check dialog."""
	
	@others</t>
<t tx="edream.110203113231.949"></t>
<t tx="edream.110203113231.950">def __init__ (self):
	
	"""Ctor for the Leo Spelling dialog."""
	
	# Call the base ctor to create the dialog.
	leoTkinterFind.leoTkinterFind.__init__(self,"Leo Spell Checking",resizeable=false)

	self.local_dictionary_file = self.getLocalDictionary()
	self.local_language_code = self.getLocalLanguageCode("en")
	self.aspell = Aspell(self.local_dictionary_file,self.local_language_code)
	&lt;&lt; set self.dictionary &gt;&gt;
	
	self.fillbox([])
	
	# State variables.
	self.currentWord = None
	self.suggestions = []
	self.c = None
	self.v = None
	self.body = None
	self.workCtrl = Tk.Text(None) # A text widget for scanning.

	self.listBox.bind("&lt;Double-Button-1&gt;",self.onChangeThenFindButton)
	self.listBox.bind("&lt;Button-1&gt;",self.onSelectListBox)
	self.listBox.bind("&lt;Map&gt;",self.onMap)</t>
<t tx="edream.110203113231.951">if self.local_dictionary_file:

	self.dictionary = self.readLocalDictionary(self.local_dictionary_file)
	if self.dictionary:
		# print "Local dictionary:", self.local_dictionary_file
		es("Local dictionary: %s" % shortFileName(self.local_dictionary_file),color="blue")
		if 0:
			keys = self.dictionary.keys()
			keys.sort()
			print "local dict:", keys
	else:
		self.dictionary = {}
		self.local_dictionary_file = None
else:
	self.dictionary = {}</t>
<t tx="edream.110203113231.952">def getLocalDictionary(self):
	
	"""Get the dictionaries containing words not in the standard dictionary from mod_spelling.ini"""

	try:
		fileName = os.path.join(app().loadDir,"../","plugins","mod_spelling.ini")
		config = ConfigParser.ConfigParser()
		config.read(fileName)
		return config.get("main","local_leo_dictionary",None)
	except:
		es_exception()
		return None</t>
<t tx="edream.110203113231.953">def getLocalLanguageCode(self,defaultLanguageCode):
	
	"""Get the dictionaries containing words not in the standard dictionary from mod_spelling.ini"""

	try:
		fileName = os.path.join(app().loadDir,"../","plugins","mod_spelling.ini")
		config = ConfigParser.ConfigParser()
		config.read(fileName)
		return config.get("main","local_language_code",defaultLanguageCode)
	except:
		es_exception()
		return defaultLanguageCode</t>
<t tx="edream.110203113231.954">def readLocalDictionary (self,local_dictionary):
	
	"""Read the dictionary of words which we use as a local dictionary
	
	Although Aspell itself has the functionality to handle this kind of things
	we duplicate it here so that we can also use it for the "ignore" functionality
	and so that in future a Python only solution could be developed."""

	try:
		f = open(local_dictionary,"r")
	except IOError:
		es("Unable to open local dictionary '%s' - using a blank one instead" % local_dictionary)
		return None
	
	try:
		# Create the dictionary - there are better ways to do this
		# in later Python's but we stick with this method for compatibility
		dct = {}
		for word in f.readlines():
			dct[word.strip().lower()] = 0
	finally:
		f.close()

	return dct</t>
<t tx="edream.110203113231.955">def createFrame (self):
	
	"""Create the Spelling dialog."""
	
	# Create the find panel...
	outer = Tk.Frame(self.frame,relief="groove",bd=2)
	outer.pack(padx=2,pady=2,expand=1,fill="both")

	&lt;&lt; Create the text and suggestion panes &gt;&gt;
	&lt;&lt; Create the spelling buttons &gt;&gt;
</t>
<t tx="edream.110203113231.956">f = outer

f2 = Tk.Frame(f)
f2.pack(expand=1,fill="x")
self.wordLabel = Tk.Label(f2, text="Suggestions for:")
self.wordLabel.pack(side="left")

fpane = Tk.Frame(f,bd=2)
fpane.pack(side="top", expand=1, fill="x")

self.listBox = Tk.Listbox(fpane,height=30,selectmode="single")
self.listBox.pack(side="left", expand=1, fill="both")

listBoxBar = Tk.Scrollbar(fpane,name='listBoxBar')

for bar,txt in ((listBoxBar,self.listBox),):
	txt['yscrollcommand'] = bar.set
	bar['command'] = txt.yview
	bar.pack(side="right", fill="y")
</t>
<t tx="edream.110203113231.957"># Create the button panes
buttons1  = Tk.Frame(outer,bd=1)
buttons1.pack (anchor="n",expand=1,fill="x")

buttons2  = Tk.Frame(outer,bd=1)
buttons2.pack (anchor="n",expand=1,fill="none")

buttonList = []
for text,command in (
	("Find",self.onFindButton),
	("Change",self.onChangeButton),
	("Change, Find",self.onChangeThenFindButton),
	("Add",self.onAddButton)):
	width = max(6,len(text))
	b=Tk.Button(buttons1,width=width,text=text,command=command)
	b.pack(side="left",fill="none",expand=1)
	buttonList.append(b)
		
for text,command in (
	("Undo",self.onUndoButton),
	("Redo",self.onRedoButton),
	("Ignore",self.onIgnoreButton),
	("Hide",self.onHideButton)):
	width = max(6,len(text))
	b=Tk.Button(buttons2,width=width,text=text,command=command)
	b.pack(side="left",fill="none",expand=0)
	buttonList.append(b)

# We need these to enable or disable buttons.
(self.findButton, self.changeButton,
 self.changeFindButton, self.addButton, 
 self.undoButton, self.redoButton,
 self.ignoreButton, self.hideButton) = buttonList</t>
<t tx="edream.110203113231.958"></t>
<t tx="edream.110203113231.959">def onAddButton (self):
	
	"""Handle a click in the Add button in the Check Spelling dialog."""

	self.add()
	self.closePipes()

</t>
<t tx="edream.110203113231.960">def onIgnoreButton (self):

	"""Handle a click in the Ignore button in the Check Spelling dialog."""

	self.ignore()
	self.closePipes()</t>
<t tx="edream.110203113231.961">def onChangeButton (self):
	
	"""Handle a click in the Change button in the Check Spelling dialog."""

	self.change()
	self.closePipes()
	self.updateButtons()
	
# Event needed for double-click event.
def onChangeThenFindButton (self,event=None): 
		
	"""Handle a click in the "Change, Find" button in the Check Spelling dialog."""

	if self.change():
		self.find()
	self.closePipes()
	self.updateButtons()</t>
<t tx="edream.110203113231.962">def onFindButton (self):
	
	"""Handle a click in the Find button in the Check Spelling dialog."""

	self.find()
	self.updateButtons()
	self.closePipes()</t>
<t tx="edream.110203113231.963">def onHideButton (self):
	
	"""Handle a click in the Hide button in the Check Spelling dialog."""

	self.closePipes()
	self.top.withdraw()
</t>
<t tx="edream.110203113231.964">def onRedoButton (self):
	
	"""Handle a click in the Redo button in the Check Spelling dialog."""

	self.c.undoer.redo() # Not a command, so command hook doesn't fire.
	self.update(show=false,fill=false)
	self.c.frame.body.bodyCtrl.focus_force()
	
def onUndoButton (self):
	
	"""Handle a click in the Undo button in the Check Spelling dialog."""

	self.c.undoer.undo() # Not a command, so command hook doesn't fire.
	self.update(show=false,fill=false)
	self.c.frame.body.bodyCtrl.focus_force()</t>
<t tx="edream.110203113231.965"></t>
<t tx="edream.110203113231.966">def add (self):

	"""Add the selected suggestion to the dictionary."""
	
	if not self.local_dictionary_file:
		return
	
	try:
		f = None
		try:
			# Rewrite the dictionary in alphabetical order.
			f = open(self.local_dictionary_file,"r")
			words = f.readlines()
			f.close()
			words = [word.strip() for word in words]
			words.append(self.currentWord)
			words.sort()
			f = open(self.local_dictionary_file,"w")
			for word in words:
				f.write("%s\n" % word)
			f.flush()
			f.close()
			es("Adding ",color="blue",newline=false) ; es('%s' % self.currentWord)
		except IOError:
			es("Can not add %s to dictionary" % self.currentWord,color="red")
	finally:
		if f: f.close()
		
	self.dictionary[self.currentWord.lower()] = 0
	
	# Restart aspell so that it re-reads its dictionary.
	self.aspell.closePipes()
	self.aspell.openPipes()
	
	self.onFindButton()</t>
<t tx="edream.110203113231.967">def change(self):
	
	"""Make the selected change to the text"""

	c = self.c ; v = self.v ; body = self.body ; t = body.bodyCtrl
	
	selection = self.getSuggestion()
	if selection:
		start,end = oldSel = app.gui.getTextSelection(t)
		if start:
			if t.compare(start, "&gt;", end):
				start,end = end,start
			t.delete(start,end)
			t.insert(start,selection)
			app.gui.setTextSelection(t,start,start + "+%dc" % (len(selection)))
			newSel = app.gui.getTextSelection(t)

			# update node, undo status, dirty flag, changed mark &amp; recolor
			c.beginUpdate()
			c.frame.body.onBodyChanged(v,"Change",oldSel=oldSel,newSel=newSel)
			c.endUpdate(true)
			t.focus_set()
			return true

	# The focus must never leave the body pane.
	t.focus_set()
	return false</t>
<t tx="edream.110203113231.968">def checkSpelling (self,event=None):
	
	"""Open the Check Spelling dialog."""

	self.top.deiconify()
	self.top.lift()
	self.update(show=true,fill=false)</t>
<t tx="edream.110203113231.969">def find(self):
	
	"""Find the next unknown word."""
	
	# Reload the work pane from the present node.
	s = self.body.bodyCtrl.get("1.0","end").rstrip()
	self.workCtrl.delete("1.0","end")
	self.workCtrl.insert("end",s)
	
	# Reset the insertion point of the work widget.
	ins = self.body.bodyCtrl.index("insert")
	self.workCtrl.mark_set("insert",ins)

	alts,word = self.findNextMisspelledWord()
	self.currentWord = word # Need to remember this for 'add' and 'ignore'
	
	if alts:
		self.fillbox(alts,word)
		self.body.bodyCtrl.focus_set()
					
		# Copy the working selection range to the body pane
		start,end = app.gui.getTextSelection(self.workCtrl)
		app.gui.setTextSelection(self.body.bodyCtrl,start,end)
	else:
		es("no more misspellings")
		self.fillbox([])</t>
<t tx="edream.110203113231.970">def ignore (self):
	
	"""Ignore the incorrect word for the duration of this spell check session."""
	
	es("Ignoring ",color="blue",newline=false) ; es('%s' % self.currentWord)
	self.dictionary[self.currentWord.lower()] = 0
	self.onFindButton()</t>
<t tx="edream.110203113231.971"></t>
<t tx="edream.110203113231.972">def closePipes(self):
	
	self.aspell.closePipes()</t>
<t tx="edream.110203113231.973">def fillbox(self,alts,word=None):

	"""Update the suggestions listbox in the Check Spelling dialog."""
	
	self.suggestions = alts
	
	if not word:
		word = ""

	self.wordLabel.configure(text = "Suggestions for: " + word)
	self.listBox.delete(0,"end")

	for i in xrange(len(self.suggestions)):
		self.listBox.insert(i,self.suggestions[i])
	
	if len(self.suggestions):
		self.listBox.select_set(1) # This doesn't show up because we don't have focus.</t>
<t tx="edream.110203113231.974">def findNextMisspelledWord(self):
	
	"""Find the next unknown word."""
	
	aspell = self.aspell ; alts = None ; word = None
	c = self.c ; v = self.v
	try:
		aspell.openPipes()
		try:
			while 1:
				v,word = self.findNextWord(v) 
				if not v or not word:
					alts = None
					break
				&lt;&lt; Skip word if ignored or in local dictionary &gt;&gt;
				alts = aspell.processWord(word)
				if alts:
					self.v = v
					c.beginUpdate()
					c.frame.tree.expandAllAncestors(v)
					c.selectVnode(v)
					c.endUpdate()
					break
		except:
			es_exception()
	finally:
		aspell.closePipes()
		return alts, word</t>
<t tx="edream.110203113231.975">@ We don't bother to call apell if the word is in our dictionary. The dictionary contains both locally 'allowed' words and 'ignored' words. We put the test before aspell rather than after aspell because the cost of checking aspell is higher than the cost of checking our local dictionary. For small local dictionaries this is probably not true and this code could easily be located after the aspell call
@c

if self.dictionary.has_key(word.lower()):
	
	# print "Ignored", word
	continue
	
# print "Didn't ignore '%s'" % word</t>
<t tx="edream.110203113231.976">def findNextWord (self,v):
	
	"""Scan for the next word, leaving the result in the work widget"""

	t = self.workCtrl
	word_start = string.letters + '_'
	t.mark_set("insert","insert wordend + 1c")
	while 1:
		# print `t.index("insert")`,`t.index("end-1c")`
		if t.compare("insert","&gt;=","end - 1c"):
			v = v.threadNext()
			if not v: return None,None
			t.delete("1.0","end")
			t.insert("end",v.bodyString())
			t.mark_set("insert","1.0")
		elif t.compare("insert","&gt;=","insert lineend - 1c"):
			t.mark_set("insert","insert lineend + 1line")
		else:
			ch = t.get("insert")
			if ch in word_start:
				word = t.get("insert wordstart","insert wordend")
				app.gui.setTextSelection(t,"insert wordstart","insert wordend")
				# print "findNextWord:",`word`
				return v,word
			elif ch:
				t.mark_set("insert","insert + 1c")</t>
<t tx="edream.110203113231.977">def getSuggestion (self):
	
	"""Return the selected suggestion from the listBox."""
	
	# Work around an old Python bug.  Convert strings to ints.
	items = self.listBox.curselection()
	try:
		items = map(int, items)
	except ValueError: pass

	if items:
		n = items[0]
		suggestion = self.suggestions[n]
		return suggestion
	else:
		return None</t>
<t tx="edream.110203113231.978">def onMap (self,event=None):
	
	"""Respond to a Tk &lt;Map&gt; event."""
	
	self.update(show=false,fill=false)</t>
<t tx="edream.110203113231.979">def onSelectListBox (self,event=None):
	
	"""Respond to a click in the selection listBox."""
	
	self.updateButtons()
	self.body.bodyCtrl.focus_set()
</t>
<t tx="edream.110203113231.980">def update (self,show=true,fill=false):
	
	"""Update the Spell Check dialog."""
	
	# print "update(show=%d,fill=%d)" % (show,fill)
	
	# Always assume that the user has changed text.
	self.c = c = top()
	self.v = c.currentVnode()
	self.body = c.frame.body
	if fill:
		self.fillbox([])
	self.updateButtons()
	if show:
		self.top.deiconify()
		# Don't interfere with Edit Headline commands.
		self.body.bodyCtrl.focus_set()
		
	# Give the signon if it hasn't been given yet.
	if not self.aspell.signonGiven:
		self.aspell.openPipes()
		self.aspell.closePipes()</t>
<t tx="edream.110203113231.981">def updateButtons (self):
	
	"""Enable or disable buttons in the Check Spelling dialog."""
	
	start,end = app.gui.getTextSelection(self.body.bodyCtrl)
	state = choose(self.suggestions and start,"normal","disabled")
	
	self.changeButton.configure(state=state)
	self.changeFindButton.configure(state=state)

	state = choose(self.c.undoer.canRedo(),"normal","disabled")
	self.redoButton.configure(state=state)
	
	state = choose(self.c.undoer.canUndo(),"normal","disabled")
	self.undoButton.configure(state=state)
	
	state = choose(self.local_dictionary_file,"normal","disabled")
	self.addButton.configure(state=state)

	self.ignoreButton.configure(state="normal")</t>
<t tx="edream.110203113231.982">@ignore</t>
<t tx="edream.110203113231.983">@nocolor

Attached is some proof-of-concept code for a Leo Plugin manager.

To try it out ... (warning: it will write files to your c:\temp directory)

1. Start 'leopm_server.py' ... Should display a message saying "Listening on 8001"
2. Start 'leopm_client.py' ... Should bring up an ugly Tkinter window

How it works:

1. The client attaches to the remote server (via XMLRPC) 
2. Client asks for a list of plug-ins
3. Server responds
4. Client asks for details of files required + version for each plugin
5. Client checks local plugin directory to see if these files are there and if they are the right version.
6. Client displays list of available + installed plugins
7. User selects plugin and clicks 'Install'
8. Client requests files from server
9. Server sends back files
10. Client installs files in local directory (currently c:\temp)

In the current code, the client side is functional - the server side is
actually dummy methods just returning the right kind of data. There's no
point doing anything clever there until the client functionality is
fully fleshed out. Although it is all running locally in the demo there
aren't any code changes required to run remotely.

It is all pretty primitive, but I think the functionality maps quite
closely with jEdit. Tidying the Tkinter interface and fleshing out the
server side shouldn't take too long and then it could be wrapped as a
plugin itself.

Advantages of this (XMLRPC) approach,

- can go over HTTP port
- client and server are nicely decoupled (server needn't be in Python if the web host doesn't support it)
- client/server stuff is so transparent (look at the server implementation!) compared to other approaches.

Some kind of 'submit plugin' option would be interesting, but suddenly security issues start to loom!

Do you think this is worth pursuing?</t>
<t tx="edream.110203113231.984">@first #!/usr/bin/env python

"""A client implementing a plug-in manager for Leo

The client is based on an XML server architecture. Methods exist
to query the plug-ins on the server, find version numbers, help information and
to download the actual source. In the future it might be possible to upload
plug-ins as well."""

try:
	import Tkinter
	from Tkinter import *
	import os,re,xmlrpclib
except ImportError:
	Tkinter = None
	
Tk = Tkinter

if Tk:
	__version__ = "0.1"
	
	PORT = 8001 # The port the server is listening on
	HOST = "http://localhost:%d" % PORT
	ROOTDIR = r"c:\temp" # Where the plugins will end up
	
	@others
	
	if __name__ == "__main__":
		server = xmlrpclib.ServerProxy(HOST)
		root = Tk()
		client = LeoPMClient(root, server, ROOTDIR)
		root.mainloop()
	</t>
<t tx="edream.110203113231.985">class LeoPMClient:
	
	"""The client to talk to the LeoPM server"""

	@others
</t>
<t tx="edream.110203113231.986">def __init__(self, master, server, rootdir):
    """Initialize the client"""
    self.server = server
    self.master = master
    self.rootdir = rootdir
    #
    frame = Frame(master)
    frame.pack()
    #
    l = Label(frame, text="Leo Plugin Manager")
    l.pack(side=TOP)
    # Get the list of plugins
    listbox = Listbox(frame)
    listbox.pack(side=TOP)
    self.listbox = listbox
    self.initListbox()
    # Detail box for additional information
    text = Text(frame)
    text.pack(side=TOP)
    self.text = text
    #
    buttonframe = Frame(frame)
    buttonframe.pack(side=BOTTOM)
    #
    quit = Button(buttonframe, text="QUIT", fg="red", command=master.quit)
    quit.pack(side=RIGHT)
    #
    download = Button(buttonframe, text="Download", command=self.downloadPlugin)
    download.pack(side=LEFT)
    # Start polling for changes in selection
    self.lastselection = None
    self.poll() </t>
<t tx="edream.110203113231.987">def poll(self):
    """Poll and update the detail view if appropriate"""
    now = self._getSelectedPluginName()
    if now is not None and now != self.lastselection:
        self.updateDetail(now)
        self.lastselection = now
    self.master.after(250, self.poll)
</t>
<t tx="edream.110203113231.988">def _getSelectedPluginName(self):
    """Return the currently selected plugin name"""
    sel = self.listbox.curselection()
    if sel:
        return self.plugins[int(sel[0])]
    else:
        return None
</t>
<t tx="edream.110203113231.989">def updateDetail(self, name):
    """Update the detail view of a plugin"""
    self.text.delete(1.0, END)
    self.text.insert(END, self.server.getPluginDescription(name))
</t>
<t tx="edream.110203113231.990">def downloadPlugin(self):
    """Download the selected plugin"""
    self.text.insert(END, "\n\nInstalling\n")
    data = self.server.getPlugin(self._getSelectedPluginName())
    self.text.insert(END, "Got plugin data\n")
    for filename, text in data:
        self.text.insert(END, "Copying file '%s' ..." % filename)
        f = file(os.path.join(self.rootdir, filename), "w")
        f.write(text)
        f.close()
        self.text.insert(END, "Done!\n")
    self.text.insert(END, "\n\nPlugin installed\n")
    self.initListbox()
</t>
<t tx="edream.110203113231.991">def getPluginList(self):
    """Return a list of plugins on the server
    
    We markup the list to show which plugins are installed etc
    
    """
    ret = []
    self.plugins = server.getPluginNames()
    for name in self.plugins:
        version = server.getPluginVersion(name)
        files = server.getPluginFilenames(name)
        #
        found = 0
        version = None
        #
        for fname in files:
            # Is file already installed?
            filename = os.path.join(self.rootdir, fname)
            if os.path.isfile(filename):
                found += 1
                # Check version
                version = version or self.getVersionOfFile(filename)
        #
        if found == len(files):
            version = version or "Unknown"
            ret.append("%s - installed (v%s)" % (name, version))
        elif found:
            ret.append("%s - partially installed" % name)
        else:
            ret.append(name)
    #
    return ret
</t>
<t tx="edream.110203113231.992">def initListbox(self):
    """Initialize the listbox"""
    plugin_list = self.getPluginList()
    self.listbox.delete(0, END)
    for item in plugin_list:
        self.listbox.insert(END, item)
</t>
<t tx="edream.110203113231.993">def getVersionOfFile(self, filename):
    """Check the version of a plugin file"""
    ver = re.compile('.*__version__\s*=\s"(.*?)".*', re.DOTALL+re.MULTILINE)
    f = file(filename, "r")
    text = f.read()
    f.close()
    match = ver.match(text)
    if match:
        return match.groups()[0]
    else:
        return None
</t>
<t tx="edream.110203113231.994">@first #!/usr/bin/env python

"""A server implementing a plug-in manager for Leo

The server is based on an XML server architecture. Methods exist
to query the plug-ins on the server, find version numbers, help information and to
download the actual source. In the future it might be possible to upload
plug-ins as well."""

import SimpleXMLRPCServer

__version__ = "0.1"

PORT = 8001

@others
        
if __name__ == "__main__":
    # Create the server
    leoPluginManager = LeoPM()
    server = SimpleXMLRPCServer.SimpleXMLRPCServer(("localhost", PORT))
    server.register_instance(leoPluginManager)
    # Go into the main listener loop
    print "LeoPM (v%s) Started\nListening on port %s" % (__version__, PORT)
    server.serve_forever()</t>
<t tx="edream.110203113231.995">class LeoPM:
	"""The Leo Plugin manager XMLRPC server"""
	@others
</t>
<t tx="edream.110203113231.996">def __init__(self, plugin_dir="."):
    """Start the server with plugins located in the specified directory"""
</t>
<t tx="edream.110203113231.997">    #self._locatePlugins()
    
def getPluginNames(self):
    """Return a list of the plug-ins by name"""
    return ["one", "two", "three"]
</t>
<t tx="edream.110203113231.998">def getPluginDescription(self, name):
	
    """Return the description of the plugin"""

    return "%s - v%s\n\n%s" % (name, len(name), "Some important details about it")
</t>
<t tx="edream.110203113231.999">def getPlugin(self, name):

    """Get the source files for a plugin
    
    Files are returned as a list of tuples (filename, text)"""

    return [("%s1.py" % name, 'this is #1\n__version__ = "%d"' % len(name)),
            ("%s2.py" % name, 'this is #2\n__version__ = "%d"' % len(name))]
</t>
<t tx="edream.110203113231.1000">def getPluginVersion(self, name):
	
    """Return the plugin version"""

    return len(name)
</t>
<t tx="edream.110203113231.1001">def getPluginFilenames(self, name):
	
    """Return a list of the files needed by a plugin"""
    return ("%s1.py" % name, "%s2.py" % name)</t>
<t tx="edream.110403140857"></t>
<t tx="edream.110403140857.1"></t>
<t tx="edream.110403140857.2">@
--How to install the wiki markup plugin--

1) first make sure that the "add_directives" plugin is enabled. This plugin turns on support for @markup directives, and it can be found in leoPlugins.leo under the section "Plugins &amp; scripts" -&gt; Directives. In particular:
	a) check that the plugin code is enabled. You should have a line like (note the "if 1"):
		if 1: # Register the handlers...
	b) generate the plugin file. Right click with the mouse on the outline heading "@file add_directives.py" and select "Write @file nodes".

2) enable the "color_markup.py" plugin:
	a) check that the plugin code is enabled. You should have a line like:
		if Tkinter: # Register the handlers...
	b) generate the plugin file. Right click with the mouse on the outline heading "@file color_markup.py" and select "Write @file nodes".

</t>
<t tx="edream.110403140857.3">@
--How to use the wiki markup plugin--

Make sure first that both the add_directives and color_markup plugins are installed and enabled (see the Installation node for details). Make also sure that coloring is not disabled for your outline (i.e. you should not have @nocolor in an ancestor node).
	
Important: coloring via wiki markups is only supported in doc parts and Python triple-double-quoted strings (not in Python triple-single-quoted strings!).

To use the wiki markup, write

@markup wiki # turn on the wiki markup
@            # start a doc part
(here goes your marked-up text, see below)

To disable the wiki markup, write

@markup      # turn off the wiki markup

You can now use the markups either selecting the Wiki menu entries (or the corresponding keyboard shortcuts) found in the Edit-&gt;Edit Body-&gt;Wiki Tags menu, or manually inserting the tags yourself. 

If you use the menus, you can either select a word and choose the appropriate menu entry to appy styling to that word, or you can just choose a menu entry (e.g. "Bold") and start writing text with the correspongin style. Select the menu entry again to return to normal text.

See the "Supported markups" for the currently supported markups.

See also the "Example" subnode. If you have the add_directives and color_markup plugins enabled, you should see the text in that node displayed as styled text.</t>
<t tx="edream.110403140857.4">@
The currently supported markups are:

''text''                   # write text in italics
__text__                   # write text in bold
~~&lt;color&gt;:text~~           # write text in the color specified by &lt;color&gt; (e.g. blue, grey, etc)
{picture file=&lt;filename&gt;}  # load the picture indicated by &lt;filename&gt;
http://url                 # URL support: double clicking on the url will open it in the default browser.
https://url                # URL support: double clicking on the url will open it in the default browser.

Note 1: italics and bold markups can be nested, e.g.

''__text__''               # write text in italics and bold

Just remember to terminate the tags in the order they were opened.

Note 2: URLs must be terminated by a space.

By default, once the text has been markup up, the actual tags (e.g. __ for bold) are not displayed anymore. You can choose to display them selecting "Show Invisibles" from the Edit menu.
</t>
<t tx="edream.110403140857.5">@color
@markup wiki
@doc (this turns on a doc section; a '@ ' would do too)

This should be ''italic'' text
This should be __bold__ text
This text should be ~~pink:colored in pink~~, ~~blue:this one in blue~~.
This text should be ''__both bold and italic__''.
Leo's homepage is at http://webpages.charter.net/edreamleo/front.html 

You can also have wiki markups in python triple-double-quoted strings:

@c

def __dummy():
	"""This is a __very important__ function."""
	return None
</t>
<t tx="edream.110403140857.6">@
Wiki markups are supported ''in subnodes too''.</t>
<t tx="edream.110403140857.7">@
Version 1.2.1, October 29, 2003.

Added documentation.
Added menu entries to tag selected text and to start/end wiki tagging.

Version 1.3, October 29, 2003.

Fixed bug in the creation of the wiki menu.
Added support for clickable http tags.

Version 1.4, November 4, 2003.
Put import tkinter in a try/except block.
Made changes for 4.1 app.gui architecture. (More work needed).</t>
<t tx="edream.110403140857.8">"""Handle coloring for markup in doc parts and Python triple-double-quoted strings"""

from leoPlugins import *
from leoGlobals import *

try:
	import Tkinter
except ImportError:
	Tkinter = None

import string  # zfill does not exist in Python 2.2.1
import tkColorChooser

if Tkinter: # Register the handlers...

	@others

	if app.gui is None:
		app.createTkGui(__file__)

	if app.gui.guiName() == "tkinter":
		
		print "wiki markup enabled"
		
		# default value for color-tagged wiki text
		wikiColoredText = "blue"

		registerHandler("color-optional-markup", colorWikiMarkup)
		registerHandler("init-color-markup", initAnyMarkup)
		#registerHandler("bodykey1", onBodykey1)
		registerHandler("bodydclick1", onBodydclick1)
		registerHandler(("start2","open2","command2"), createWikiMenu)
	
		__version__ = "1.4" # DS: 10/29/03.  EKR: 11/4/03: mods for 4.1.
		plugin_signon(__name__)
</t>
<t tx="edream.110403140857.9">def initAnyMarkup (tag,keywords):
	
	"""initialize colorer.markup_string
	
	The colorer completely recolors the body pane when this changes"""
	
	keys = ("colorer","v")
	colorer,v = [keywords.get(key) for key in keys]

	c = colorer.c
	if not c or not v or not top(): return

	# underline means hyperlinks
	c.frame.body.tag_configure("http",underline=1) # EKR: 11/4/03
	c.frame.body.tag_configure("https",underline=1) # EKR: 11/4/03
	# trace()
	dict = scanDirectives(c,v=v) # v arg is essential.
	pluginsList = dict.get("pluginsList")
	
	if pluginsList:
		for d,v,s,k in pluginsList:
			if d == "markup":
				kind = s[k:]
				if kind:
					colorer.markup_string = kind
					return
					
	colorer.markup_string = "unknown" # default</t>
<t tx="edream.110403140857.10">colorCount = 0

def colorWikiMarkup (tag,keywords):

	keys = ("colorer","v","s","i","j","colortag")
	colorer,v,s,i,j,colortag = [keywords.get(key) for key in keys]

	global colorCount ; colorCount += 1
	
	c = colorer.c
	dict = scanDirectives(c,v=v) # v arg is essential.
	pluginsList = dict.get("pluginsList")
	
	if pluginsList:
		for d,v,s2,k in pluginsList:
			if d == "markup":
				# trace(`colorCount`,`d`)
				if match_word(s2,k,"wiki"):
					doWikiText(colorer,v,s,i,j,colortag)
					return true # We have colored the text.
			
	# trace(`colorCount`,"no markup")
	return None # We have not colored the text.</t>
<t tx="edream.110403140857.11">def doWikiText (colorer,v,s,i,end,colortag):

	firsti = i ; inserted = 0

	while i &lt; end:
		&lt;&lt; set first to a tuple describing the first tag to be handled &gt;&gt;
		if first:
			tag,n1,n2,delim1,delim2 = first
			i = n2 + len(delim2)
			&lt;&lt; handle the tag using n1,n2,delim1,delim2 &gt;&gt;
		else: i = end
		
	colorer.tag(colortag,firsti,end+inserted)</t>
<t tx="edream.110403140857.12">first = None

for tag,delim1,delim2 in (
	("bold","__","__"),
	("italic","''","''"),
	("picture","{picture file=","}"),
	("color","~~","~~"),
	("http","http://"," "),
	("https","https://"," ")):
	n1 = s.find(delim1,i,end)
	if n1 &gt; -1:
		n2 = s.find(delim2,n1+len(delim1),end)
		if n2 &gt; -1:
			if not first or (first and n1 &lt; first[1]):
				first = tag,n1,n2,delim1,delim2
</t>
<t tx="edream.110403140857.13">if tag =="picture":
	colorer.tag("elide",n1,n2+len(delim2)) # Elide everything.
	filename = s[n1+len(delim1):n2]
	filename = os.path.join(app().loadDir,filename)
	filename = os.path.normpath(filename)
	inserted += insertWikiPicture(colorer,filename,n2+len(delim2))
elif tag == "color":
	&lt;&lt; parse and handle color field &gt;&gt;
elif tag == "http" or tag == "https":
	colorer.tag(tag,n1,n2)
else:
	# look for nested bold or italic.
	if tag == "bold":
		delim3,delim4 = "''","''" # Look for nested italic.
	else:
		delim3,delim4 = "__","__" # Look for nested bold.
	n3 = s.find(delim3,n1+len(delim1),n2) ; n4 = -1
	if n3 &gt; -1:
		n4 = s.find(delim4,n3+len(delim3),n2+len(delim2))
	if n3 &gt; -1 and n4 &gt; -1:
		colorer.tag("elide",n1,n1+len(delim1))
		colorer.tag("elide",n2,n2+len(delim2))
		colorer.tag("elide",n3,n3+len(delim3))
		colorer.tag("elide",n4,n4+len(delim4))
		colorer.tag(tag,n1+len(delim1),n3)
		colorer.tag("bolditalic",n3+len(delim3),n4)
		colorer.tag(tag,n4+len(delim4),n2)
	else:
		# No nested tag.
		colorer.tag("elide",n1,n1+len(delim1))
		colorer.tag("elide",n2,n2+len(delim2))
		colorer.tag(tag,n1+len(delim1),n2)</t>
<t tx="edream.110403140857.14"># Parse the color value.
j = n1+len(delim1)
n = s.find(":",j,n2)
if n2 &gt; n &gt; j &gt; -1:
	name = s[j:n]
	if name[0] == '#' and len(name) &gt; 1:
		name = '#' + string.zfill(name[1:],6)
	if name in colorer.color_tags_list:
		colorer.tag("elide",n1,n+1)
		colorer.tag(name,n+1,n2)
		colorer.tag("elide",n2,n2+len(delim2))
	else:
		try:
			# print "entering", name
			colorer.body.bodyCtrl.tag_configure(name,foreground=name)
			colorer.color_tags_list.append(name)
			colorer.tag("elide",n1,n+1)
			colorer.tag(name,n+1,n2)
			colorer.tag("elide",n2,n2+len(delim2))
		except: # an invalid color name: elide nothing.
			pass # es_exception()</t>
<t tx="edream.110403140857.15">def insertWikiPicture (colorer,filename,i):
	
	"""Try to insert a picture with the give filename.
	
	Returns the number of characters actually inserted"""
	
	# trace(`colorer.color_pass`)
	if colorer.color_pass == 0:
		colorer.redoColoring = true # schedule a two-pass recoloring.
		return 0
		
	if colorer.color_pass == 2:
		return 0 # The second redo pass.
		
	# trace(`filename`,`v`)
	if not os.path.exists(filename):
		return 0

	try:
		# Create the image
		photo = Tkinter.PhotoImage(master=app().root, file=filename)
		image = colorer.body.bodyCtrl.image_create(colorer.index(i),image=photo,padx=0)
		
		# Keep references so images stay on the canvas.
		colorer.image_references.append((photo,image,colorer.line_index,i),)
		return 1
	except:
		es_exception()
		return 0</t>
<t tx="edream.110403140857.16">def onBodykey1(tag,keywords):
	c = keywords.get("c")
	body = c.frame.body
	idx = body.bodyCtrl.index("insert")
	line,char = map(int, idx.split('.'))
	elideRange = body.bodyCtrl.tag_prevrange("elide", idx) # EKR: 11/4/03
	if elideRange:
		elideLine,elideStart = map(int, elideRange[0].split('.'))
		elideLine,elideEnd   = map(int, elideRange[1].split('.'))
		if line==elideLine and elideStart&lt;char&lt;=elideEnd:
			pass
			# print "XXX: tag!"
			# body.bodyCtrl.mark_set("insert", "elide+1c")
	return 0 # do not override
</t>
<t tx="edream.110403140857.17">def onBodydclick1(tag,keywords):
	"""Handle double clicks on a hyperlink."""

	c = keywords.get("c")
	url = getUrl(c, "http", "https")
	if url:
		try:
			import webbrowser
			webbrowser.open(url)
		except:
			es("exception opening " + url)
			es_exception()
</t>
<t tx="edream.110403140857.18">def getUrl(c, *tags):
	"""See if the current text belongs to a hyperlink tag and, if so, return the url."""
	
	body = c.frame.body
	selStart,selEnd = body.getTextSelection() # EKR: 11/4/03
	for tag in tags:
		hyperlink = body.bodyCtrl.tag_prevrange(tag,selEnd) # EKR: 11/4/03
		if hyperlink:
			hyperStart,hyperEnd = hyperlink
			if selStart==selEnd: 
				# kludge: only react on single chars, not on selections
				if body.bodyCtrl.compare(hyperStart,"&lt;=",selStart) and body.bodyCtrl.compare(selStart,"&lt;=",hyperEnd):
					url = body.bodyCtrl.get(hyperStart,hyperEnd)
					return url
	return None</t>
<t tx="edream.110403140857.19"></t>
<t tx="edream.110403140857.20">def createWikiMenu(tag, keywords):
	"""Create menu entries under Edit-&gt;Edit Body to insert wiki tags."""

	if	(tag=="open2" or tag=="start2" or
		(tag=="command2" and keywords.get("label")=="new")):

		c = top()
		
		editBodyMenuName = "Edit Body..."
		wikiMenuName = "&amp;Wiki Tags..."
		if c.frame.menu.getMenu(wikiMenuName):
			return # wiki menu already created

		editBodyMenu = c.frame.menu.getMenu(editBodyMenuName)
		separator = (("-", None, None),)
		c.frame.menu.createMenuEntries(editBodyMenu, separator)
		
		wikiMenu = c.frame.menu.createNewMenu(wikiMenuName, editBodyMenuName)
		newEntries = (
			("&amp;Bold", "Alt+Shift+B", doWikiBold),
			("&amp;Italic", "Alt+Shift+I", doWikiItalic),
			#("Insert Pict&amp;ure...", "Alt+Shift+U", doWikiPicture),
			("C&amp;olor", "Alt+Shift+O", doWikiColor),
			("Choose Co&amp;lor...", "Alt+Shift+L", doWikiChooseColor),
			)
		
		c.frame.menu.createMenuEntries(wikiMenu, newEntries)

</t>
<t tx="edream.110403140857.21">def doWikiBold(event=None):
	c = top()
	v = c.currentVnode()
	if not v: return

	insertWikiMarkup(c,v,"__","__")
	return</t>
<t tx="edream.110403140857.22">def doWikiItalic(event=None):
	c = top()
	v = c.currentVnode()
	if not v: return

	insertWikiMarkup(c,v,"''","''")
	return
</t>
<t tx="edream.110403140857.23">def doWikiColor(event=None):
	global wikiColoredText
	
	c = top()
	v = c.currentVnode()
	if not v: return

	insertWikiMarkup(c,v,"~~%s:" % wikiColoredText,"~~")
	return
</t>
<t tx="edream.110403140857.24">def doWikiChooseColor(event=None):
	global wikiColoredText
	
	c = top()
	v = c.currentVnode()
	if not v: return
	
	rgb,val = tkColorChooser.askcolor(color=wikiColoredText)
	if val:
		wikiColoredText = val
		doWikiColor()
</t>
<t tx="edream.110403140857.25">def doWikiPicture(event=None):
	import tkFileDialog

	c = top()
	v = c.currentVnode()
	if not v: return

	name = tkFileDialog.askopenfilename(
		title="Insert Picture",
		filetypes=[("All files", "*")]
		)
	if name == "":	return
	
	insertWikiMarkup(c,v,"{picture file=%s}" % name,"")
	return</t>
<t tx="edream.110403140857.26">def insertWikiMarkup(c,v,leftTag,rightTag):
	body = c.frame.body
	oldSel = body.bodyCtrl.tag_ranges("sel")
	if oldSel:
		&lt;&lt; apply markup to selection &gt;&gt;
	else:
		&lt;&lt; handle no selection &gt;&gt;

	body.focus_set()</t>
<t tx="edream.110403140857.27">start,end = oldSel
body.bodyCtrl.insert(start, leftTag)
# we need to review where the selection now ends
start,end = body.bodyCtrl.tag_ranges("sel")
body.bodyCtrl.insert(end, rightTag)
app.gui.setTextSelection(body.bodyCtrl, start + "-" + `len(leftTag)`  + "c",
						 end + "+" + `len(rightTag)` + "c")
newSel = body.getTextSelection()
c.frame.onBodyChanged(v,"Change",oldSel=oldSel,newSel=newSel)
</t>
<t tx="edream.110403140857.28"># Note: this does not currently handle mixed nested tags,
# e.g. &lt;b&gt;&lt;i&gt;text&lt;/b&gt;&lt;/i&gt;. One should always close the
# tags in the order they were opened, as in &lt;b&gt;&lt;i&gt;text&lt;/i&gt;&lt;/b&gt;.
oldSel = body.getTextSelection() # EKR: 11/04/03
nextChars = body.bodyCtrl.get(oldSel[0], "%s+%dc" % (oldSel[0],len(rightTag)))
if nextChars == rightTag:
	# if the next chars are the right tag, just move beyond it
	newPos = "%s+%dc" % (oldSel[0],len(rightTag))
else:
	# insert a pair of tags and set cursor between the tags
	body.bodyCtrl.insert("insert", leftTag)
	body.bodyCtrl.insert("insert", rightTag)
	newPos = "%s+%dc" % (oldSel[0],len(leftTag))
body.setTextSelection(newPos, newPos)
newSel = body.getTextSelection()
c.frame.onBodyChanged(v,"Typing",oldSel=oldSel,newSel=newSel)
</t>
<t tx="edream.110603185221">@language python
@ignore</t>
<t tx="edream.110603185221.1"></t>
<t tx="edream.110603185221.2">"""Debugger basics"""

import os,sys,types

__all__ = ["BdbQuit","Bdb","Breakpoint"]

@others</t>
<t tx="edream.110603185221.3">class BdbQuit(Exception):
	"""Exception to give up completely"""
</t>
<t tx="edream.110603185221.4">class Bdb:
	
	"""Generic Python debugger base class.

This class takes care of details of the trace facility;
a derived class should implement user interaction.
The standard debugger class (pdb.Pdb) is an example.
"""

	@others</t>
<t tx="edream.110603185221.5">def __init__(self):

    self.breaks = {}
    self.fncache = {}
</t>
<t tx="edream.110603185221.6">def canonic(self, filename):
    if filename == "&lt;" + filename[1:-1] + "&gt;":
        return filename
    canonic = self.fncache.get(filename)
    if not canonic:
        canonic = os.path.abspath(filename)
        canonic = os.path.normcase(canonic)
        self.fncache[filename] = canonic
    return canonic
</t>
<t tx="edream.110603185221.7">def reset(self):
    import linecache
    linecache.checkcache()
    self.botframe = None
    self.stopframe = None
    self.returnframe = None
    self.quitting = 0
</t>
<t tx="edream.110603185221.8">def trace_dispatch(self, frame, event, arg):
    if self.quitting:
        return # None
    if event == 'line':
        return self.dispatch_line(frame)
    if event == 'call':
        return self.dispatch_call(frame, arg)
    if event == 'return':
        return self.dispatch_return(frame, arg)
    if event == 'exception':
        return self.dispatch_exception(frame, arg)
    print 'bdb.Bdb.dispatch: unknown debugging event:', `event`
    return self.trace_dispatch
</t>
<t tx="edream.110603185221.9">def dispatch_line(self, frame):
    if self.stop_here(frame) or self.break_here(frame):
        self.user_line(frame)
        if self.quitting: raise BdbQuit
    return self.trace_dispatch
</t>
<t tx="edream.110603185221.10">def dispatch_call(self, frame, arg):
    # XXX 'arg' is no longer used
    if self.botframe is None:
        # First call of dispatch since reset()
        self.botframe = frame.f_back # (CT) Note that this may also be None!
        return self.trace_dispatch
    if not (self.stop_here(frame) or self.break_anywhere(frame)):
        # No need to trace this function
        return # None
    self.user_call(frame, arg)
    if self.quitting: raise BdbQuit
    return self.trace_dispatch
</t>
<t tx="edream.110603185221.11">def dispatch_return(self, frame, arg):
    if self.stop_here(frame) or frame == self.returnframe:
        self.user_return(frame, arg)
        if self.quitting: raise BdbQuit
    return self.trace_dispatch
</t>
<t tx="edream.110603185221.12">def dispatch_exception(self, frame, arg):
    if self.stop_here(frame):
        self.user_exception(frame, arg)
        if self.quitting: raise BdbQuit
    return self.trace_dispatch
</t>
<t tx="edream.110603185221.13"># Normally derived classes don't override the following
# methods, but they may if they want to redefine the
# definition of stopping and breakpoints.

def stop_here(self, frame):
    # (CT) stopframe may now also be None, see dispatch_call.
    # (CT) the former test for None is therefore removed from here.
    if frame is self.stopframe:
        return True
    while frame is not None and frame is not self.stopframe:
        if frame is self.botframe:
            return True
        frame = frame.f_back
    return False
</t>
<t tx="edream.110603185221.14">def break_here(self, frame):

    filename = self.canonic(frame.f_code.co_filename)
    if not filename in self.breaks:
        return False
    lineno = frame.f_lineno
    if not lineno in self.breaks[filename]:
        return False
    # flag says ok to delete temp. bp
    (bp, flag) = effective(filename, lineno, frame)
    if bp:
        self.currentbp = bp.number
        if (flag and bp.temporary):
            self.do_clear(str(bp.number))
        return True
    else:
        return False
</t>
<t tx="edream.110603185221.15">def do_clear(self, arg):
    raise NotImplementedError, "subclass of bdb must implement do_clear()"
</t>
<t tx="edream.110603185221.16">def break_anywhere(self, frame):
    return self.breaks.has_key(
        self.canonic(frame.f_code.co_filename))
</t>
<t tx="edream.110603185221.17"># Derived classes should override the user_* methods to gain control.</t>
<t tx="edream.110603185221.18">def user_call(self, frame, argument_list):
    """This method is called when there is the remote possibility
    that we ever need to stop in this function."""
    pass
</t>
<t tx="edream.110603185221.19">def user_line(self, frame):
    """This method is called when we stop or break at this line."""
    pass
</t>
<t tx="edream.110603185221.20">def user_return(self, frame, return_value):
    """This method is called when a return trap is set here."""
    pass
</t>
<t tx="edream.110603185221.21">def user_exception(self, frame, (exc_type, exc_value, exc_traceback)):
    """This method is called if an exception occurs,
    but only if we are to stop at or just below this level."""
    pass
</t>
<t tx="edream.110603185221.22"># Derived classes and clients can call the following methods
# to affect the stepping state.</t>
<t tx="edream.110603185221.23">def set_step(self):
    """Stop after one line of code."""
    self.stopframe = None
    self.returnframe = None
    self.quitting = 0
</t>
<t tx="edream.110603185221.24">def set_next(self, frame):
    """Stop on the next line in or below the given frame."""
    self.stopframe = frame
    self.returnframe = None
    self.quitting = 0
</t>
<t tx="edream.110603185221.25">def set_return(self, frame):
    """Stop when returning from the given frame."""
    self.stopframe = frame.f_back
    self.returnframe = frame
    self.quitting = 0
</t>
<t tx="edream.110603185221.26">def set_trace(self):
    """Start debugging from here."""
    frame = sys._getframe().f_back
    self.reset()
    while frame:
        frame.f_trace = self.trace_dispatch
        self.botframe = frame
        frame = frame.f_back
    self.set_step()
    sys.settrace(self.trace_dispatch)
</t>
<t tx="edream.110603185221.27">def set_continue(self):
    # Don't stop except at breakpoints or when finished
    self.stopframe = self.botframe
    self.returnframe = None
    self.quitting = 0
    if not self.breaks:
        # no breakpoints; run without debugger overhead
        sys.settrace(None)
        frame = sys._getframe().f_back
        while frame and frame is not self.botframe:
            del frame.f_trace
            frame = frame.f_back
</t>
<t tx="edream.110603185221.28">def set_quit(self):
    self.stopframe = self.botframe
    self.returnframe = None
    self.quitting = 1
    sys.settrace(None)
</t>
<t tx="edream.110603185221.29"># Derived classes and clients can call the following methods
# to manipulate breakpoints.  These methods return an
# error message is something went wrong, None if all is well.
</t>
<t tx="edream.110603185221.30"># Set_break prints out the breakpoint line and file:lineno.
# Call self.get_*break*() to see the breakpoints or better
# for bp in Breakpoint.bpbynumber: if bp: bp.bpprint().

def set_break(self, filename, lineno, temporary=0, cond = None):
    filename = self.canonic(filename)
    import linecache # Import as late as possible
    line = linecache.getline(filename, lineno)
    if not line:
        return 'Line %s:%d does not exist' % (filename,
                               lineno)
    if not filename in self.breaks:
        self.breaks[filename] = []
    list = self.breaks[filename]
    if not lineno in list:
        list.append(lineno)
    bp = Breakpoint(filename, lineno, temporary, cond)
</t>
<t tx="edream.110603185221.31">def clear_break(self, filename, lineno):
    filename = self.canonic(filename)
    if not filename in self.breaks:
        return 'There are no breakpoints in %s' % filename
    if lineno not in self.breaks[filename]:
        return 'There is no breakpoint at %s:%d' % (filename,
                                lineno)
    # If there's only one bp in the list for that file,line
    # pair, then remove the breaks entry
    for bp in Breakpoint.bplist[filename, lineno][:]:
        bp.deleteMe()
    if not Breakpoint.bplist.has_key((filename, lineno)):
        self.breaks[filename].remove(lineno)
    if not self.breaks[filename]:
        del self.breaks[filename]
</t>
<t tx="edream.110603185221.32">def clear_bpbynumber(self, arg):
    try:
        number = int(arg)
    except:
        return 'Non-numeric breakpoint number (%s)' % arg
    try:
        bp = Breakpoint.bpbynumber[number]
    except IndexError:
        return 'Breakpoint number (%d) out of range' % number
    if not bp:
        return 'Breakpoint (%d) already deleted' % number
    self.clear_break(bp.file, bp.line)
</t>
<t tx="edream.110603185221.33">def clear_all_file_breaks(self, filename):
    filename = self.canonic(filename)
    if not filename in self.breaks:
        return 'There are no breakpoints in %s' % filename
    for line in self.breaks[filename]:
        blist = Breakpoint.bplist[filename, line]
        for bp in blist:
            bp.deleteMe()
    del self.breaks[filename]
</t>
<t tx="edream.110603185221.34">def clear_all_breaks(self):
    if not self.breaks:
        return 'There are no breakpoints'
    for bp in Breakpoint.bpbynumber:
        if bp:
            bp.deleteMe()
    self.breaks = {}
</t>
<t tx="edream.110603185221.35">def get_break(self, filename, lineno):
    filename = self.canonic(filename)
    return filename in self.breaks and \
        lineno in self.breaks[filename]
</t>
<t tx="edream.110603185221.36">def get_breaks(self, filename, lineno):
    filename = self.canonic(filename)
    return filename in self.breaks and \
        lineno in self.breaks[filename] and \
        Breakpoint.bplist[filename, lineno] or []
</t>
<t tx="edream.110603185221.37">def get_file_breaks(self, filename):
    filename = self.canonic(filename)
    if filename in self.breaks:
        return self.breaks[filename]
    else:
        return []
</t>
<t tx="edream.110603185221.38">def get_all_breaks(self):
    return self.breaks
</t>
<t tx="edream.110603185221.39"></t>
<t tx="edream.110603185221.40"># Derived classes and clients can call the following method
# to get a data structure representing a stack trace.

def get_stack(self, f, t):
    stack = []
    if t and t.tb_frame is f:
        t = t.tb_next
    while f is not None:
        stack.append((f, f.f_lineno))
        if f is self.botframe:
            break
        f = f.f_back
    stack.reverse()
    i = max(0, len(stack) - 1)
    while t is not None:
        stack.append((t.tb_frame, t.tb_lineno))
        t = t.tb_next
    return stack, i
</t>
<t tx="edream.110603185221.41">#

def format_stack_entry(self, frame_lineno, lprefix=': '):
    import linecache, repr
    frame, lineno = frame_lineno
    filename = self.canonic(frame.f_code.co_filename)
    s = filename + '(' + `lineno` + ')'
    if frame.f_code.co_name:
        s = s + frame.f_code.co_name
    else:
        s = s + "&lt;lambda&gt;"
    if '__args__' in frame.f_locals:
        args = frame.f_locals['__args__']
    else:
        args = None
    if args:
        s = s + repr.repr(args)
    else:
        s = s + '()'
    if '__return__' in frame.f_locals:
        rv = frame.f_locals['__return__']
        s = s + '-&gt;'
        s = s + repr.repr(rv)
    line = linecache.getline(filename, lineno)
    if line: s = s + lprefix + line.strip()
    return s
</t>
<t tx="edream.110603185221.42"># The following two methods can be called by clients to use
# a debugger to debug a statement, given as a string.

</t>
<t tx="edream.110603185221.43">def run(self, cmd, globals=None, locals=None):
    if globals is None:
        import __main__
        globals = __main__.__dict__
    if locals is None:
        locals = globals
    self.reset()
    sys.settrace(self.trace_dispatch)
    if not isinstance(cmd, types.CodeType):
        cmd = cmd+'\n'
    try:
        try:
            exec cmd in globals, locals
        except BdbQuit:
            pass
    finally:
        self.quitting = 1
        sys.settrace(None)
</t>
<t tx="edream.110603185221.44">def runeval(self, expr, globals=None, locals=None):
    if globals is None:
        import __main__
        globals = __main__.__dict__
    if locals is None:
        locals = globals
    self.reset()
    sys.settrace(self.trace_dispatch)
    if not isinstance(expr, types.CodeType):
        expr = expr+'\n'
    try:
        try:
            return eval(expr, globals, locals)
        except BdbQuit:
            pass
    finally:
        self.quitting = 1
        sys.settrace(None)
</t>
<t tx="edream.110603185221.45">def runctx(self, cmd, globals, locals):
    # B/W compatibility
    self.run(cmd, globals, locals)
</t>
<t tx="edream.110603185221.46"># This method is more useful to debug a single function call.

def runcall(self, func, *args):
    self.reset()
    sys.settrace(self.trace_dispatch)
    res = None
    try:
        try:
            res = func(*args)
        except BdbQuit:
            pass
    finally:
        self.quitting = 1
        sys.settrace(None)
    return res
</t>
<t tx="edream.110603185221.47">def set_trace():
    Bdb().set_trace()</t>
<t tx="edream.110603185221.48">class Breakpoint:
	
	"""Breakpoint class

Implements temporary breakpoints, ignore counts, disabling and
(re)-enabling, and conditionals.

Breakpoints are indexed by number through bpbynumber and by
the file,line tuple using bplist.  The former points to a
single instance of class Breakpoint.  The latter points to a
list of such instances since there may be more than one
breakpoint per line.

"""
	&lt;&lt; class Breakpoint declarations &gt;&gt;

	@others
</t>
<t tx="edream.110603185221.49"># XXX Keeping state in the class is a mistake -- this means
# you cannot have more than one active Bdb instance.

next = 1        # Next bp to be assigned
bplist = {}     # indexed by (file, lineno) tuple
bpbynumber = [None] # Each entry is None or an instance of Bpt
            # index 0 is unused, except for marking an
            # effective break .... see effective()</t>
<t tx="edream.110603185221.50">def __init__(self, file, line, temporary=0, cond = None):

    self.file = file    # This better be in canonical form!
    self.line = line
    self.temporary = temporary
    self.cond = cond
    self.enabled = 1
    self.ignore = 0
    self.hits = 0
    self.number = Breakpoint.next
    Breakpoint.next = Breakpoint.next + 1

    # Build the two lists
    self.bpbynumber.append(self)
    if self.bplist.has_key((file, line)):
        self.bplist[file, line].append(self)
    else:
        self.bplist[file, line] = [self]</t>
<t tx="edream.110603185221.51">def deleteMe(self):
    index = (self.file, self.line)
    self.bpbynumber[self.number] = None   # No longer in list
    self.bplist[index].remove(self)
    if not self.bplist[index]:
        # No more bp for this f:l combo
        del self.bplist[index]
</t>
<t tx="edream.110603185221.52">def enable(self):
    self.enabled = 1
</t>
<t tx="edream.110603185221.53">def disable(self):
    self.enabled = 0
</t>
<t tx="edream.110603185221.54">def bpprint(self):
    if self.temporary:
        disp = 'del  '
    else:
        disp = 'keep '
    if self.enabled:
        disp = disp + 'yes'
    else:
        disp = disp + 'no '
    print '%-4dbreakpoint    %s at %s:%d' % (self.number, disp,
                         self.file, self.line)
    if self.cond:
        print '\tstop only if %s' % (self.cond,)
    if self.ignore:
        print '\tignore next %d hits' % (self.ignore)
    if (self.hits):
        if (self.hits &gt; 1): ss = 's'
        else: ss = ''
        print ('\tbreakpoint already hit %d time%s' %
               (self.hits, ss))
</t>
<t tx="edream.110603185221.55"># Determines if there is an effective (active) breakpoint at this
# line of code.  Returns breakpoint number or 0 if none.

def effective(file, line, frame):
    """Determine which breakpoint for this file:line is to be acted upon.

    Called only if we know there is a bpt at this
    location.  Returns breakpoint that was triggered and a flag
    that indicates if it is ok to delete a temporary bp.

    """
    possibles = Breakpoint.bplist[file,line]
    for i in range(0, len(possibles)):
        b = possibles[i]
        if b.enabled == 0:
            continue
        # Count every hit when bp is enabled
        b.hits = b.hits + 1
        if not b.cond:
			&lt;&lt; handle unconditional breakpoint &gt;&gt;
        else:
            &lt;&lt; handle conditional breakpoint &gt;&gt;
    return (None, None)</t>
<t tx="edream.110603185221.56">if b.ignore &gt; 0:
	# Ignoring: go on to next.
    b.ignore = b.ignore -1
    continue
else:
    # Break.
	# Return breakpoint and marker that's ok to delete if temporary.
    return (b,1)</t>
<t tx="edream.110603185221.57"># Ignore count applies only to those bpt hits where the condition evaluates to true.

try:
    val = eval(b.cond, frame.f_globals,
           frame.f_locals)
    if val:
        if b.ignore &gt; 0:
            b.ignore = b.ignore -1
        else:
            return (b,1)
except:
    # The most conservative thing is to stop on breakpoint regardless of ignore count.
    # Don't delete temporary, as another hint to user.
    return (b,0)</t>
<t tx="edream.110603185221.58"># -------------------- testing --------------------</t>
<t tx="edream.110603185221.59">class Tdb(Bdb):
	@others
</t>
<t tx="edream.110603185221.60">def user_call(self, frame, args):
    name = frame.f_code.co_name
    if not name: name = '???'
    print '+++ call', name, args
</t>
<t tx="edream.110603185221.61">def user_line(self, frame):
    import linecache
    name = frame.f_code.co_name
    if not name: name = '???'
    fn = self.canonic(frame.f_code.co_filename)
    line = linecache.getline(fn, frame.f_lineno)
    print '+++', fn, frame.f_lineno, name, ':', line.strip()
</t>
<t tx="edream.110603185221.62">def user_return(self, frame, retval):
    print '+++ return', retval
</t>
<t tx="edream.110603185221.63">def user_exception(self, frame, exc_stuff):
    print '+++ exception', exc_stuff
    self.set_continue()
</t>
<t tx="edream.110603185221.64">def foo(n):
    print 'foo(', n, ')'
    x = bar(n*10)
    print 'bar returned', x
</t>
<t tx="edream.110603185221.65">def bar(a):
    print 'bar(', a, ')'
    return a/2
</t>
<t tx="edream.110603185221.66">def test():
    t = Tdb()
    t.run('import bdb; bdb.foo(10)')
</t>
<t tx="edream.110603185221.67">#! /usr/bin/env python

"""A Python debugger."""

# (See pdb.doc for documentation.)

import sys
import linecache
import cmd
import bdb
from repr import Repr
import os
import re
import pprint

&lt;&lt; pdb declarations &gt;&gt;

@others

mainmodule = ''
mainpyfile = ''

# When invoked as main program, invoke the debugger on a script
if __name__=='__main__':
    if not sys.argv[1:]:
        print "usage: pdb.py scriptfile [arg] ..."
        sys.exit(2)

    mainpyfile = filename = sys.argv[1]     # Get script filename
    if not os.path.exists(filename):
        print 'Error:', `filename`, 'does not exist'
        sys.exit(1)
    mainmodule = os.path.basename(filename)
    del sys.argv[0]         # Hide "pdb.py" from argument list

    # Insert script directory in front of module search path
    sys.path.insert(0, os.path.dirname(filename))

    run('execfile(' + `filename` + ')')</t>
<t tx="edream.110603185221.68"># Create a custom safe Repr instance and increase its maxstring.
# The default of 30 truncates error messages too easily.

_repr = Repr()
_repr.maxstring = 200
_saferepr = _repr.repr

__all__ = ["run", "pm", "Pdb", "runeval", "runctx", "runcall", "set_trace",
           "post_mortem", "help"]</t>
<t tx="edream.110603185221.69">def find_function(funcname, filename):
    cre = re.compile(r'def\s+%s\s*[(]' % funcname)
    try:
        fp = open(filename)
    except IOError:
        return None
    # consumer of this info expects the first line to be 1
    lineno = 1
    answer = None
    while 1:
        line = fp.readline()
        if line == '':
            break
        if cre.match(line):
            answer = funcname, filename, lineno
            break
        lineno = lineno + 1
    fp.close()
    return answer
</t>
<t tx="edream.110603185221.70"># Interaction prompt line will separate file and call info from code
# text using value of line_prefix string.  A newline and arrow may
# be to your liking.  You can set it once pdb is imported using the
# command "pdb.line_prefix = '\n% '".

# line_prefix = ': '    # Use this to get the old situation back
line_prefix = '\n-&gt; '   # Probably a better default

class Pdb(bdb.Bdb, cmd.Cmd):
	@others</t>
<t tx="edream.110603185221.71">def __init__(self):

    bdb.Bdb.__init__(self)
    cmd.Cmd.__init__(self)
    self.prompt = '(Pdb) '
    self.aliases = {}
    # Try to load readline if it exists
    try:
        import readline
    except ImportError:
        pass

    # Read $HOME/.pdbrc and ./.pdbrc
    self.rcLines = []
    if 'HOME' in os.environ:
        envHome = os.environ['HOME']
        try:
            rcFile = open(os.path.join(envHome, ".pdbrc"))
        except IOError:
            pass
        else:
            for line in rcFile.readlines():
                self.rcLines.append(line)
            rcFile.close()
    try:
        rcFile = open(".pdbrc")
    except IOError:
        pass
    else:
        for line in rcFile.readlines():
            self.rcLines.append(line)
        rcFile.close()
</t>
<t tx="edream.110603185221.72">def reset(self):
    bdb.Bdb.reset(self)
    self.forget()
</t>
<t tx="edream.110603185221.73">def forget(self):
    self.lineno = None
    self.stack = []
    self.curindex = 0
    self.curframe = None
</t>
<t tx="edream.110603185221.74">def setup(self, f, t):
    self.forget()
    self.stack, self.curindex = self.get_stack(f, t)
    self.curframe = self.stack[self.curindex][0]
    self.execRcLines()
</t>
<t tx="edream.110603185221.75"># Can be executed earlier than 'setup' if desired
def execRcLines(self):
    if self.rcLines:
        # Make local copy because of recursion
        rcLines = self.rcLines
        # executed only once
        self.rcLines = []
        for line in rcLines:
            line = line[:-1]
            if len(line) &gt; 0 and line[0] != '#':
                self.onecmd(line)
</t>
<t tx="edream.110603185221.76"># Override Bdb methods

def user_call(self, frame, argument_list):
    """This method is called when there is the remote possibility
    that we ever need to stop in this function."""
    if self.stop_here(frame):
        print '--Call--'
        self.interaction(frame, None)
</t>
<t tx="edream.110603185221.77">def user_line(self, frame):
    """This function is called when we stop or break at this line."""
    self.interaction(frame, None)
</t>
<t tx="edream.110603185221.78">def user_return(self, frame, return_value):
    """This function is called when a return trap is set here."""
    frame.f_locals['__return__'] = return_value
    print '--Return--'
    self.interaction(frame, None)
</t>
<t tx="edream.110603185221.79">def user_exception(self, frame, (exc_type, exc_value, exc_traceback)):
    """This function is called if an exception occurs,
    but only if we are to stop at or just below this level."""
    frame.f_locals['__exception__'] = exc_type, exc_value
    if type(exc_type) == type(''):
        exc_type_name = exc_type
    else: exc_type_name = exc_type.__name__
    print exc_type_name + ':', _saferepr(exc_value)
    self.interaction(frame, exc_traceback)
</t>
<t tx="edream.110603185221.80"># General interaction function

def interaction(self, frame, traceback):
    self.setup(frame, traceback)
    self.print_stack_entry(self.stack[self.curindex])
    self.cmdloop()
    self.forget()
</t>
<t tx="edream.110603185221.81">def default(self, line):
    if line[:1] == '!': line = line[1:]
    locals = self.curframe.f_locals
    globals = self.curframe.f_globals
    try:
        code = compile(line + '\n', '&lt;stdin&gt;', 'single')
        exec code in globals, locals
    except:
        t, v = sys.exc_info()[:2]
        if type(t) == type(''):
            exc_type_name = t
        else: exc_type_name = t.__name__
        print '***', exc_type_name + ':', v
</t>
<t tx="edream.110603185221.82">def precmd(self, line):
    """Handle alias expansion and ';;' separator."""
    if not line.strip():
        return line
    args = line.split()
    while args[0] in self.aliases:
        line = self.aliases[args[0]]
        ii = 1
        for tmpArg in args[1:]:
            line = line.replace("%" + str(ii),
                                  tmpArg)
            ii = ii + 1
        line = line.replace("%*", ' '.join(args[1:]))
        args = line.split()
    # split into ';;' separated commands
    # unless it's an alias command
    if args[0] != 'alias':
        marker = line.find(';;')
        if marker &gt;= 0:
            # queue up everything after marker
            next = line[marker+2:].lstrip()
            self.cmdqueue.append(next)
            line = line[:marker].rstrip()
    return line
</t>
<t tx="edream.110603185221.83"># Command definitions, called by cmdloop()
# The argument is the remaining string on the command line
# Return true to exit from the command loop

do_h = cmd.Cmd.do_help

def do_break(self, arg, temporary = 0):
    # break [ ([filename:]lineno | function) [, "condition"] ]
    if not arg:
        if self.breaks:  # There's at least one
            print "Num Type         Disp Enb   Where"
            for bp in bdb.Breakpoint.bpbynumber:
                if bp:
                    bp.bpprint()
        return
    # parse arguments; comma has lowest precedence
    # and cannot occur in filename
    filename = None
    lineno = None
    cond = None
    comma = arg.find(',')
    if comma &gt; 0:
        # parse stuff after comma: "condition"
        cond = arg[comma+1:].lstrip()
        arg = arg[:comma].rstrip()
    # parse stuff before comma: [filename:]lineno | function
    colon = arg.rfind(':')
    if colon &gt;= 0:
        filename = arg[:colon].rstrip()
        f = self.lookupmodule(filename)
        if not f:
            print '*** ', `filename`,
            print 'not found from sys.path'
            return
        else:
            filename = f
        arg = arg[colon+1:].lstrip()
        try:
            lineno = int(arg)
        except ValueError, msg:
            print '*** Bad lineno:', arg
            return
    else:
        # no colon; can be lineno or function
        try:
            lineno = int(arg)
        except ValueError:
            try:
                func = eval(arg,
                            self.curframe.f_globals,
                            self.curframe.f_locals)
            except:
                func = arg
            try:
                if hasattr(func, 'im_func'):
                    func = func.im_func
                code = func.func_code
                lineno = code.co_firstlineno
                filename = code.co_filename
            except:
                # last thing to try
                (ok, filename, ln) = self.lineinfo(arg)
                if not ok:
                    print '*** The specified object',
                    print `arg`,
                    print 'is not a function'
                    print ('or was not found '
                           'along sys.path.')
                    return
                lineno = int(ln)
    if not filename:
        filename = self.defaultFile()
    # Check for reasonable breakpoint
    line = self.checkline(filename, lineno)
    if line:
        # now set the break point
        err = self.set_break(filename, line, temporary, cond)
        if err: print '***', err
        else:
            bp = self.get_breaks(filename, line)[-1]
            print "Breakpoint %d at %s:%d" % (bp.number,
                                              bp.file,
                                              bp.line)
</t>
<t tx="edream.110603185221.84"># To be overridden in derived debuggers
def defaultFile(self):
    """Produce a reasonable default."""
    filename = self.curframe.f_code.co_filename
    if filename == '&lt;string&gt;' and mainpyfile:
        filename = mainpyfile
    return filename
</t>
<t tx="edream.110603185221.85">do_b = do_break

def do_tbreak(self, arg):
    self.do_break(arg, 1)
</t>
<t tx="edream.110603185221.86">def lineinfo(self, identifier):
    failed = (None, None, None)
    # Input is identifier, may be in single quotes
    idstring = identifier.split("'")
    if len(idstring) == 1:
        # not in single quotes
        id = idstring[0].strip()
    elif len(idstring) == 3:
        # quoted
        id = idstring[1].strip()
    else:
        return failed
    if id == '': return failed
    parts = id.split('.')
    # Protection for derived debuggers
    if parts[0] == 'self':
        del parts[0]
        if len(parts) == 0:
            return failed
    # Best first guess at file to look at
    fname = self.defaultFile()
    if len(parts) == 1:
        item = parts[0]
    else:
        # More than one part.
        # First is module, second is method/class
        f = self.lookupmodule(parts[0])
        if f:
            fname = f
        item = parts[1]
    answer = find_function(item, fname)
    return answer or failed
</t>
<t tx="edream.110603185221.87">def checkline(self, filename, lineno):
    """Return line number of first line at or after input
    argument such that if the input points to a 'def', the
    returned line number is the first
    non-blank/non-comment line to follow.  If the input
    points to a blank or comment line, return 0.  At end
    of file, also return 0."""

    line = linecache.getline(filename, lineno)
    if not line:
        print 'End of file'
        return 0
    line = line.strip()
    # Don't allow setting breakpoint at a blank line
    if (not line or (line[0] == '#') or
         (line[:3] == '"""') or line[:3] == "'''"):
        print '*** Blank or comment'
        return 0
    # When a file is read in and a breakpoint is at
    # the 'def' statement, the system stops there at
    # code parse time.  We don't want that, so all breakpoints
    # set at 'def' statements are moved one line onward
    if line[:3] == 'def':
        instr = ''
        brackets = 0
        while 1:
            skipone = 0
            for c in line:
                if instr:
                    if skipone:
                        skipone = 0
                    elif c == '\\':
                        skipone = 1
                    elif c == instr:
                        instr = ''
                elif c == '#':
                    break
                elif c in ('"',"'"):
                    instr = c
                elif c in ('(','{','['):
                    brackets = brackets + 1
                elif c in (')','}',']'):
                    brackets = brackets - 1
            lineno = lineno+1
            line = linecache.getline(filename, lineno)
            if not line:
                print 'end of file'
                return 0
            line = line.strip()
            if not line: continue   # Blank line
            if brackets &lt;= 0 and line[0] not in ('#','"',"'"):
                break
    return lineno
</t>
<t tx="edream.110603185221.88">def do_enable(self, arg):
    args = arg.split()
    for i in args:
        try:
            i = int(i)
        except ValueError:
            print 'Breakpoint index %r is not a number' % i
            continue

        if not (0 &lt;= i &lt; len(bdb.Breakpoint.bpbynumber)):
            print 'No breakpoint numbered', i
            continue

        bp = bdb.Breakpoint.bpbynumber[i]
        if bp:
            bp.enable()
</t>
<t tx="edream.110603185221.89">def do_disable(self, arg):
    args = arg.split()
    for i in args:
        try:
            i = int(i)
        except ValueError:
            print 'Breakpoint index %r is not a number' % i
            continue

        if not (0 &lt;= i &lt; len(bdb.Breakpoint.bpbynumber)):
            print 'No breakpoint numbered', i
            continue

        bp = bdb.Breakpoint.bpbynumber[i]
        if bp:
            bp.disable()
</t>
<t tx="edream.110603185221.90">def do_condition(self, arg):
    # arg is breakpoint number and condition
    args = arg.split(' ', 1)
    bpnum = int(args[0].strip())
    try:
        cond = args[1]
    except:
        cond = None
    bp = bdb.Breakpoint.bpbynumber[bpnum]
    if bp:
        bp.cond = cond
        if not cond:
            print 'Breakpoint', bpnum,
            print 'is now unconditional.'
</t>
<t tx="edream.110603185221.91">def do_ignore(self,arg):
    """arg is bp number followed by ignore count."""
    args = arg.split()
    bpnum = int(args[0].strip())
    try:
        count = int(args[1].strip())
    except:
        count = 0
    bp = bdb.Breakpoint.bpbynumber[bpnum]
    if bp:
        bp.ignore = count
        if count &gt; 0:
            reply = 'Will ignore next '
            if count &gt; 1:
                reply = reply + '%d crossings' % count
            else:
                reply = reply + '1 crossing'
            print reply + ' of breakpoint %d.' % bpnum
        else:
            print 'Will stop next time breakpoint',
            print bpnum, 'is reached.'
</t>
<t tx="edream.110603185221.92">def do_clear(self, arg):
    """Three possibilities, tried in this order:
    clear -&gt; clear all breaks, ask for confirmation
    clear file:lineno -&gt; clear all breaks at file:lineno
    clear bpno bpno ... -&gt; clear breakpoints by number"""
    if not arg:
        try:
            reply = raw_input('Clear all breaks? ')
        except EOFError:
            reply = 'no'
        reply = reply.strip().lower()
        if reply in ('y', 'yes'):
            self.clear_all_breaks()
        return
    if ':' in arg:
        # Make sure it works for "clear C:\foo\bar.py:12"
        i = arg.rfind(':')
        filename = arg[:i]
        arg = arg[i+1:]
        try:
            lineno = int(arg)
        except:
            err = "Invalid line number (%s)" % arg
        else:
            err = self.clear_break(filename, lineno)
        if err: print '***', err
        return
    numberlist = arg.split()
    for i in numberlist:
        err = self.clear_bpbynumber(i)
        if err:
            print '***', err
        else:
            print 'Deleted breakpoint %s ' % (i,)
</t>
<t tx="edream.110603185221.93">do_cl = do_clear # 'c' is already an abbreviation for 'continue'

def do_where(self, arg):
    self.print_stack_trace()
</t>
<t tx="edream.110603185221.94">do_w = do_where
do_bt = do_where

def do_up(self, arg):
    if self.curindex == 0:
        print '*** Oldest frame'
    else:
        self.curindex = self.curindex - 1
        self.curframe = self.stack[self.curindex][0]
        self.print_stack_entry(self.stack[self.curindex])
        self.lineno = None
</t>
<t tx="edream.110603185221.95">do_u = do_up

def do_down(self, arg):
    if self.curindex + 1 == len(self.stack):
        print '*** Newest frame'
    else:
        self.curindex = self.curindex + 1
        self.curframe = self.stack[self.curindex][0]
        self.print_stack_entry(self.stack[self.curindex])
        self.lineno = None
</t>
<t tx="edream.110603185221.96">do_d = do_down

def do_step(self, arg):
    self.set_step()
    return 1
</t>
<t tx="edream.110603185221.97">do_s = do_step

def do_next(self, arg):
    self.set_next(self.curframe)
    return 1
</t>
<t tx="edream.110603185221.98">do_n = do_next

def do_return(self, arg):
    self.set_return(self.curframe)
    return 1
</t>
<t tx="edream.110603185221.99">do_r = do_return

def do_continue(self, arg):
    self.set_continue()
    return 1
</t>
<t tx="edream.110603185221.100">do_c = do_cont = do_continue

def do_jump(self, arg):
    if self.curindex + 1 != len(self.stack):
        print "*** You can only jump within the bottom frame"
        return
    try:
        arg = int(arg)
    except ValueError:
        print "*** The 'jump' command requires a line number."
    else:
        try:
            # Do the jump, fix up our copy of the stack, and display the
            # new position
            self.curframe.f_lineno = arg
            self.stack[self.curindex] = self.stack[self.curindex][0], arg
            self.print_stack_entry(self.stack[self.curindex])
        except ValueError, e:
            print '*** Jump failed:', e
</t>
<t tx="edream.110603185221.101">do_j = do_jump

def do_debug(self, arg):
    sys.settrace(None)
    globals = self.curframe.f_globals
    locals = self.curframe.f_locals
    p = Pdb()
    p.prompt = "(%s) " % self.prompt.strip()
    print "ENTERING RECURSIVE DEBUGGER"
    sys.call_tracing(p.run, (arg, globals, locals))
    print "LEAVING RECURSIVE DEBUGGER"
    sys.settrace(self.trace_dispatch)
    self.lastcmd = p.lastcmd
</t>
<t tx="edream.110603185221.102">def do_quit(self, arg):
    self.set_quit()
    return 1
</t>
<t tx="edream.110603185221.103">do_q = do_quit
do_exit = do_quit

def do_EOF(self, arg):
    print
    self.set_quit()
    return 1
</t>
<t tx="edream.110603185221.104">def do_args(self, arg):
    f = self.curframe
    co = f.f_code
    dict = f.f_locals
    n = co.co_argcount
    if co.co_flags &amp; 4: n = n+1
    if co.co_flags &amp; 8: n = n+1
    for i in range(n):
        name = co.co_varnames[i]
        print name, '=',
        if name in dict: print dict[name]
        else: print "*** undefined ***"
</t>
<t tx="edream.110603185221.105">do_a = do_args

def do_retval(self, arg):
    if '__return__' in self.curframe.f_locals:
        print self.curframe.f_locals['__return__']
    else:
        print '*** Not yet returned!'
</t>
<t tx="edream.110603185221.106">do_rv = do_retval

def _getval(self, arg):
    try:
        return eval(arg, self.curframe.f_globals,
                    self.curframe.f_locals)
    except:
        t, v = sys.exc_info()[:2]
        if isinstance(t, str):
            exc_type_name = t
        else: exc_type_name = t.__name__
        print '***', exc_type_name + ':', `v`
        raise
</t>
<t tx="edream.110603185221.107">def do_p(self, arg):
    try:
        print repr(self._getval(arg))
    except:
        pass
</t>
<t tx="edream.110603185221.108">def do_pp(self, arg):
    try:
        pprint.pprint(self._getval(arg))
    except:
        pass
</t>
<t tx="edream.110603185221.109">def do_list(self, arg):
    self.lastcmd = 'list'
    last = None
    if arg:
        try:
            x = eval(arg, {}, {})
            if type(x) == type(()):
                first, last = x
                first = int(first)
                last = int(last)
                if last &lt; first:
                    # Assume it's a count
                    last = first + last
            else:
                first = max(1, int(x) - 5)
        except:
            print '*** Error in argument:', `arg`
            return
    elif self.lineno is None:
        first = max(1, self.curframe.f_lineno - 5)
    else:
        first = self.lineno + 1
    if last is None:
        last = first + 10
    filename = self.curframe.f_code.co_filename
    breaklist = self.get_file_breaks(filename)
    try:
        for lineno in range(first, last+1):
            line = linecache.getline(filename, lineno)
            if not line:
                print '[EOF]'
                break
            else:
                s = `lineno`.rjust(3)
                if len(s) &lt; 4: s = s + ' '
                if lineno in breaklist: s = s + 'B'
                else: s = s + ' '
                if lineno == self.curframe.f_lineno:
                    s = s + '-&gt;'
                print s + '\t' + line,
                self.lineno = lineno
    except KeyboardInterrupt:
        pass
</t>
<t tx="edream.110603185221.110">do_l = do_list

def do_whatis(self, arg):
    try:
        value = eval(arg, self.curframe.f_globals,
                        self.curframe.f_locals)
    except:
        t, v = sys.exc_info()[:2]
        if type(t) == type(''):
            exc_type_name = t
        else: exc_type_name = t.__name__
        print '***', exc_type_name + ':', `v`
        return
    code = None
    # Is it a function?
    try: code = value.func_code
    except: pass
    if code:
        print 'Function', code.co_name
        return
    # Is it an instance method?
    try: code = value.im_func.func_code
    except: pass
    if code:
        print 'Method', code.co_name
        return
    # None of the above...
    print type(value)
</t>
<t tx="edream.110603185221.111">def do_alias(self, arg):
    args = arg.split()
    if len(args) == 0:
        keys = self.aliases.keys()
        keys.sort()
        for alias in keys:
            print "%s = %s" % (alias, self.aliases[alias])
        return
    if args[0] in self.aliases and len(args) == 1:
        print "%s = %s" % (args[0], self.aliases[args[0]])
    else:
        self.aliases[args[0]] = ' '.join(args[1:])
</t>
<t tx="edream.110603185221.112">def do_unalias(self, arg):
    args = arg.split()
    if len(args) == 0: return
    if args[0] in self.aliases:
        del self.aliases[args[0]]
</t>
<t tx="edream.110603185221.113"># Print a traceback starting at the top stack frame.
# The most recently entered frame is printed last;
# this is different from dbx and gdb, but consistent with
# the Python interpreter's stack trace.
# It is also consistent with the up/down commands (which are
# compatible with dbx and gdb: up moves towards 'main()'
# and down moves towards the most recent stack frame).

def print_stack_trace(self):
    try:
        for frame_lineno in self.stack:
            self.print_stack_entry(frame_lineno)
    except KeyboardInterrupt:
        pass
</t>
<t tx="edream.110603185221.114">def print_stack_entry(self, frame_lineno, prompt_prefix=line_prefix):
    frame, lineno = frame_lineno
    if frame is self.curframe:
        print '&gt;',
    else:
        print ' ',
    print self.format_stack_entry(frame_lineno, prompt_prefix)
</t>
<t tx="edream.110603185221.115"># Help methods (derived from pdb.doc)

def help_help(self):
    self.help_h()
</t>
<t tx="edream.110603185221.116">def help_h(self):
    print """h(elp)
Without argument, print the list of available commands.
With a command name as argument, print help about that command
"help pdb" pipes the full documentation file to the $PAGER
"help exec" gives help on the ! command"""
</t>
<t tx="edream.110603185221.117">def help_where(self):
    self.help_w()
</t>
<t tx="edream.110603185221.118">def help_w(self):
    print """w(here)
Print a stack trace, with the most recent frame at the bottom.
An arrow indicates the "current frame", which determines the
context of most commands.  'bt' is an alias for this command."""
</t>
<t tx="edream.110603185221.119">help_bt = help_w

def help_down(self):
    self.help_d()
</t>
<t tx="edream.110603185221.120">def help_d(self):
    print """d(own)
Move the current frame one level down in the stack trace
(to an older frame)."""
</t>
<t tx="edream.110603185221.121">def help_up(self):
    self.help_u()
</t>
<t tx="edream.110603185221.122">def help_u(self):
    print """u(p)
Move the current frame one level up in the stack trace
(to a newer frame)."""
</t>
<t tx="edream.110603185221.123">def help_break(self):
    self.help_b()
</t>
<t tx="edream.110603185221.124">def help_b(self):
    print """b(reak) ([file:]lineno | function) [, condition]
With a line number argument, set a break there in the current
file.  With a function name, set a break at first executable line
of that function.  Without argument, list all breaks.  If a second
argument is present, it is a string specifying an expression
which must evaluate to true before the breakpoint is honored.

The line number may be prefixed with a filename and a colon,
to specify a breakpoint in another file (probably one that
hasn't been loaded yet).  The file is searched for on sys.path;
the .py suffix may be omitted."""
</t>
<t tx="edream.110603185221.125">def help_clear(self):
    self.help_cl()
</t>
<t tx="edream.110603185221.126">def help_cl(self):
    print "cl(ear) filename:lineno"
    print """cl(ear) [bpnumber [bpnumber...]]
With a space separated list of breakpoint numbers, clear
those breakpoints.  Without argument, clear all breaks (but
first ask confirmation).  With a filename:lineno argument,
clear all breaks at that line in that file.

Note that the argument is different from previous versions of
the debugger (in python distributions 1.5.1 and before) where
a linenumber was used instead of either filename:lineno or
breakpoint numbers."""
</t>
<t tx="edream.110603185221.127">def help_tbreak(self):
    print """tbreak  same arguments as break, but breakpoint is
removed when first hit."""
</t>
<t tx="edream.110603185221.128">def help_enable(self):
    print """enable bpnumber [bpnumber ...]
Enables the breakpoints given as a space separated list of
bp numbers."""
</t>
<t tx="edream.110603185221.129">def help_disable(self):
    print """disable bpnumber [bpnumber ...]
Disables the breakpoints given as a space separated list of
bp numbers."""
</t>
<t tx="edream.110603185221.130">def help_ignore(self):
    print """ignore bpnumber count
Sets the ignore count for the given breakpoint number.  A breakpoint
becomes active when the ignore count is zero.  When non-zero, the
count is decremented each time the breakpoint is reached and the
breakpoint is not disabled and any associated condition evaluates
to true."""
</t>
<t tx="edream.110603185221.131">def help_condition(self):
    print """condition bpnumber str_condition
str_condition is a string specifying an expression which
must evaluate to true before the breakpoint is honored.
If str_condition is absent, any existing condition is removed;
i.e., the breakpoint is made unconditional."""
</t>
<t tx="edream.110603185221.132">def help_step(self):
    self.help_s()
</t>
<t tx="edream.110603185221.133">def help_s(self):
    print """s(tep)
Execute the current line, stop at the first possible occasion
(either in a function that is called or in the current function)."""
</t>
<t tx="edream.110603185221.134">def help_next(self):
    self.help_n()
</t>
<t tx="edream.110603185221.135">def help_n(self):
    print """n(ext)
Continue execution until the next line in the current function
is reached or it returns."""
</t>
<t tx="edream.110603185221.136">def help_return(self):
    self.help_r()
</t>
<t tx="edream.110603185221.137">def help_r(self):
    print """r(eturn)
Continue execution until the current function returns."""
</t>
<t tx="edream.110603185221.138">def help_continue(self):
    self.help_c()
</t>
<t tx="edream.110603185221.139">def help_cont(self):
    self.help_c()
</t>
<t tx="edream.110603185221.140">def help_c(self):
    print """c(ont(inue))
Continue execution, only stop when a breakpoint is encountered."""
</t>
<t tx="edream.110603185221.141">def help_jump(self):
    self.help_j()
</t>
<t tx="edream.110603185221.142">def help_j(self):
    print """j(ump) lineno
Set the next line that will be executed."""
</t>
<t tx="edream.110603185221.143">def help_debug(self):
    print """debug code
Enter a recursive debugger that steps through the code argument
(which is an arbitrary expression or statement to be executed
in the current environment)."""
</t>
<t tx="edream.110603185221.144">def help_list(self):
    self.help_l()
</t>
<t tx="edream.110603185221.145">def help_l(self):
    print """l(ist) [first [,last]]
List source code for the current file.
Without arguments, list 11 lines around the current line
or continue the previous listing.
With one argument, list 11 lines starting at that line.
With two arguments, list the given range;
if the second argument is less than the first, it is a count."""
</t>
<t tx="edream.110603185221.146">def help_args(self):
    self.help_a()
</t>
<t tx="edream.110603185221.147">def help_a(self):
    print """a(rgs)
Print the arguments of the current function."""
</t>
<t tx="edream.110603185221.148">def help_p(self):
    print """p expression
Print the value of the expression."""
</t>
<t tx="edream.110603185221.149">def help_pp(self):
    print """pp expression
Pretty-print the value of the expression."""
</t>
<t tx="edream.110603185221.150">def help_exec(self):
    print """(!) statement
Execute the (one-line) statement in the context of
the current stack frame.
The exclamation point can be omitted unless the first word
of the statement resembles a debugger command.
To assign to a global variable you must always prefix the
command with a 'global' command, e.g.:
(Pdb) global list_options; list_options = ['-l']
(Pdb)"""
</t>
<t tx="edream.110603185221.151">def help_quit(self):
    self.help_q()
</t>
<t tx="edream.110603185221.152">def help_q(self):
    print """q(uit) or exit - Quit from the debugger.
The program being executed is aborted."""
</t>
<t tx="edream.110603185221.153">help_exit = help_q

def help_whatis(self):
    print """whatis arg
Prints the type of the argument."""
</t>
<t tx="edream.110603185221.154">def help_EOF(self):
    print """EOF
Handles the receipt of EOF as a command."""
</t>
<t tx="edream.110603185221.155">def help_alias(self):
    print """alias [name [command [parameter parameter ...] ]]
Creates an alias called 'name' the executes 'command'.  The command
must *not* be enclosed in quotes.  Replaceable parameters are
indicated by %1, %2, and so on, while %* is replaced by all the
parameters.  If no command is given, the current alias for name
is shown. If no name is given, all aliases are listed.

Aliases may be nested and can contain anything that can be
legally typed at the pdb prompt.  Note!  You *can* override
internal pdb commands with aliases!  Those internal commands
are then hidden until the alias is removed.  Aliasing is recursively
applied to the first word of the command line; all other words
in the line are left alone.

Some useful aliases (especially when placed in the .pdbrc file) are:

#Print instance variables (usage "pi classInst")
alias pi for k in %1.__dict__.keys(): print "%1.",k,"=",%1.__dict__[k]

#Print instance variables in self
alias ps pi self
"""
</t>
<t tx="edream.110603185221.156">def help_unalias(self):
    print """unalias name
Deletes the specified alias."""
</t>
<t tx="edream.110603185221.157">def help_pdb(self):
    help()
</t>
<t tx="edream.110603185221.158">def lookupmodule(self, filename):

    """Helper function for break/clear parsing -- may be overridden."""

    root, ext = os.path.splitext(filename)
    if ext == '':
        filename = filename + '.py'
    if os.path.isabs(filename):
        return filename
    for dirname in sys.path:
        while os.path.islink(dirname):
            dirname = os.readlink(dirname)
        fullname = os.path.join(dirname, filename)
        if os.path.exists(fullname):
            return fullname
    return None
</t>
<t tx="edream.110603185221.159"></t>
<t tx="edream.110603185221.160"># Simplified interface

def run(statement, globals=None, locals=None):
    Pdb().run(statement, globals, locals)
</t>
<t tx="edream.110603185221.161">def runeval(expression, globals=None, locals=None):
    return Pdb().runeval(expression, globals, locals)
</t>
<t tx="edream.110603185221.162">def runctx(statement, globals, locals):
    # B/W compatibility
    run(statement, globals, locals)
</t>
<t tx="edream.110603185221.163">def runcall(*args):
    return Pdb().runcall(*args)
</t>
<t tx="edream.110603185221.164">def set_trace():
    Pdb().set_trace()
</t>
<t tx="edream.110603185221.165"># Post-Mortem interface

def post_mortem(t):
    p = Pdb()
    p.reset()
    while t.tb_next is not None:
        t = t.tb_next
    p.interaction(t.tb_frame, t)
</t>
<t tx="edream.110603185221.166">def pm():
    post_mortem(sys.last_traceback)
</t>
<t tx="edream.110603185221.167"># Main program for testing

TESTCMD = 'import x; x.main()'

def test():
    run(TESTCMD)</t>
<t tx="edream.110603185221.168"># print help
def help():

    for dirname in sys.path:
        fullname = os.path.join(dirname, 'pdb.doc')
        if os.path.exists(fullname):
            sts = os.system('${PAGER-more} '+fullname)
            if sts: print '*** Pager exit status:', sts
            break
    else:
        print 'Sorry, can\'t find the help file "pdb.doc"',
        print 'along the Python search path'</t>
<t tx="edream.110603185221.169">import bdb,os,types

from Tkinter import *
from WindowList import ListedToplevel
from ScrolledList import ScrolledList

@others</t>
<t tx="edream.110603185221.170">class Idb(bdb.Bdb):
	@others
</t>
<t tx="edream.110603185221.171">def __init__(self, gui):

    self.gui = gui
    bdb.Bdb.__init__(self)</t>
<t tx="edream.110603185221.172">def user_line(self, frame):
	
    if self.in_rpc_code(frame):
        self.set_step()
        return

    message = self.__frame2message(frame)
    self.gui.interaction(message, frame)</t>
<t tx="edream.110603185221.173">def user_exception(self, frame, info):

    if self.in_rpc_code(frame):
        self.set_step()
        return

    message = self.__frame2message(frame)
    self.gui.interaction(message, frame, info)</t>
<t tx="edream.110603185221.174">def in_rpc_code(self, frame):

    if frame.f_code.co_filename.count('rpc.py'):
        return True
    else:
        prev_frame = frame.f_back
        if prev_frame.f_code.co_filename.count('Debugger.py'):
            # Test will catch both Debugger.py and RemoteDebugger.py
            return False
        return self.in_rpc_code(prev_frame)</t>
<t tx="edream.110603185221.175">def __frame2message(self, frame):

    code = frame.f_code
    filename = code.co_filename
    lineno = frame.f_lineno
    basename = os.path.basename(filename)
	
    message = "%s:%s" % (basename, lineno)
    if code.co_name != "?":
        message = "%s: %s()" % (message, code.co_name)

    return message</t>
<t tx="edream.110603185221.176">class Debugger:
	
	vstack = vsource = vlocals = vglobals = None

	@others
</t>
<t tx="edream.110603185221.177">def __init__(self, pyshell, idb=None):

    if idb is None:
        idb = Idb(self)
    self.pyshell = pyshell
    self.idb = idb
    self.frame = None
    self.make_gui()
    self.interacting = 0
</t>
<t tx="edream.110603185221.178">def run(self, *args):
    try:
        self.interacting = 1
        return self.idb.run(*args)
    finally:
        self.interacting = 0
</t>
<t tx="edream.110603185221.179">def close(self, event=None):

    if self.interacting:
        self.top.bell()
        return

    if self.stackviewer:
        self.stackviewer.close(); self.stackviewer = None

    # Clean up pyshell if user clicked debugger control close widget.
    # (Causes a harmless extra cycle through close_debugger() if user
    # toggled debugger from pyshell Debug menu)
    self.pyshell.close_debugger()

    # Now close the debugger control window....
    self.top.destroy()</t>
<t tx="edream.110603185221.180">def make_gui(self):

    pyshell = self.pyshell
    self.flist = pyshell.flist
	&lt;&lt; create top widget &amp; bindings &gt;&gt;
    self.bframe = bframe = Frame(top)
    self.bframe.pack(anchor="w")
    self.buttons = bl = []
    &lt;&lt; create the buttons &gt;&gt;
    self.cframe = cframe = Frame(bframe)
    self.cframe.pack(side="left")
    #
    if not self.vstack:
        self.__class__.vstack = BooleanVar(top)
        self.vstack.set(1)
    self.bstack = Checkbutton(cframe,
        text="Stack", command=self.show_stack, variable=self.vstack)
    self.bstack.grid(row=0, column=0)
    if not self.vsource:
        self.__class__.vsource = BooleanVar(top)
    self.bsource = Checkbutton(cframe,
        text="Source", command=self.show_source, variable=self.vsource)
    self.bsource.grid(row=0, column=1)
    if not self.vlocals:
        self.__class__.vlocals = BooleanVar(top)
        self.vlocals.set(1)
    self.blocals = Checkbutton(cframe,
        text="Locals", command=self.show_locals, variable=self.vlocals)
    self.blocals.grid(row=1, column=0)
    if not self.vglobals:
        self.__class__.vglobals = BooleanVar(top)
    self.bglobals = Checkbutton(cframe,
        text="Globals", command=self.show_globals, variable=self.vglobals)
    self.bglobals.grid(row=1, column=1)
    #
    self.status = Label(top, anchor="w")
    self.status.pack(anchor="w")
    self.error = Label(top, anchor="w")
    self.error.pack(anchor="w", fill="x")
    self.errorbg = self.error.cget("background")
    #
    self.fstack = Frame(top, height=1)
    self.fstack.pack(expand=1, fill="both")
    self.flocals = Frame(top)
    self.flocals.pack(expand=1, fill="both")
    self.fglobals = Frame(top, height=1)
    self.fglobals.pack(expand=1, fill="both")
    #
    if self.vstack.get():
        self.show_stack()
    if self.vlocals.get():
        self.show_locals()
    if self.vglobals.get():
        self.show_globals()</t>
<t tx="edream.110603185221.181">self.bcont = b = Button(bframe, text="Go", command=self.cont)
bl.append(b)
self.bstep = b = Button(bframe, text="Step", command=self.step)
bl.append(b)
self.bnext = b = Button(bframe, text="Over", command=self.next)
bl.append(b)
self.bret = b = Button(bframe, text="Out", command=self.ret)
bl.append(b)
self.bret = b = Button(bframe, text="Quit", command=self.quit)
bl.append(b)

for b in bl:
    b.configure(state="disabled")
    b.pack(side="left")</t>
<t tx="edream.110603185221.182">self.root = root = pyshell.root
self.top = top =ListedToplevel(root)
self.top.wm_title("Debug Control")
self.top.wm_iconname("Debug")
top.wm_protocol("WM_DELETE_WINDOW", self.close)
self.top.bind("&lt;Escape&gt;", self.close)</t>
<t tx="edream.110603185221.183">def interaction(self, message, frame, info=None):
    self.frame = frame
    self.status.configure(text=message)
    #
    if info:
        type, value, tb = info
        try:
            m1 = type.__name__
        except AttributeError:
            m1 = "%s" % str(type)
        if value is not None:
            try:
                m1 = "%s: %s" % (m1, str(value))
            except:
                pass
        bg = "yellow"
    else:
        m1 = ""
        tb = None
        bg = self.errorbg
    self.error.configure(text=m1, background=bg)
    #
    sv = self.stackviewer
    if sv:
        stack, i = self.idb.get_stack(self.frame, tb)
        sv.load_stack(stack, i)
    #
    self.show_variables(1)
    #
    if self.vsource.get():
        self.sync_source_line()
    #
    for b in self.buttons:
        b.configure(state="normal")
    #
    self.top.tkraise()
    self.root.mainloop()
    #
    for b in self.buttons:
        b.configure(state="disabled")
    self.status.configure(text="")
    self.error.configure(text="", background=self.errorbg)
    self.frame = None
</t>
<t tx="edream.110603185221.184">def sync_source_line(self):

    frame = self.frame
    if not frame:
        return

    filename, lineno = self.__frame2fileline(frame)
    if filename[:1] + filename[-1:] != "&lt;&gt;" and os.path.exists(filename):
        self.flist.gotofileline(filename, lineno)</t>
<t tx="edream.110603185221.185">def __frame2fileline(self, frame):

    code = frame.f_code
    filename = code.co_filename
    lineno = frame.f_lineno
    return filename, lineno</t>
<t tx="edream.110603185221.186"></t>
<t tx="edream.110603185221.187">def cont(self):
    self.idb.set_continue()
    self.root.quit()
</t>
<t tx="edream.110603185221.188">def step(self):
    self.idb.set_step()
    self.root.quit()
</t>
<t tx="edream.110603185221.189">def next(self):

    self.idb.set_next(self.frame)
    self.root.quit()
</t>
<t tx="edream.110603185221.190">def ret(self):
    self.idb.set_return(self.frame)
    self.root.quit()
</t>
<t tx="edream.110603185221.191">def quit(self):
    self.idb.set_quit()
    self.root.quit()
</t>
<t tx="edream.110603185221.192"></t>
<t tx="edream.110603185221.193">stackviewer = None

def show_stack(self):

    if not self.stackviewer and self.vstack.get():
        self.stackviewer = sv = StackViewer(self.fstack, self.flist, self)
        if self.frame:
            stack, i = self.idb.get_stack(self.frame, None)
            sv.load_stack(stack, i)
    else:
        sv = self.stackviewer
        if sv and not self.vstack.get():
            self.stackviewer = None
            sv.close()
        self.fstack['height'] = 1
</t>
<t tx="edream.110603185221.194">def show_source(self):

    if self.vsource.get():
        self.sync_source_line()
</t>
<t tx="edream.110603185221.195">def show_frame(self, (frame, lineno)):
    self.frame = frame
    self.show_variables()
</t>
<t tx="edream.110603185221.196">localsviewer = None
globalsviewer = None

def show_locals(self):
    lv = self.localsviewer
    if self.vlocals.get():
        if not lv:
            self.localsviewer = NamespaceViewer(self.flocals, "Locals")
    else:
        if lv:
            self.localsviewer = None
            lv.close()
            self.flocals['height'] = 1
    self.show_variables()
</t>
<t tx="edream.110603185221.197">def show_globals(self):

    gv = self.globalsviewer
    if self.vglobals.get():
        if not gv:
            self.globalsviewer = NamespaceViewer(self.fglobals, "Globals")
    else:
        if gv:
            self.globalsviewer = None
            gv.close()
            self.fglobals['height'] = 1
    self.show_variables()
</t>
<t tx="edream.110603185221.198">def show_variables(self, force=0):

    lv = self.localsviewer
    gv = self.globalsviewer
    frame = self.frame
    if not frame:
        ldict = gdict = None
    else:
        ldict = frame.f_locals
        gdict = frame.f_globals
        if lv and gv and ldict is gdict:
            ldict = None
    if lv:
        lv.load_dict(ldict, force, self.pyshell.interp.rpcclt)
    if gv:
        gv.load_dict(gdict, force, self.pyshell.interp.rpcclt)
</t>
<t tx="edream.110603185221.199"># - Not bound in this class.
# - Just call corresponding idb class.</t>
<t tx="edream.110603185221.200">def set_breakpoint_here(self, filename, lineno):

    self.idb.set_break(filename, lineno)
</t>
<t tx="edream.110603185221.201">def clear_breakpoint_here(self, filename, lineno):
    self.idb.clear_break(filename, lineno)
</t>
<t tx="edream.110603185221.202">def clear_file_breaks(self, filename):
	
    self.idb.clear_all_file_breaks(filename)

</t>
<t tx="edream.110603185221.203">def load_breakpoints(self):

    "Load PyShellEditorWindow breakpoints into subprocess debugger"
    pyshell_edit_windows = self.pyshell.flist.inversedict.keys()
    for editwin in pyshell_edit_windows:
        filename = editwin.io.filename
        try:
            for lineno in editwin.breakpoints:
                self.set_breakpoint_here(filename, lineno)
        except AttributeError:
            continue
</t>
<t tx="edream.110603185221.204">
class StackViewer(ScrolledList):
	@others
</t>
<t tx="edream.110603185221.205">def __init__(self, master, flist, gui):
    ScrolledList.__init__(self, master, width=80)
    self.flist = flist
    self.gui = gui
    self.stack = []
</t>
<t tx="edream.110603185221.206">def load_stack(self, stack, index=None):
    self.stack = stack
    self.clear()
    for i in range(len(stack)):
        frame, lineno = stack[i]
        try:
            modname = frame.f_globals["__name__"]
        except:
            modname = "?"
        code = frame.f_code
        filename = code.co_filename
        funcname = code.co_name
        import linecache
        sourceline = linecache.getline(filename, lineno)
        import string
        sourceline = string.strip(sourceline)
        if funcname in ("?", "", None):
            item = "%s, line %d: %s" % (modname, lineno, sourceline)
        else:
            item = "%s.%s(), line %d: %s" % (modname, funcname,
                                             lineno, sourceline)
        if i == index:
            item = "&gt; " + item
        self.append(item)
    if index is not None:
        self.select(index)
</t>
<t tx="edream.110603185221.207">def popup_event(self, event):
    "override base method"
    if self.stack:
        return ScrolledList.popup_event(self, event)
</t>
<t tx="edream.110603185221.208">def fill_menu(self):
    "override base method"
    menu = self.menu
    menu.add_command(label="Go to source line",
                     command=self.goto_source_line)
    menu.add_command(label="Show stack frame",
                     command=self.show_stack_frame)
</t>
<t tx="edream.110603185221.209">def on_select(self, index):
    "override base method"
    if 0 &lt;= index &lt; len(self.stack):
        self.gui.show_frame(self.stack[index])
</t>
<t tx="edream.110603185221.210">def on_double(self, index):
    "override base method"
    self.show_source(index)
</t>
<t tx="edream.110603185221.211">def goto_source_line(self):
    index = self.listbox.index("active")
    self.show_source(index)
</t>
<t tx="edream.110603185221.212">def show_stack_frame(self):
    index = self.listbox.index("active")
    if 0 &lt;= index &lt; len(self.stack):
        self.gui.show_frame(self.stack[index])
</t>
<t tx="edream.110603185221.213">def show_source(self, index):
    if not (0 &lt;= index &lt; len(self.stack)):
        return
    frame, lineno = self.stack[index]
    code = frame.f_code
    filename = code.co_filename
    if os.path.isfile(filename):
        edit = self.flist.open(filename)
        if edit:
            edit.gotoline(lineno)
</t>
<t tx="edream.110603185221.214">

class NamespaceViewer:
	@others
</t>
<t tx="edream.110603185221.215">def __init__(self, master, title, dict=None):
    width = 0
    height = 40
    if dict:
        height = 20*len(dict) # XXX 20 == observed height of Entry widget
    self.master = master
    self.title = title
    import repr
    self.repr = repr.Repr()
    self.repr.maxstring = 60
    self.repr.maxother = 60
    self.frame = frame = Frame(master)
    self.frame.pack(expand=1, fill="both")
    self.label = Label(frame, text=title, borderwidth=2, relief="groove")
    self.label.pack(fill="x")
    self.vbar = vbar = Scrollbar(frame, name="vbar")
    vbar.pack(side="right", fill="y")
    self.canvas = canvas = Canvas(frame,
                                  height=min(300, max(40, height)),
                                  scrollregion=(0, 0, width, height))
    canvas.pack(side="left", fill="both", expand=1)
    vbar["command"] = canvas.yview
    canvas["yscrollcommand"] = vbar.set
    self.subframe = subframe = Frame(canvas)
    self.sfid = canvas.create_window(0, 0, window=subframe, anchor="nw")
    self.load_dict(dict)
</t>
<t tx="edream.110603185221.216">dict = -1

def load_dict(self, dict, force=0, rpc_client=None):
    if dict is self.dict and not force:
        return
    subframe = self.subframe
    frame = self.frame
    for c in subframe.children.values():
        c.destroy()
    self.dict = None
    if not dict:
        l = Label(subframe, text="None")
        l.grid(row=0, column=0)
    else:
        names = dict.keys()
        names.sort()
        row = 0
        for name in names:
            value = dict[name]
            svalue = self.repr.repr(value) # repr(value)
            # Strip extra quotes caused by calling repr on the (already)
            # repr'd value sent across the RPC interface:
            if rpc_client:
                svalue = svalue[1:-1]
            l = Label(subframe, text=name)
            l.grid(row=row, column=0, sticky="nw")
            l = Entry(subframe, width=0, borderwidth=0)
            l.insert(0, svalue)
            l.grid(row=row, column=1, sticky="nw")
            row = row+1
    self.dict = dict
    # XXX Could we use a &lt;Configure&gt; callback for the following?
    subframe.update_idletasks() # Alas!
    width = subframe.winfo_reqwidth()
    height = subframe.winfo_reqheight()
    canvas = self.canvas
    self.canvas["scrollregion"] = (0, 0, width, height)
    if height &gt; 300:
        canvas["height"] = 300
        frame.pack(expand=1)
    else:
        canvas["height"] = height
        frame.pack(expand=0)
</t>
<t tx="edream.110603185221.217">def close(self):
    self.frame.destroy()
</t>
<t tx="edream.110603185221.218"># The key idea: Idb and bdb use the stack frame to get the source line.</t>
<t tx="edream.110703030027">def destroySelf (self):
	
	self.top.destroy() # 11/7/03</t>
<t tx="edream.110703035301">Corrected crashes in the following plugins due to app.gui reorg:

- script_io_to_body.py 
- mod_spelling.py

Changed several other plugins so they load only if app.gui.guiName == "tkinter".

Converted all .ini files to @silentfile</t>
<t tx="edream.110803170600">from leoGlobals import *
import leoTest

u = leoTest.testUtils()
nodes = 0 ; lines = 0
c = top()
c.clearAllVisited()
v = u.findNodeAnywhere(c,"Plugins &amp; scripts")
after = v.nodeAfterTree()
trace(v,after)
while v and v != after:
	if not v.t.isVisited():
		v.t.setVisited()
		nodes += 1
		lines += len(splitLines(v.bodyString()))
	v = v.threadNext()
	
pages = ((nodes * 10) + lines) / 50
print "nodes,lines,pages",nodes,lines,pages
es("nodes,lines,pages",nodes,lines,pages)</t>
<t tx="edream.111303085447.1">def destroySelf(self):
	
	pass # Nothing more needs to be done once all windows have been destroyed.</t>
<t tx="edream.111303090930"></t>
<t tx="edream.111303091300"></t>
<t tx="edream.111303091857"></t>
<t tx="edream.111303092328">def createColorPanel(self,c):

	"""Create Color panel."""

	trace("not ready yet")</t>
<t tx="edream.111303092328.1">def createComparePanel(self,c):

	"""Create Compare panel."""

	trace("not ready yet")</t>
<t tx="edream.111303092328.2">def createFindPanel(self):

	"""Create a hidden Find panel."""

	return wxFindFrame()</t>
<t tx="edream.111303092328.3">def createFontPanel(self,c):

	"""Create a Font panel."""

	trace("not ready yet")</t>
<t tx="edream.111303092328.4">def createLeoFrame(self,title):
	
	"""Create a new Leo frame."""

	return wxLeoFrame(title)</t>
<t tx="edream.111303092328.5">def createPrefsPanel(self,c):

	"""Create a Prefs panel."""

	return wxLeoPrefs(c)</t>
<t tx="edream.111303092854"></t>
<t tx="edream.111303093843">def setIdleTimeHook (self,idleTimeHookHandler,*args,**keys):
	
	pass # trace(idleTimeHookHandler)
	
</t>
<t tx="edream.111303093843.1">def setIdleTimeHookAfterDelay (self,delay,idleTimeHookHandler,*args,**keys):
	
	trace(delay,idleTimeHookHandler)</t>
<t tx="edream.111303093953.1"></t>
<t tx="edream.111303093953.2">def firstIndex (self):

	return 0</t>
<t tx="edream.111303093953.3">def lastIndex (self):

	return "end"</t>
<t tx="edream.111303093953.4">def moveIndexBackward(self,index,n):

	return index + n
</t>
<t tx="edream.111303093953.5">def moveIndexForward(self,index,n):

	return index -n</t>
<t tx="edream.111303093953.6">def compareIndices (self,t,n1,rel,n2):
	
	val = eval("%d $s %d" % (n1,rel,n2))
	trace(val)
	return val</t>
<t tx="edream.111303093953.7">def getindex(self,text,index):
	
	"""Convert string index of the form line.col into a tuple of two ints."""
	
	val = tuple(map(int,string.split(text.index(index), ".")))
	
	trace(val)
	
	return val</t>
<t tx="edream.111303093953.8"></t>
<t tx="edream.111303093953.9">def getInsertPoint(self,t):

	if t:
		t.bodyCtrl.GetInsertionPoint()
	else:
		return 0</t>
<t tx="edream.111303093953.10">def setInsertPoint (self,t,pos):

	if t and pos: # s_text control doesn't exist.
		trace(pos)
		t.bodyCtrl.SetInsertionPoint(pos)</t>
<t tx="edream.111303093953.11"></t>
<t tx="edream.111303093953.12">def getSelectionRange (self,t):

	return t.bodyCtrl.GetSelection()</t>
<t tx="edream.111303093953.13">def getTextSelection (self,t):
	
	"""Return a tuple representing the selected range of t, a Tk.Text widget.
	
	Return a tuple giving the insertion point if no range of text is selected."""

	# To get the current selection
	sel = t.bodyCtrl.GetSelection()
	if len(sel) == 2:
		return sel
	else:
		# Return the insertion point if there is no selected text.
		insert = t.bodyCtrl.GetInsertionPoint()
		return insert,insert</t>
<t tx="edream.111303093953.14">def setSelectionRange(self,t,n1,n2):

	if t and n1 and n2:
		trace(n1,n2)
		t.bodyCtrl.SetSelection(n1,n2)</t>
<t tx="edream.111303093953.15">def setSelectionRangeWithLength(self,t,start,length):
	
	t.bodyCtrl.SetSelection(n1,start+length)</t>
<t tx="edream.111303093953.16">def setTextSelection (self,t,start,end):

	if not start or not end:
		return
		
	if start &gt; end:
		start,end = end,start
		
	t.bodyCtrl.SetSelection(start,end)</t>
<t tx="edream.111303093953.17"></t>
<t tx="edream.111303093953.18">def getAllText (self,t):
	
	"""Return all the text of Tk.Text t converted to unicode."""
	
	s = t.get("1.0","end")
	if s is None:
		return u""
	else:
		return toUnicode(s,app.tkEncoding)</t>
<t tx="edream.111303093953.19">def getCharAfterIndex (self,t,index):

	ch = t.get(index + "+1c")
	return toUnicode(ch,app.tkEncoding)</t>
<t tx="edream.111303093953.20">def getCharAtIndex (self,t,index):
	ch = t.get(index)
	return toUnicode(ch,app.tkEncoding)</t>
<t tx="edream.111303093953.21">def getCharBeforeIndex (self,t,index):

	ch = t.get(index + "-1c")
	return toUnicode(ch,app.tkEncoding)</t>
<t tx="edream.111303093953.22">def getLineContainingIndex (self,t,index):

	line = t.get(index + " linestart", index + " lineend")
	return toUnicode(line,app.tkEncoding)</t>
<t tx="edream.111303093953.23">def replaceSelectionRangeWithText (self,t,start,end,text):

	t.delete(start,end)
	t.insert(start,text)</t>
<t tx="edream.111303093953.24"></t>
<t tx="edream.111303093953.25">def makeIndexVisible(self,t,index):

	if t and index:
		t.bodyCtrl.ShowPosition(index)
</t>
<t tx="edream.111303095242">class wxLeoMenu (leoMenu.leoMenu):
	
	"""A class that represents a wxPython Leo window."""
	
	@others</t>
<t tx="edream.111303095242.3">def __init__ (self,frame):
	
	# Init the base class.
	leoMenu.leoMenu.__init__(self,frame)
	
	# Init the ivars.
	self.c = frame.c
	self.frame = frame
	
	self.menuDict = {}</t>
<t tx="edream.111303095242.6">def defineOpenWithMenuCallback (self,command):
		
	# The first parameter must be event, and it must default to None.
	def callback(event,command=command):
		try: self.c.openWith(data=command)
		except: print traceback.print_exc()

	trace(`callback`)
	return callback</t>
<t tx="edream.111303100039"></t>
<t tx="edream.111303100039.1"></t>
<t tx="edream.111303100039.6">def insertHeadlineTime (self):
	
	es("insertHeadlineTime not ready yet")
	return

	frame = self ; c = frame.c ; v = c.currentVnode()
	h = v.headString() # Remember the old value.

	if v.edit_text():
		sel1,sel2 = app.gui.getTextSelection(v.edit_text())
		if sel1 and sel2 and sel1 != sel2: # 7/7/03
			v.edit_text().delete(sel1,sel2)
		v.edit_text().insert("insert",c.getTime(body=false))
		frame.idle_head_key(v)

	# A kludge to get around not knowing whether we are editing or not.
	if h.strip() == v.headString().strip():
		es("Edit headline to append date/time")</t>
<t tx="edream.111303100039.7"></t>
<t tx="edream.111303100039.8">def cascade(self):
	
	es("cascade not ready yet")
	return

	x,y,delta = 10,10,10
	for frame in app.windowList:
		top = frame.top
		# Compute w,h
		top.update_idletasks() # Required to get proper info.
		geom = top.geometry() # geom = "WidthxHeight+XOffset+YOffset"
		dim,junkx,junky = string.split(geom,'+')
		w,h = string.split(dim,'x')
		w,h = int(w),int(h)
		# Set new x,y and old w,h
		geom = "%dx%d%+d%+d" % (w,h,x,y)
		frame.setTopGeometry(geom) # frame.top.geometry("%dx%d%+d%+d" % (w,h,x,y))
		# Compute the new offsets.
		x += 30 ; y += 30
		if x &gt; 200:
			x = 10 + delta ; y = 40 + delta
			delta += 10
</t>
<t tx="edream.111303100039.9">def equalSizedPanes(self):
	
	es("equalSizedPanes not ready yet")
	return

	frame = self
	frame.resizePanesToRatio(0.5,frame.secondary_ratio)
</t>
<t tx="edream.111303100039.10">def hideLogWindow (self):
	
	es("hideLogWindow not ready yet")
	return
	
	frame = self
	frame.divideLeoSplitter2(0.99, not frame.splitVerticalFlag)</t>
<t tx="edream.111303100039.11">def minimizeAll(self):
	
	es("minimizeAll not ready yet")
	return

	self.minimize(app.findFrame)
	self.minimize(app.pythonFrame)
	for frame in app.windowList:
		self.minimize(frame)
	
def minimize(self, frame):

	if frame:
		frame.Show(false)</t>
<t tx="edream.111303100039.12"># The key invariant: self.splitVerticalFlag tells the alignment of the main splitter.
def toggleSplitDirection(self):
	
	es("toggleSplitDirection not ready yet")
	return

	# Abbreviations.
	frame = self
	bar1 = self.bar1 ; bar2 = self.bar2
	split1Pane1,split1Pane2 = self.split1Pane1,self.split1Pane2
	split2Pane1,split2Pane2 = self.split2Pane1,self.split2Pane2
	# Switch directions.
	verticalFlag = self.splitVerticalFlag = not self.splitVerticalFlag
	orientation = choose(verticalFlag,"vertical","horizontal")
	app.config.setWindowPref("initial_splitter_orientation",orientation)
	# Reconfigure the bars.
	bar1.place_forget()
	bar2.place_forget()
	self.configureBar(bar1,verticalFlag)
	self.configureBar(bar2,not verticalFlag)
	# Make the initial placements again.
	self.placeSplitter(bar1,split1Pane1,split1Pane2,verticalFlag)
	self.placeSplitter(bar2,split2Pane1,split2Pane2,not verticalFlag)
	# Adjust the log and body panes to give more room around the bars.
	self.reconfigurePanes()
	# Redraw with an appropriate ratio.
	vflag,ratio,secondary_ratio = frame.initialRatios()
	self.resizePanesToRatio(ratio,secondary_ratio)</t>
<t tx="edream.111303101257">def abortEditLabelCommand (self):

	es("abortEditLabelCommand not ready yet")
	return
	
	c = self.c ; v = c.currentVnode ; tree = self.tree
	# trace(v)
	if self.revertHeadline and v.edit_text() and v == self.editVnode:
		
		# trace(`self.revertHeadline`)
		v.edit_text().delete("1.0","end")
		v.edit_text().insert("end",self.revertHeadline)
		tree.idle_head_key(v) # Must be done immediately.
		tree.revertHeadline = None
		tree.select(v)
		if v and len(v.t.joinList) &gt; 0:
			# 3/26/03: changed redraw_now to force_redraw.
			tree.force_redraw() # force a redraw of joined headlines.</t>
<t tx="edream.111303101257.1">def endEditLabelCommand (self):
	
	es("endEditLabelCommand not ready yet")
	return

	c = self.c ; tree = self.tree ; v = self.editVnode

	if v and v.edit_text():
		tree.select(v)

	if v: # Bug fix 10/9/02: also redraw ancestor headlines.
		# 3/26/03: changed redraw_now to force_redraw.
		tree.force_redraw() # force a redraw of joined headlines.

	gui.set_focus(c,c.frame.bodyCtrl) # 10/14/02</t>
<t tx="edream.111303101709">def toggleActivePane(self):
	
	# This can't work from the menu...
	
	es("toggleActivePane not ready yet")
	return

	if self.FindFocus() == self.body.bodyCtrl:
		self.tree.SetFocus()
	else:
		self.body.bodyCtrl.SetFocus()</t>
<t tx="edream.111303103141">def add_command (self,menu,**keys):
	
	label    = keys.get("label")
	callback = keys.get("command")

	if menu:
		id = const(label)
		menu.Append(id,label,label)
		key = (menu,label),
		self.menuDict[key] = id # Remember id 
		# trace(label,callback)
		wx.EVT_MENU(self.frame,id,callback)
	else:
		trace("no menu",label)

</t>
<t tx="edream.111303103141.1">def bind (self,bind_shortcut,callback):
	
	# trace(bind_shortcut,callback)
	
	pass</t>
<t tx="edream.111303103141.2">def delete (self,menu,readItemName):
	
	trace(menu,readItemName)
	
	## return menu.delete(realItemName)
</t>
<t tx="edream.111303103141.3">def delete_range (self,menu,n1,n2):
	
	if not menu:
		trace("no menu")
		return
		
	# trace(n1,n2,menu.GetTitle())
	
	items = menu.GetMenuItems()
	
	if 0: # debugging
		for item in items:
			id = item.GetId()
			item = menu.FindItemById(id)
			trace(item.GetText())
			
	## Doesn't work:  a problem with wxPython.
	
	if len(items) &gt; n1 and len(items) &gt; n2:
		i = n1
		while i &lt;= n2:
			id = items[i].GetId()
			item = menu.FindItemById(id)
			trace("deleting:",item.GetText())
			menu.Delete(id)
			i += 1</t>
<t tx="edream.111303103141.4">def destroy (self,menu):
	
	trace()

	## menu.destroy()</t>
<t tx="edream.111303103254">def defineMenuCallback(self,command,name):
		
	# The first parameter must be event, and it must default to None.
	def callback(event=None,self=self,command=command,label=name):
		self.c.doCommand(command,label,event)

	return callback</t>
<t tx="edream.111303103457"></t>
<t tx="edream.111303103457.2">def createMenuBar(self):
	
	self.menuBar = menuBar = wx.wxMenuBar()

	self.createMenusFromTables()

	self.frame.SetMenuBar(menuBar)</t>
<t tx="edream.111303110018">def new_menu(self,parent,tearoff=0):
	
	return wx.wxMenu()</t>
<t tx="edream.111303111942">def insert_cascade (self,parent,index,label,menu,underline):

	if not parent:
		self.menuBar.append(menu,label)</t>
<t tx="edream.111303111942.1">def add_cascade (self,parent,label,menu,underline):

	"""Create a menu with the given parent menu."""

	if parent:
		# Create a submenu of the parent menu.
		id = const(label)
		parent.AppendMenu(id,label,menu,label)
	else:
		# Create a top-level menu.
		self.menuBar.Append(menu,label)</t>
<t tx="edream.111303121150">def add_separator(self,menu):
	
	if menu:
		menu.AppendSeparator()
	else:
		trace("null menu")</t>
<t tx="edream.111303135410">def setTitle (self,title):

	self.title = title
	self.SetTitle(title) # Call the wx code.</t>
<t tx="edream.111303141147">def signOnWithVersion (self):

	c = self.c
	color = app.config.getWindowPref("log_error_color")
	signon = c.getSignOnLine()
	n1,n2,n3,junk,junk=sys.version_info
	
	es("Leo Log Window...",color=color)
	es(signon)
	es("Python %d.%d.%d wxWindows %s" % (n1,n2,n3,wx.wxVERSION_STRING))
	enl()</t>
<t tx="edream.111303163727.1">def enableMenu (self,menu,name,val):
	
	if not menu:
		trace("no menu",name,val)
		return
	
	realName = self.getRealMenuName(name)
	realName = realName.replace("&amp;","")
	id = menu.FindItem(realName)
	if id:
		item = menu.FindItemById(id)
		val = choose(val,1,0)
		item.Enable(val)
	else:
		trace("no item",name,val)</t>
<t tx="edream.111303163727.2">def disableMenu (self,menu,name):
	
	if not menu:
		trace("no menu",name)
		return
	
	realName = self.getRealMenuName(name)
	realName = realName.replace("&amp;","")
	id = menu.FindItem(realName)
	if id:
		item = menu.FindItemById(id)
		item.Enable(0)
	else:
		trace("no item",name,val)</t>
<t tx="edream.111303163727.3">def setMenuLabel (self,menu,name,label,underline=-1):

	if not menu:
		trace("no menu",name)
		return
		
	if type(name) == type(0):
		# "name" is actually an index into the menu.
		items = menu.GetMenuItems() # GetItemByPosition does not exist.
		if items and len(items) &gt; name :
			id = items[name].GetId()
		else: id = None
	else:
		realName = self.getRealMenuName(name)
		realName = realName.replace("&amp;","")
		id = menu.FindItem(realName)

	if id:
		item = menu.FindItemById(id)
		label = self.getRealMenuName(label)
		label = label.replace("&amp;","")
		# trace(name,label)
		item.SetText(label)
	else:
		trace("no item",name,label)</t>
<t tx="edream.111303171218"># Returning indices...
def getBeforeInsertionPoint (self):
	trace()
	
def getInsertionPoint (self):
	return self.bodyCtrl.GetInsertionPoint()
	
# Returning chars...
def getCharAtInsertPoint (self):
	t = self.bodyCtrl
	pos = t.GetInsertionPoint()
	return t.GetRange(pos,pos+1)

def getCharBeforeInsertPoint (self):
	t = self.bodyCtrl
	pos = t.GetInsertionPoint()
	return t.GetRange(pos-1,pos)

# Setting the insertion point...
def setInsertionPoint (self,index):
	self.bodyCtrl.SetInsertionPoint(index)

def setInsertPointToEnd (self):
	self.bodyCtrl.SetInsertionPointEnd()
	
def setInsertPointToStartOfLine (self,lineNumber):
	trace()</t>
<t tx="edream.111303171218.1">def deleteSelection (self):
	t = self.bodyCtrl
	t.Remove(t.GetSelection())

def getTextSelection (self):
	return self.bodyCtrl.GetSelection()
	
def hasTextSelection (self):
	start,end = self.bodyCtrl.GetSelection()
	return start != end

def selectAllText (self):
	self.bodyCtrl.SetSelection(-1,-1)

def setTextSelection (self,sel):
	self.bodyCtrl.SetSelection(sel)</t>
<t tx="edream.111303171238"># These routines replace most of the former insert/delete and index routines.</t>
<t tx="edream.111303171238.1">def deleteAllText(self):
	self.bodyCtrl.Clear()
	
def deleteCharacter (self,index):
	self.bodyCtrl.Remove(index,index+1)
	
def deleteLine (self,lineNumber): # zero based line number.
	t = self.bodyCtrl
	pos1 = t.XYToPosition(lineNumber)
	n = t.GetLineLength(lineNumber)
	t.Remove(pos1,pos1 + n)

def deleteLines (self,lineNumber,numberOfLines): # zero based line number.
	t = self.bodyCtrl
	pos1 = t.XYToPosition(lineNumber)
	pos2 = t.XYToPosition(lineNumber+numberOfLine-1)
	n = t.GetLineLength(lineNumber+numberOfLine-1)
	t.Remove(pos1,pos2 + n)

def deleteRange (self,index1,index2):
	self.bodyCtrl.Remove(index1,index2)</t>
<t tx="edream.111303171238.2">def getAllText (self):
	return self.bodyCtrl.GetValue()
	
def getCharAtIndex (self,index):
	return self.bodyCtrl.GetRange(index,index+1)

def getInsertLines (self):
	trace()

def getSelectionAreas (self):
	trace()

def getSelectionLines (self):
	trace()
	
def getTextRange(self,n1,n2):
	return self.bodyCtrl.GetRange(n1,n2)</t>
<t tx="edream.111303171238.3">def insertAtEnd (self,s):

	return self.bodyCtrl.AppendText(s)
	
def insertAtInsertPoint (self,s):
	
	self.bodyCtrl.WriteText(s)</t>
<t tx="edream.111303171238.4">def setSelectionAreas (self,before,sel,after):

	trace()</t>
<t tx="edream.111303184347">@ The wxWindows menu code has problems:  changes do not take effect immediately.</t>
<t tx="edream.111303201144.6">### self.scanForTabWidth(v)

### incremental = undoType not in ("Cut","Paste") and not self.forceFullRecolorFlag
c.recolor()
###self.forceFullRecolorFlag = false</t>
<t tx="edream.111303201144.7">redraw_flag = false

c.beginUpdate()

# Update dirty bits.
if not v.isDirty() and v.setDirty(): # Sets all cloned and @file dirty bits
	redraw_flag = true
	
# Update icons.
val = v.computeIcon()
if val != v.iconVal:
	v.iconVal = val
	redraw_flag = true

c.endUpdate(redraw_flag) # redraw only if necessary</t>
<t tx="edream.111303202917"></t>
<t tx="edream.111303202917.1">def getColorizer(self):

	return self.colorizer

def recolor(self,v,incremental=false):

	if self.use_coloring:
		self.colorizer.colorize(v,incremental)

def recolor_now(self,v,incremental=false):

	if self.use_coloring:
		self.colorizer.colorize(v,incremental)
	
def recolor_range(self,v,leading,trailing):

	if self.use_coloring:
		self.colorizer.recolor_range(v,leading,trailing)
	
def updateSyntaxColorer (self,v):

	return self.colorizer.updateSyntaxColorer(v)</t>
<t tx="edream.111303204025"></t>
<t tx="edream.111303204025.1">def adjustIndex (self,index,offset):
	
	try:
		column, row = index
		return column, row + offset
	except:
		return index + offset</t>
<t tx="edream.111303204025.2">def compareIndices(self,i,rel,j):
	
	try:
		y1,x1 = i
		y2,x2 = j
		pos1 = self.bodyCtrl.XYToPosition(x1,y1)
		pos2 = self.bodyCtrl.XYToPosition(x2,y2)
	except:
		pos1 = i
		pos2 = j
	
	val = eval("%d %s %d" % (pos1,rel,pos2))
	trace(i,j,rel,val)
	return val</t>
<t tx="edream.111303204025.3">def convertRowColumnToIndex (self,row,column):
	
	index = self.bodyCtrl.XYToPosition(column,row-1)
	# trace(column,row,"-&gt;",index)
	return index</t>
<t tx="edream.111303204025.4">def convertIndexToRowColumn (self,index):
	
	x,y = self.bodyCtrl.PositionToXY(index)
	# trace(index,"-&gt;",y+1,x)
	return y+1,x</t>
<t tx="edream.111303204025.5">def getImageIndex (self,image):
	
	trace(image)</t>
<t tx="edream.111303204517"></t>
<t tx="edream.111303204836"></t>
<t tx="edream.111303205442">@ The colorizer isn't ready for prime time:
	
	- It's too slow when selecting long text
	- The screen flashes too much
	- The tkColorToWxColor routine needs much more work.
	
wxLeo should use wxStc rather than wxText!</t>
<t tx="edream.111303205611">def tag_add (self,tagName,index1,index2):
	
	# trace(tagName,index1,index2)

	style = self.styles.get(tagName)
	if style:
		self.bodyCtrl.SetStyle(index1,index2,style)</t>
<t tx="edream.111303205611.1">def tag_bind (self,tagName,event,callback):
	
	# trace(tagName,event,callback)
	pass
</t>
<t tx="edream.111303205611.2">def tag_configure (self,colorName,**keys):
	
	foreground = keys.get("foreground")
	background = keys.get("background")

	if foreground:
		fcolor = self.tkColorToWxColor (foreground)
		bcolor = self.tkColorToWxColor (background)
		if fcolor and bcolor:
			# trace(colorName,foreground,keys)
			style = wx.wxTextAttr(fcolor,bcolor)
			self.styles[colorName] = style
		elif fcolor:
			style = wx.wxTextAttr(fcolor)
			self.styles[colorName] = style</t>
<t tx="edream.111303205611.3">def tag_delete(self,tagName):

	if tagName == "keyword": # A kludge.

		# trace(tagName)
		style = wx.wxTextAttr(wx.wxBLACK)
		last = self.maxWxIndex()
		
		if 1: # This may cause the screen flash.
			self.bodyCtrl.SetStyle(0,last,style)</t>
<t tx="edream.111303205611.4">def tag_remove (self,tagName,index1,index2):
	
	trace(tagName,index1,index2)
	pass
</t>
<t tx="edream.111403080609">def maxWxIndex (self):
	
	return self.bodyCtrl.GetLastPosition()</t>
<t tx="edream.111403082513">def tkColorToWxColor (self, color):
	
	d = {
		"red": wx.wxRED,
		"blue": wx.wxBLUE,
		"#00aa00": wx.wxGREEN,
		"firebrick3": wx.wxRED }
		
	return d.get(color)</t>
<t tx="edream.111403090242">def drawIcon(self,v,x,y):
	trace(v)

# Scrolling... 
def scrollTo(self,v):
	trace()

def idle_scrollTo(self,v):
	pass</t>
<t tx="edream.111403090242.1">def editLabel(self,v):
	pass

def editVnode(self):
	pass

def endEditLabel(self):
	pass
	
def setEditVnode(self,v):
	pass

def setNormalLabelState(self,v):
	pass

def OnActivateHeadline(self,v):
	trace()</t>
<t tx="edream.111403093253">The new code now works with the new reorg.  This means that wxLeo is using all the code in Leo's core.

In particular:

- wxLeo creates all menus using the base leoMenu class.
- wxLeo uses all commands in the Commands class.
- wxLeoFrame contains only gui-dependent commands.

The syntax colorer is working in demo mode.  Almost certainly wxLeo should use a better control than wxText.</t>
<t tx="edream.111403093253.1"></t>
<t tx="edream.111403093559">def focus_get(self):
	
	return self.FindFocus()</t>
<t tx="edream.111403093559.1">def getFont(self):
	trace()

def setFont(self,font):
	trace()</t>
<t tx="edream.111403104835">def getWildcardList (self,filetypes):
	
	"""Create a wxWindows wildcard string for open/save dialogs."""

	if not filetypes:
		return "*.leo"

	if 1: # Too bad: this is sooo wimpy.
			a,b = filetypes[0] 
			return b

	else: # This _sometimes_ works: wxWindows is driving me crazy!

		# wildcards = ["%s (%s)" % (a,b) for a,b in filetypes]
		wildcards = ["%s" % (b) for a,b in filetypes]
		wildcard = "|".join(wildcards)
		trace(wildcard)
		return wildcard</t>
<t tx="edream.111403135745">def set_ivars (self,c):
	
	"""Init the commander ivars from the find panel."""
	
	trace()

	# N.B.: separate c.ivars are much more convenient than a dict.
	for key in self.intKeys:
		key = key + "_flag"
		data = self.dict.get(key)
		if data:
			box,id = data
			val = box.GetValue()
			#trace(key,val)
			setattr(c,key,val)
		else:
			#trace("no data",key)
			setattr(c,key,false)

	fp = self.findPanel
	c.find_text = fp.findText.GetValue()
	c.change_text = fp.changeText.GetValue()</t>
<t tx="edream.111403141810">def initialRatios (self):

	config = app.config
	s = config.getWindowPref("initial_splitter_orientation")
	verticalFlag = s == None or (s != "h" and s != "horizontal")
	
	# Tweaked for tk.  Other tweaks may be best for wx.
	if verticalFlag:
		r = config.getFloatWindowPref("initial_vertical_ratio")
		if r == None or r &lt; 0.0 or r &gt; 1.0: r = 0.5
		r2 = config.getFloatWindowPref("initial_vertical_secondary_ratio")
		if r2 == None or r2 &lt; 0.0 or r2 &gt; 1.0: r2 = 0.8
	else:
		r = config.getFloatWindowPref("initial_horizontal_ratio")
		if r == None or r &lt; 0.0 or r &gt; 1.0: r = 0.3
		r2 = config.getFloatWindowPref("initial_horizontal_secondary_ratio")
		if r2 == None or r2 &lt; 0.0 or r2 &gt; 1.0: r2 = 0.8

	return verticalFlag,r,r2</t>
<t tx="edream.111403151611">def bringToFront (self,window):
	
	if window.IsIconized():
		window.Maximize()
	window.Raise()
	window.Show(true)</t>
<t tx="edream.111403151611.1">def bringToFront (self):
	
	app.gui.bringToFront(self)
	self.c = top()
	self.init(self.c)
	self.findPanel.findText.SetFocus()
	self.findPanel.findText.SetSelection(-1,-1)</t>
<t tx="edream.111503074302">sizer = wx.wxBoxSizer(wx.wxVERTICAL)
sizer.Add(self.findPanel)
self.SetAutoLayout(true)# tell dialog to use sizer
self.SetSizer(sizer) # actually set the sizer
sizer.Fit(self)# set size to minimum size as calculated by the sizer
sizer.SetSizeHints(self)# set size hints to honour mininum size</t>
<t tx="edream.111503085739">for name,command in (
	("changeButton",self.changeButton),
	("changeAllButton",self.changeAllButton),
	("changeThenFindButton",self.changeThenFindButton),
	("findButton",self.findButton),
	("findAllButton",self.findAllButton)):
		
	def eventHandler(event,command=command):
		# trace(command)
		command()

	id = const_dict.get(name)
	assert(id)
	wx.EVT_BUTTON(self,id,eventHandler)</t>
<t tx="edream.111503085739.1">textKeys = ["find_text","change_text"]
keys = textKeys[:]
for item in self.intKeys:
	keys.append(item)

for name in keys:

	if name not in textKeys:
		name += "_flag"

	def eventHandler(event,self=self,name=name):
		box = event.GetEventObject()
		val = box.GetValue()
		# trace(name,val)
		setattr(self.c,name,val)

	id = const_dict.get(name)
	if id:
		if name in textKeys:
			wx.EVT_TEXT(self,id,eventHandler)
		else:
			wx.EVT_CHECKBOX(self,id,eventHandler)</t>
<t tx="edream.111503091617">def init_s_text (self,s):
	
	c = self.c
	t = self.s_text # the dummy widget

	# Set the text for searching.
	t.text = s
	
	# Set the insertion point.
	if c.reverse_flag:
		t.SetInsertionPointEnd()
	else:
		t.SetInsertionPoint(0)
	return t</t>
<t tx="edream.111503093140">class wxSearchWidget:

	"""A dummy widget class to pass to Leo's core find code."""

	@others</t>
<t tx="edream.111503093522">def gui_search (self,t,find_text,index,
	stopindex,backwards,regexp,nocase):
		
	trace(index,stopindex,backwards,regexp,nocase)
	
	s = t.text # t is the dummy text widget
	
	if index is None:
		index = 0

	pos = s.find(find_text,index)

	if pos == -1:
		pos = None
	
	return pos</t>
<t tx="edream.111503094014">def __init__ (self):
	
	self.insertPoint = 0
	self.selection = 0,0
	self.bodyCtrl = self
	self.body = self
	self.text = None</t>
<t tx="edream.111503094014.1"># Simulating wxWindows calls (upper case)
def SetSelection(self,n1,n2):
	self.selection = n1,n2
	
# Others...
def deleteSelection (self):
	self.selection = 0,0

def getTextSelection (self):
	return self.selection
	
def hasTextSelection (self):
	start,end = self.selection
	return start != end

def selectAllText (self):
	self.selection = 0,-1

def setTextSelection (self,sel):
	try:
		start,end = sel
		self.selection = start,end
	except:
		self.selection = sel,sel</t>
<t tx="edream.111503094322"># Simulating wxWindows calls (upper case)
def GetInsertionPoint (self):
	return self.insertPoint

def SetInsertionPoint (self,index):
	self.insertPoint = index
	
def SetInsertionPointEND (self,index):
	self.insertPoint = len(self.text)+1

# Returning indices...
def getBeforeInsertionPoint (self):
	trace()

# Returning chars...
def getCharAtInsertPoint (self):
	trace()

def getCharBeforeInsertPoint (self):
	trace()

# Setting the insertion point...
def setInsertPointToEnd (self):
	self.insertPoint = -1
	
def setInsertPointToStartOfLine (self,lineNumber):
	trace()</t>
<t tx="edream.111503105816">def injectCallbacks(self):
	
	import leoNodes
	
	# Some callback is required.
	def doNothingCallback(*args,**keys):
		pass

	for name in (
		"OnBoxClick","OnDrag","OnEndDrag",
		"OnHeadlineClick","OnHeadlineRightClick","OnHeadlineKey",
		"OnHyperLinkControlClick","OnHyperLinkEnter","OnHyperLinkLeave",
		"OnIconClick","OnIconDoubleClick","OnIconRightClick"):

		# trace(f)
		funcToMethod(doNothingCallback,leoNodes.vnode,name=name)</t>
<t tx="edream.111503110300">At this point, Leo is useable.

What I did:

- Added use_coloring ivar to the wxLeoFrame class.  The body text is syntax colored only if this is true.
	This is set to false at present because the default colors are very poor.
    Also, coloring causes the body pane to scroll for large text.  These are minor problems...

- Got find panel working.  This required creating dummy wxSearchWidget class.  Probably _all_ the search code should be in the base leoFind class, but that would making supporting regexp searches harder.

- Simplified the event handlers in the find panel.  We can use tables to _create_ the event handlers.

- Solved the problem with selecting new nodes: we must lock out further event handling once an event handler starts.  In particular, the syntax colorer generates a lot of other events.  This also prevents the outline from being marked dirty when a new node is selected.

- Added code to insject do-nothing callbacks into vnode class.  This is required by the syntax colorer.

Later:

- Completed Find panel.

- Made sure Leo prompts when closing a window.
	- The new code is very simple: it just calls app.closeLeoWindow.
		- Removed some gui dependencies from the app.finishQuit logic.
		  (They are now in the app.tkinterGui.destroySelf routine.)

- Implemented the wx gui dialog code.
	- Only the number dialog remains...

Very little remains to be done, and nothing big.</t>
<t tx="edream.111503111146"></t>
<t tx="edream.111503111350"></t>
<t tx="edream.111503133933.2"># The var names must match the names in leoFind class.
table = (
	("Entire Outline","entire-outline",wx.wxRB_GROUP),
	("Suboutline Only","suboutline_only_flag",0),  
	("Node Only","node_only_flag",0),    
	("Selection Only","selection-only",0))
	
for label,var,group in table:

	if var: id = const(var)
	else:   id = const("entire-outline")
		
	box = wx.wxRadioButton(self,id,label,
		wx.wxDefaultPosition,(100,25),
		group,wx.wxDefaultValidator,"group2")

	col3Sizer.Add(box,0,wx.wxBORDER | wx.wxLEFT,20)
	
	self.frame.dict[var] = box,id</t>
<t tx="edream.111503133933.3"># The var names must match the names in leoFind class.
table = (
	("search_headline_flag","Search Headline Text"),
	("search_body_flag","Search Body Text"),
	("mark_finds_flag","Mark Finds"),
	("mark_changes_flag","Mark Changes"))

for var,label in table:
	
	id = const(var)
	box = wx.wxCheckBox(self,id,label,
		wx.wxDefaultPosition,(100,25),
		0,wx.wxDefaultValidator,"")

	col4Sizer.Add(box,0,wx.wxBORDER | wx.wxLEFT,20)
	self.frame.dict[var] = box,id</t>
<t tx="edream.111503204508">def init (self,c):

	"""Init the find panel from c.
	
	(The opposite of set_ivars)."""

	# N.B.: separate c.ivars are much more convenient than a dict.
	for key in self.intKeys:
		key = key + "_flag"
		val = getattr(c,key)
		data = self.dict.get(key)
		if data:
			box,id = data
			box.SetValue(val)
			# trace(key,`val`)

	self.findPanel.findText.SetValue(c.find_text)
	self.findPanel.changeText.SetValue(c.change_text)</t>
<t tx="edream.111503211508">def onCloseFindFrame (self,event):

	if event.CanVeto():
		event.Veto()
		self.Hide()</t>
<t tx="edream.111503213533">def destroySelf(self):
	
	self.Destroy()</t>
<t tx="edream.111503213733">def destroySelf (self):
	
	self.Destroy()</t>
<t tx="edream.111603104327"></t>
<t tx="edream.111603112846"></t>
<t tx="edream.111603112846.1">@ Entries in the table passed to createOpenWithMenuFromTable are
tuples of the form (commandName,shortcut,data).

- command is one of "os.system", "os.startfile", "os.spawnl", "os.spawnv" or "exec".
- shortcut is a string describing a shortcut, just as for createMenuItemsFromTable.
- data is a tuple of the form (command,arg,ext).

Leo executes command(arg+path) where path is the full path to the temp file.
If ext is not None, the temp file has the given extension.
Otherwise, Leo computes an extension based on the @language directive in effect.
@c

def createOpenWithMenuFromTable (self,table):
	
	trace("Not ready yet")
	
	return ### Not ready yet

	app.openWithTable = table # Override any previous table.
	# Delete the previous entry.
	parent = self.getMenu("File")
	label = self.getRealMenuName("Open &amp;With...")
	amp_index = label.find("&amp;")
	label = label.replace("&amp;","")
	try:
		index = parent.index(label)
		parent.delete(index)
	except:
		try:
			index = parent.index("Open With...")
			parent.delete(index)
		except: return
	# Create the "Open With..." menu.
	openWithMenu = Tkinter.Menu(parent,tearoff=0)
	self.setMenu("Open With...",openWithMenu)
	parent.insert_cascade(index,label=label,menu=openWithMenu,underline=amp_index)
	# Populate the "Open With..." menu.
	shortcut_table = []
	for triple in table:
		if len(triple) == 3: # 6/22/03
			shortcut_table.append(triple)
		else:
			es("createOpenWithMenuFromTable: invalid data",color="red")
			return
			
	# for i in shortcut_table: print i
	self.createMenuItemsFromTable("Open &amp;With...",shortcut_table,openWith=1)
</t>
<t tx="edream.111603130528">A number of changes made to accomodate the new reorg...</t>
<t tx="edream.111603213219">class wxLeoTree (leoFrame.leoTree):
	@others
</t>
<t tx="edream.111603213219.1">def __init__ (self,frame,parentFrame):

	# Init the base class.
	leoFrame.leoTree.__init__(self,frame)

	self.treeCtrl = wx.wxTreeCtrl(parentFrame,
		const("cTreeCtrl"),
		wx.wxDefaultPosition, wx.wxDefaultSize,
		wx.wxTR_HAS_BUTTONS | wx.wxTR_EDIT_LABELS, wx.wxDefaultValidator,
		"treeCtrl")

	self.root_id = None
	
	&lt;&lt; declare event handlers &gt;&gt;</t>
<t tx="edream.111603213329">id = const("cTreeCtrl")

wx.EVT_TREE_KEY_DOWN        (self.treeCtrl,id,self.onTreeKeyDown) # Control keys do not fire this event.
wx.EVT_TREE_SEL_CHANGED     (self.treeCtrl,id,self.onTreeChanged)
wx.EVT_TREE_SEL_CHANGING    (self.treeCtrl,id,self.onTreeChanging)
wx.EVT_TREE_BEGIN_DRAG      (self.treeCtrl,id,self.onTreeBeginDrag)
wx.EVT_TREE_END_DRAG        (self.treeCtrl,id,self.onTreeEndDrag)
wx.EVT_TREE_BEGIN_LABEL_EDIT(self.treeCtrl,id,self.onTreeBeginLabelEdit)
wx.EVT_TREE_END_LABEL_EDIT  (self.treeCtrl,id,self.onTreeEndLabelEdit)

 
wx.EVT_TREE_ITEM_COLLAPSED  (self.treeCtrl,id,self.onTreeCollapsed)
wx.EVT_TREE_ITEM_EXPANDED   (self.treeCtrl,id,self.onTreeExpanded)

wx.EVT_TREE_ITEM_COLLAPSING (self.treeCtrl,id,self.onTreeCollapsing)
wx.EVT_TREE_ITEM_EXPANDING  (self.treeCtrl,id,self.onTreeExpanding)</t>
<t tx="edream.111603221005">def expandAllAncestors(self,v):
	trace()</t>
<t tx="edream.111603221343.1"># Warning: do not try to "optimize" this by returning if v==tree.currentVnode.

def select (self,v,updateBeadList=true):

	c = self.c ; frame = c.frame ; body = frame.bodyCtrl
	old_v = c.currentVnode()

	if not doHook("unselect1",c=c,new_v=v,old_v=old_v):
		if 0: ## Not ready yet.
			&lt;&lt; unselect the old node &gt;&gt;
	else: old_body = u""

	doHook("unselect2",c=c,new_v=v,old_v=old_v)
	
	if not doHook("select1",c=c,new_v=v,old_v=old_v):
		&lt;&lt; select the new node &gt;&gt;
		if v and v != old_v: # 3/26/03: Suppress duplicate call.
			try: # may fail during initialization
				self.idle_scrollTo(v)
			except: pass
		&lt;&lt; update c.beadList or c.beadPointer &gt;&gt;
		&lt;&lt; update c.visitedList &gt;&gt;

	&lt;&lt; set the current node and redraw &gt;&gt;
	doHook("select2",c=c,new_v=v,old_v=old_v)
	doHook("select3",c=c,new_v=v,old_v=old_v)
</t>
<t tx="edream.111603221343.3"># Remember the position of the scrollbar before making any changes.
yview = body.yview()
insertSpot = c.frame.body.getInsertionPoint()

# Remember the old body text
old_body = body.getAllText()

if old and old != v and old.edit_text():
	old.t.scrollBarSpot = yview
	old.t.insertSpot = insertSpot
</t>
<t tx="edream.111603221343.4">if 0: # Done in event handler??

	frame.setWrap(v)

	# Delete only if necessary: this may reduce flicker slightly.
	s = v.t.bodyString
	s = toUnicode(s,"utf-8")
	old_body = toUnicode(old_body,"utf-8")
	if old_body != s:
		body.delete("1.0","end")
		body.insert("1.0",s)

	# We must do a full recoloring: we may be changing context!
	self.frame.body.recolor_now(v)

	if v and v.t.scrollBarSpot != None:
		first,last = v.t.scrollBarSpot
		body.yview("moveto",first)

	if v.t.insertSpot != None: # 9/21/02: moved from c.selectVnode
		c.frame.bodyCtrl.mark_set("insert",v.t.insertSpot)
		c.frame.bodyCtrl.see(v.t.insertSpot)
	else:
		c.frame.bodyCtrl.mark_set("insert","1.0")</t>
<t tx="edream.111603221343.5">if updateBeadList:
	
	if c.beadPointer &gt; -1:
		present_v = c.beadList[c.beadPointer]
	else:
		present_v = None
	
	if v != present_v:
		# Replace the tail of c.beadList by c and make c the present node.
		# print "updating c.beadList"
		c.beadPointer += 1
		c.beadList[c.beadPointer:] = []
		c.beadList.append(v)
		
	# trace(c.beadPointer,v,present_v)</t>
<t tx="edream.111603221343.6"># Make v the most recently visited node on the list.
if v in c.visitedList:
	c.visitedList.remove(v)
	
c.visitedList.insert(0,v)</t>
<t tx="edream.111603221343.7">self.setCurrentVnode(v)

if 0: ## Not ready yet
	self.setSelectedLabelState(v)
	self.scanForTabWidth(v) # 9/13/02 #GS I believe this should also get into the select1 hook.

app.gui.set_focus(c,c.frame.bodyCtrl)</t>
<t tx="edream.111603222048">def bind (self,bind_shortcut,callback):
	
	pass # later.</t>
<t tx="edream.111703103908"></t>
<t tx="edream.111703103908.2">def leoHelp (self):
	
	es("leoHelp not ready yet")
	
	return ##
	
	file = os.path.join(app.loadDir,"..","doc","sbooks.chm")
	file = toUnicode(file,app.tkEncoding) # 10/20/03

	if os.path.exists(file):
		os.startfile(file)
	else:	
		answer = app.gui.runAskYesNoDialog(
			"Download Tutorial?",
			"Download tutorial (sbooks.chm) from SourceForge?")

		if answer == "yes":
			try:
				if 0: # Download directly.  (showProgressBar needs a lot of work)
					url = "http://umn.dl.sourceforge.net/sourceforge/leo/sbooks.chm"
					import urllib
					self.scale = None
					urllib.urlretrieve(url,file,self.showProgressBar)
					if self.scale:
						self.scale.destroy()
						self.scale = None
				else:
					url = "http://prdownloads.sourceforge.net/leo/sbooks.chm?download"
					import webbrowser
					os.chdir(app.loadDir)
					webbrowser.open_new(url)
			except:
				es("exception dowloading sbooks.chm")
				es_exception()</t>
<t tx="edream.111703103908.3">def showProgressBar (self,count,size,total):

	# trace("count,size,total:" + `count` + "," + `size` + "," + `total`)
	if self.scale == None:
		&lt;&lt; create the scale widget &gt;&gt;
	self.scale.set(count*size)
	self.scale.update_idletasks()</t>
<t tx="edream.111703103908.4">Tk = Tkinter
top = Tk.Toplevel()
top.title("Download progress")
self.scale = scale = Tk.Scale(top,state="normal",orient="horizontal",from_=0,to=total)
scale.pack()
top.lift()</t>
<t tx="edream.111803100242">"""If a headline starts with @rst &lt;filename&gt;, double-clicking on it will 
write a file in outline order, with the headlines converted to reStructuredText 
section headings.

If the name of the &lt;filename&gt; has the extension .html, .htm or .tex, and if you have
docutils installed, it will generate HTML or LaTeX, respectively."""

# By Josef Dalcolmo: contributed under the same licensed as Leo.py itself.

# EKR: The code now lets other plugins handle @folder and @url nodes.

from leoPlugins import *
from leoGlobals import *

import os

&lt;&lt; about this plugin &gt;&gt;
&lt;&lt; change log &gt;&gt;

@others

# Register the handlers...
registerHandler("icondclick1",onIconDoubleClick)
	
__version__ = "1.5" # Set version for the plugin handler.
plugin_signon(__name__)</t>
<t tx="edream.111803100242.1">@ This plugin writes out @rst nodes as a reStructuredText file.

If the filename ends in .html, .htm or .tex and if you have docutils_ (a Python
module) installed, then it will be written as HTML or LaTeX, respectively. The HTML converter is far
from bug-free, but remember, docutils is alpha software. (Perhaps a future
version will allow automatic translation to other formats, like OpenOffice.org
as well).

Headlines are translated into reStructuredText headlines, e.g. underlined
depending on the level and empty line separated from body text otherwise, text
is written as it is. The "#" character is not used for underlining, so it may
be used for a title as in::

	#####
	Title
	#####

Otherwise, section underlining is discouraged, since it is automatically generated.

.. _docutils: http://docutils.sourceforge.net</t>
<t tx="edream.111803100242.2">@ Change log:

- New tree types: @rst has been added.

- EKR: The code now lets other plugins handle @folder and @url nodes.

- HTML generation: @rst nodes can now generate HTML, if Python docutils_ are
  installed. Simply give the filename an extension .htm or .html. You can try
  this out by renaming the filename in this @rst tree.

- underlines: I changed the order of the underline characters again. The "&gt;" is
  doesn't really look good as an underline in my opinion, so I moved it to a very
  low level.

- JD 2003-03-10 (rev 1.3): some more corrections to the unicode-&gt; encoding translation.
  No only check for missing docutils (doesn't mask other errors any more).

- JD 2003-03-11 (rev 1.4): separated out the file launching code to a different pluging.

- 2003-11-02 Added generation of LaTeX files, just make the extension of the filename '.tex'. --Timo Honkasalo</t>
<t tx="edream.111803100242.3"># by Josef Dalcolmo 2003-01-13
#
# this does not check for proper filename syntax.
# path is the current dir, or the place @folder points to
# this should probably be changed to @path or so.

def onIconDoubleClick(tag,keywords):

	v = keywords.get("v")
	c = keywords.get("c")
	h = v.headString().strip()
	if match_word(h,0,"@rst"):
		fname = h[5:]
		ext = os.path.splitext(fname)[1].lower()
		if ext in ('.htm','.html','.tex'):
			&lt;&lt; write rST as HTML/LaTeX &gt;&gt;
		else:
			&lt;&lt; write rST file &gt;&gt;
</t>
<t tx="edream.111803100242.4">try:
	import docutils
except ImportError:
	docutils = None
	es('HTML/LaTeX generation requires docutils')

if docutils:
	import StringIO
	rstFile = StringIO.StringIO()
	writeTreeAsRst(rstFile, fname, v, c)
	rstText = rstFile.getvalue()
	# Set the writer and encoding for the converted file
	if ext in ('.html','.htm'):
		writer='html'
		enc="utf-8"
	else:
		writer='latex'
		enc="iso-8859-1"
	&lt;&lt; convert rST to HTML/LaTeX &gt;&gt;
	convertedFile = file(fname,'w')
	convertedFile.write(output)
	convertedFile.close()
	rstFile.close()
	es('written: '+str(fname))</t>
<t tx="edream.111803100242.5"># this code snipped has been taken from code contributed by Paul Paterson 2002-12-05
from docutils.core import Publisher
from docutils.io import StringOutput, StringInput

pub = Publisher()
# Initialize the publisher
pub.source = StringInput(source=rstText)
pub.destination = StringOutput(pub.settings, encoding=enc)
pub.set_reader('standalone', None, 'restructuredtext')
pub.set_writer(writer)
output = pub.publish()</t>
<t tx="edream.111803100242.6">rstFile = file(fname,'w')
writeTreeAsRst(rstFile, fname, v, c)
rstFile.close()
es('written: '+str(fname))</t>
<t tx="edream.111803100242.7">def writeTreeAsRst(rstFile, fname, vnode, c):
	'Writes the tree under vnode to the file rstFile (fname is the filename)'
	# we don't write a title, so the titlepage can be customized
	# use '#' for title under/overline
	# 3/7/03
	dict = scanDirectives(c,v=vnode)
	encoding = dict.get("encoding",None)
	if encoding == None:
		encoding = app().config.default_derived_file_encoding
	# 3/7/03
	s = toEncodedString(fname,encoding,reportErrors=true)
	rstFile.write('.. filename: '+s+'\n')
	rstFile.write('\n')
	# 3/7/03
	s = vnode.bodyString()
	s = toEncodedString(s,encoding,reportErrors=true)
	rstFile.write(s+'\n')		# write body of titlepage
	rstFile.write('\n')
	
	toplevel = vnode.level()
	stopHere = vnode.nodeAfterTree()
	v = vnode.threadNext()
	# repeat for all nodes in this tree
	while v != stopHere:
		# 3/7/03
		h = v.headString()
		h = toEncodedString(h,encoding,reportErrors=true)
		rstFile.write(h+'\n')
		rstFile.write(underline(h,v.level()-toplevel))
		rstFile.write('\n')
		# 3/7/03
		s = v.bodyString()
		s = toEncodedString(s,encoding,reportErrors=true)
		rstFile.write(s+'\n')
		rstFile.write('\n')
		v = v.threadNext()</t>
<t tx="edream.111803100242.8"># note the first character is intentionally unused, to serve as the underline
# character in a title (in the body of the @rst node)

def underline(h,level):
	str = """#=+*^~"'`-:&gt;&lt;_"""[level]
	return str*max(len(h),4)+'\n'</t>
<t tx="edream.111803100856"></t>
<t tx="edream.111903105454"></t>
<t tx="edream.111903190444"></t>
<t tx="edream.111903190444.1"></t>
<t tx="edream.112003032318">@nocolor
http://sourceforge.net/forum/message.php?msg_id=2295621
By: billp9619

As I was explaining my ideas about opml it occurred to me that it uses DIV tags
and a Javascript as the output of the stylesheet.

But then that is what ALL the HTML collapsing outlines use! So the html behavior
is nothing special to opml...it is a behavior of scripted DIV tags in html.

I found a style sheet named outline_leo,xsl on my computer. This is really tiny
and works pretty good. Don't know where I got it from though.
 
Anyway, as I expected the insertion of a html FORM  and a  TEXTAREA box into
one of these DIV tags would collapse out of sight then reappear when clicked
just like any other node.. Actually this is one of those odd things that maybe
noone ever thought of trying,,,,I've never seen it in one of these html outlines
before.

Interestingly, the familiar collapsing xml display in Internet Explorer is really
just a xsl stylesheet and  produces DIV tags and a script like all these other
html outlines. Somewhere I found a version with minor revisions to make it work
with standard xpath.

There is a program called xpathvisualizer that runs in IE and gives basically
the same xml display but highlights an inputted xpath expression. With this
you can view source and see the script and DIV tags.

At the end of the day the only benefit to opml is that others are using
it (standard?) and perhaps  there is something especially good about its Javascript
implementation.

BTW, to load leo into internet explorer just save a copy with an .xml file extension.
Then drag it to IE.
And of course the file  could have an embedded xml-stylesheet instruction to
use leo_outline.xsl which just shows headlines, etc,

Also BTW... I have been using Python for some time now but I don't know if i
can handle plug-in development at this stage.  :-)

(But I might be up to refining the html/script environment further. )</t>
<t tx="edream.112103192146"></t>
<t tx="edream.112103192146.1"></t>
<t tx="edream.112303075625"></t>
<t tx="edream.120103084310"></t>
<t tx="edream.120103084310.1">1. The sys.path variable has been reset when the plugins are run. It
is set so that *only* the plugins directory is in the path. This means
that no import of standard modules will work in plugins.

In plugins_menu: createPluginsMenu

replace:
path = os.path.join(app().loadDir,"..","plugins")
sys.path = path

by:

path = os.path.join(app().loadDir,"..","plugins")
newpath = old_path; newpath.append(path)
sys.path = newpath
</t>
<t tx="edream.120203140328.1">from leoGlobals import *
import tkFont

@others

c = top()

# Body pane.
fn = c.frame.body.cget("font")
font = tkFont.Font(font=fn)
name,size,slant,weight = getFontSettings(font)
print "body:",fn,name,size,slant,weight

if 0:

	# Log pane.
	fn = c.frame.log.getFontConfig()
	font = tkFont.Font(font=fn)
	name,size,slant,weight = getFontSettings(font)
	es("log:" + name + "," + `size` + "," + slant + "," + weight)
	
	# Tree pane.
	font = c.frame.tree.getFont()
	name,size,slant,weight = getFontSettings(font)
	es("head:" + name + "," + `size` + "," + slant + "," + weight)</t>
<t tx="edream.120203140328.2">def getFontSettings (font):

	name   = font.cget("family")
	size   = font.cget("size")
	slant  = font.cget("slant")
	weight = font.cget("weight")

	return name, size, slant, weight</t>
<t tx="edream.120203141341"></t>
<t tx="edream.120203141341.1">from leoGlobals import *
config = app.config

font = config.getFontFromParams(
		"body_text_font_family", "body_text_font_size",
		"body_text_font_slant",  "body_text_font_weight",
		tag = "body")
		
print font

c = top() ; body = c.frame.body.bodyCtrl

print body

# body.configure(font=font)</t>
<t tx="edream.120203141927">from leoGlobals import *

font = app.config.defaultFont

print font.cget("family"), font.cget("weight")</t>
<t tx="edream.120303095057.1">@language python

"""Replace Commands.openWithTempFilePath so Leo opens temporary
files with a filename that begins with the headline text, and
located in a "username_Leo" subdirectory of the temporary
directory. The "LeoTemp" prefix is omitted.  This makes it easier to
see which temporary file is related to which outline node."""

from leoPlugins import *
from leoGlobals import *

import leoCommands
import getpass,os,tempfile

@others

# Register the handlers...
registerHandler("start2", onStart)

__version__ = "1.3"
plugin_signon(__name__)</t>
<t tx="edream.120303095910">def onStart (tag,keywords):

	# trace("replacing openWithTempFilePath")

	funcToMethod(openWithTempFilePath,leoCommands.Commands,"openWithTempFilePath")
</t>
<t tx="edream.120303095910.1">def openWithTempFilePath (self,v,ext):

	"""Return the path to the temp file corresponding to v and ext.

	Replaces the Commands method."""    

	try:
		leoTempDir = getpass.getuser() + "_" + "Leo"
	except:
		leoTempDir = "LeoTemp"
		es("Could not retrieve your user name.")
		es("Temporary files will be stored in: %s" % leoTempDir)

	td = os.path.join(os.path.abspath(tempfile.gettempdir()), leoTempDir)
	if not os.path.exists(td):
		os.mkdir(td)

	name = sanitize_filename(v.headString()) + '_' + str(id(v.t))  + ext
	path = os.path.join(td,name)
	return path</t>
<t tx="edream.120603093808"># Leo enables only those plugins whose filenames appear here.
# Leo loads plugins in the order they appear in this file.
# File names may be indented as desired.

# Debugging plugins...
	# trace_keys.py

# "official" plugins...
	add_directives.py
	# mod_autosave.py
	open_with.py
	color_markup.py
	image.py
	# nav_buttons.py
	plugins_menu.py
	rowcol.py
	# status_line.py
	# word_export.py
	# xemacs.py
	
# Other plugins...
	# open_shell.py

# New from Steve Zatz
	# ** requires docutils: http://docutils.sourceforge.net/
	# ** Will use SilverCity syntax styline if present: http://silvercity.sourceforge.net/
	# rst2.py

# New from Paul Paterson.
	nodenavigator.py
	searchbox.py
	# newButtons.py

# New from Bernhard Mulder
	# mod_http.py
	
# New from Davide Salomoni
	hoist.py</t>
<t tx="edream.120603100522">leoPlugins.py now enables plugins using pluginsManager.txt.</t>
<t tx="edream.120703082844">@language python

"""
Up Down, show the body as a continum space, the user can go up or down, and will automatically jump from one node to the next.
"""

@
04/12/03 File Created. RodrigoB.
05/12/03 Leo4.1 support. RodrigoB.
06/12/03 Changing to line based. Upload. RodrigoB.
@c

__version__ = "0.0.3"

from leoPlugins import *
from leoGlobals import *

last_key = None # global var for this module.

try:    import Tkinter
except: Tkinter = None

if Tkinter and app.gui.guiName() == "tkinter":

    @others

	# Register the handlers...
	registerHandler("start2", OnStart2) #  install the plugin hooks

	plugin_signon(__name__)
</t>
<t tx="edream.120703082844.1">def OnStart2(tag, keywords):

	"""."""
	
	trace("updown started")
	
	c = keywords['c']
	c.frame.body.bodyCtrl.bind("&lt;Key&gt;", OnBodyKey, '+') # append an extra binding.</t>
<t tx="edream.120703082844.2">def OnBodyKey(event):
	"""."""
	tracing = true
	c = top() ; global last_key
	text = c.frame.body.bodyCtrl
	v = c.currentVnode()
	keycode = event.keycode
	if 0:
		if tracing: # for debugging.
			# trace("event %s %s" % (event, dir(event))) 
			trace("ch %s %s %s" % (event.char, event.keycode, event.num))
	if keycode in [33, 98, 99]: # up, page up
		keycode = "up"
	elif keycode in [34, 104, 105]: # down, page down
		keycode = "down"        
			 
	if last_key == keycode:
		if keycode == "up":
			new = v.threadBack()
			if tracing: trace("Going up")
		elif keycode == "down":
			new = v.threadNext()
			if tracing: trace("Going down")
		else:
			new = None	
		if new:
			c.selectVnode(new) # on Leo4 it will automatically show the selected node.
		last_key = None
		return
	
	insert_line = int(text.index("insert").split('.')[0])
	last_line   = int(text.index("end").split('.')[0]) - 1

	if insert_line == 1 and keycode == "up":
		last_key = keycode
	elif insert_line == last_line and keycode == "down":
		last_key = keycode
	else:
		last_key = None</t>
<t tx="ekr.20040107092135">Most of these were written by Paul Paterson.  EKR added the Recent Menu.</t>
<t tx="ekr.20040107092135.2">&lt;&lt; doc string &gt;&gt;

__version__ = "0.3"

from leoPlugins import *
from leoGlobals import *
import leoFind

try:
	import Tkinter
except ImportError:
	Tkinter = None
Tk = Tkinter

&lt;&lt; vars &gt;&gt;
@others

if Tkinter:
	search = SearchBox()
	
	if app.gui is None:
		app.createTkGui(__file__)

	if app.gui.guiName() == "tkinter":
		# es("Starting searchbox", color="orange")
		registerHandler("after-create-leo-frame", search.addWidgets)
		plugin_signon(__name__)</t>
<t tx="ekr.20040107092135.3">class SearchBox:
	"""A search box for Leo"""
	@others</t>
<t tx="ekr.20040107092135.5">def doSearch(self,*args,**keys):
	
	"""Do the actual search"""
	# import pdb; pdb.set_trace()
	text = self.search.get()
	# Remove the old find frame so its options don't compete with ours.
	search_mode = self.option_value.get() 
	new_find = QuickFind(text,search_mode)
	old_find, app.findFrame = app.findFrame, new_find
	# Do the search.
	self.c.findNext()
	# Restore the find frame.
	app.findFrame = old_find
	# Remember this list 
	self.updateRecentList(text, search_mode) 
	if 0: # This doesn't work yet: the user can't see the match.
		self.search.focus_set()</t>
<t tx="ekr.20040107092135.6">class QuickFind(leoFind.leoFind):
	
	"""A class for quick searching"""
	
	@others
</t>
<t tx="ekr.20040107092135.7">def __init__(self, text, search_option=""):
	
	"""Initialize the finder"""

	# Init the base class.
	leoFind.leoFind.__init__(self)
	
	self.s_text = Tk.Text() # Used by find.search()
	self.__find_text = text
	self.search_option = search_option
</t>
<t tx="ekr.20040107092135.8">def set_ivars(self, c):

	"""Set the ivars for the find"""

	# Modified from leoTkinterFind.set_ivars
	for key in self.intKeys:
		setattr(c, key + "_flag", 0)
	c.change_text = ""
	c.find_text = self.__find_text
	
	# Set options
	for flag_name in OPTION_DICT[self.search_option]: 
		if flag_name.startswith("!"): 
			value = 0 
			name = flag_name[1:] 
		else: 
			value = 1 
			name = flag_name 
		setattr(c, name, value) 
</t>
<t tx="ekr.20040107103252">def init_s_text (self,s):

	c = self.c ; t = self.s_text	
	t.delete("1.0","end")
	t.insert("end",s)
	t.mark_set("insert",choose(c.reverse_flag,"end","1.0"))
	return t
</t>
<t tx="ekr.20040107103339">def gui_search (self,t,*args,**keys):

	return t.search(*args,**keys)</t>
<t tx="ekr.20040107111307">def onBackSpace (self,event=None):
	trace()
</t>
<t tx="ekr.20040108054555.3">def addWidgets(self, tags, keywords):
	"""Add the widgets to the navigation bar"""
	self.c = keywords['c'] 
	toolbar = self.c.frame.iconFrame
	# Button.
	self.go = Tkinter.Button(self._getSizer(toolbar, 25, 32), text="GO", command=self.doSearch)
	self.go.pack(side="right", fill="both", expand=1)
	# Search options.
	options = [name for name, flags in OPTION_LIST]
	self.option_value = Tkinter.StringVar() 
	self.options = Tkinter.OptionMenu(
		self._getSizer(toolbar, 29, 130), self.option_value, *options)
	self.option_value.set(options[0]) 
	self.options.pack(side="right", fill="both", expand=1)
	# Text entry.
	self.search = Tkinter.Entry(self._getSizer(toolbar, 24, 130))
	self.search.pack(side="right", padx=3, fill="both", expand=1)
	self.search.bind("&lt;Return&gt;", self.onKey)
	# Store a list of the last searches.
	self.search_list = []

</t>
<t tx="ekr.20040108054555.4">def _getSizer(self, parent, height, width):
	"""Return a sizer object to force a Tk widget to be the right size"""
	if USE_FIXED_SIZES: 
		sizer = Tkinter.Frame(parent, height=height, width=width)
		sizer.pack_propagate(0) # don't shrink 
		sizer.pack(side="right")
		return sizer
	else:
		return parent</t>
<t tx="ekr.20040108054555.5">def onKey (self,event=None): 
	"""Called when the user presses Return in the text entry box"""
	self.search.after_idle(self.doSearch)

</t>
<t tx="ekr.20040108054555.7">def updateRecentList(self, text, search_mode):
	"""Update the list of recently searched items"""

	# First update the menu - delete all the options if there are any
	menu = self.options["menu"]
	if self.search_list:
		menu.delete(len(OPTION_LIST),"end")

	menu.add_command(label="-------------", command=lambda:0) 

	# Update and prune list to remove a previous search for this text 
	self.search_list = [(text, search_mode)] +  [
		(name, mode) for name, mode in self.search_list[:SEARCH_LIST_LENGTH] if name &lt;&gt; text] 

	# Now update the menu 
	for name, mode in self.search_list:
		menu.add_command(
			label=name,command=Tkinter._setit(self.option_value,name,self.searchRecent))</t>
<t tx="ekr.20040108054555.8">def searchRecent(self, *args, **kw):
	"""Do a search on a recently used item"""
	# Find the item.
	name = self.option_value.get() 
	for item_name, mode in self.search_list:
		if item_name == name: 
			# Ok, so set mode and text and then do the search 
			self.option_value.set(mode)
			self.search.delete(0, "end")
			self.search.insert(0, name)
			self.doSearch() 
			break
	else:
		print name, self.search_list 
		es("Recent search item not found! Looks like a bug ...", color="red")</t>
<t tx="ekr.20040108054555.14"># Set this to 0 if the sizing of the toolbar controls doesn't look good on 
# your platform 
USE_FIXED_SIZES = 1

# Set this to the number of previous searches you want to remember 
SEARCH_LIST_LENGTH = 10

# Define the search option/find option matrix - we define as a list first 
# so we can keep a nice order. You can easily add options here if you 
# know what you are doing ;) 
# If an option is supposed to zero a flag then start the name with a ! 

OPTION_LIST = [
	("Search text", ["search_body_flag", "search_headline_flag", "ignore_case_flag"]), 
	("Search word", ["search_body_flag", "search_headline_flag", "whole_word_flag", "ignore_case_flag"]), 
	("Search headlines", ["search_headline_flag","ignore_case_flag"]), 
	("Search body", ["search_body_flag", "ignore_case_flag"]), 
	("Case sensitive", ["search_body_flag", "search_headline_flag"]), 
]

OPTION_DICT = dict(OPTION_LIST)</t>
<t tx="ekr.20040108060748">"""Add a quick search to the toolbar in Leo

A search box which behaves like a web site search is added, along with
a "GO" button to do quick searches right from the main Leo window. All the
current search options are retained except that "search body text" is
explicitely set - mainly because this is by far the most common use case.

Pressing &lt;CR&gt; while editing the text automatically does a search. Repeated
searches can be done by clicking the "GO" button.

The combo box also stores a list of previous searches, which can be
selected to quickly repeat a search. When activating a previous
search the original search mode is used.

Still to do:

- incremental search
- reverse search
- persist recent searches across Leo sessions
- use INI file to set options for list size etc
"""</t>
<t tx="ekr.20040108062655">"""Add a quick node navigators to the toolbar in Leo 

Adds a node navigator to the toolbar. The navigator allows quick
access to marked nodes. You can either go to the marked node or hoist
the marked node.

""" 

__name__ = "Node Navigator"
__version__ = "0.3" 

from leoPlugins import * 
from leoGlobals import * 

try:    import Tkinter 
except: Tkinter = None 
Tk = Tkinter 

# Set this to 0 if the sizing of the toolbar controls doesn't look good on your platform. 
USE_FIXED_SIZES = 1 

@others

if Tkinter: 
	if app.gui is None: 
		app.createTkGui(__file__) 

	if app.gui.guiName() == "tkinter":
		nav = Navigator() 
		registerHandler("after-create-leo-frame", nav.addWidgets) 
		registerHandler(("set-mark","clear-mark"),nav.updateMarks)
		registerHandler("select2",nav.updateRecent)
		plugin_signon("nodenavigator")</t>
<t tx="ekr.20040108062655.2">class Navigator: 
	"""A node navigation aid for Leo"""
	@others
</t>
<t tx="ekr.20040108062655.3">def addWidgets(self, tag, keywords): 
	"""Add the widgets to the navigation bar""" 
	self.c = c = keywords['c'] 
	toolbar = self.c.frame.iconFrame 
	# Main container 
	self.frame = Tkinter.Frame(toolbar) 
	self.frame.pack(side="left")
	# Marks
	marks = ["Marks"] 
	self.mark_value = Tkinter.StringVar() 
	self.marks = Tkinter.OptionMenu(self._getSizer(self.frame,29,70),self.mark_value,*marks)
	self.mark_value.set(marks[0]) 
	self.marks.pack(side="right",fill="both",expand=1)
	# Recent.
	recent = ["Recent"]
	self.recent_value = Tkinter.StringVar() 
	self.recent = Tkinter.OptionMenu(self._getSizer(self.frame,29,70),self.recent_value,*recent) 
	self.recent_value.set(recent[0]) 
	self.recent.pack(side="left",fill="both",expand=1)
	# Recreate the menus immediately.
	self.updateRecent("tag",{"c":c})
	self.updateMarks("tag",{"c":c})</t>
<t tx="ekr.20040108062655.4">def _getSizer(self, parent, height, width):
	
	"""Return a sizer object to force a Tk widget to be the right size""" 
	if USE_FIXED_SIZES: 
		sizer = Tkinter.Frame(parent,height=height,width=width) 
		sizer.pack_propagate(0) # don't shrink 
		sizer.pack(side="right") 
		return sizer 
	else: 
		return parent </t>
<t tx="ekr.20040108062655.5">def onSelect(self, vnode):
	"""Do the navigation"""

	self.c.selectVnode(vnode)</t>
<t tx="ekr.20040108062655.6">def updateMarks(self, tag, keywords):
	"""Update the marks list"""        
	c = keywords.get("c")
	v = c.rootVnode()

	# Clear old marks menu
	try:
		menu = self.marks["menu"]
		menu.delete(0,"end")
	except: return

	# Find all marked nodes
	vnodes = [] ; tnodes = []
	while v:
		if v.isMarked() and v.t not in tnodes:
			
			def callback(event=None,self=self,v=v):
				return self.onSelect(v)

			name = v.headString().strip()
			menu.add_command(label=name,command=callback)
			tnodes.append(v.t)
			vnodes.append(v)
		v = v.threadNext()</t>
<t tx="ekr.20040108091136">def updateRecent(self,tag,keywords):
	"""Update the marks list"""        
	c = keywords.get("c")
	v = c.rootVnode()

	# Clear old marks menu
	try:
		menu = self.recent["menu"]
		menu.delete(0,"end")
	except: return

	# Make sure the node still exists.
	# Insert only the last cloned node.
	vnodes = [] ; tnodes = []
	for v in c.visitedList:
		if v.exists(c) and v.t not in tnodes:
			
			def callback(event=None,self=self,v=v):
				return self.onSelect(v)

			menu.add_command(label=v.headString(),command=callback)
			tnodes.append(v.t)
			vnodes.append(v)</t>
<t tx="ekr.20040108095351">"""Add row/column indicators to the toolbar.""" 

__name__ = "Row/Column indicators"
__version__ = "0.1" 

from leoPlugins import * 
from leoGlobals import * 

try:    import Tkinter 
except: Tkinter = None 
Tk = Tkinter

@others

if Tkinter: 

	if app.gui is None: 
		app.createTkGui(__file__)

	if app.gui.guiName() == "tkinter":
		rowCol = rowColClass() 
		registerHandler("after-create-leo-frame",rowCol.addWidgets) 
		plugin_signon("rowcol")</t>
<t tx="ekr.20040108095351.1">class rowColClass:
	
	"""Class that puts row/column indicators in the status bar."""
	
	@others</t>
<t tx="ekr.20040108095351.2">def addWidgets (self,tag,keywords):
	
	self.c = keywords['c']

	toolbar = self.c.frame.iconFrame

	# Main container 
	self.rowColFrame = f = Tkinter.Frame(toolbar) 
	f.pack(side="left")
	
	text = "line 0, col 0"
	width = len(text) # Setting the width here prevents jitters.
	self.rowColLabel = Tk.Label(f,text=text,width=width,anchor="w")
	self.rowColLabel.pack(side="left")
	
	# Update the row/column indicators immediately to reserve a place.
	self.updateRowColWidget()</t>
<t tx="ekr.20040108095351.4">def updateRowColWidget (self):
	
	c = self.c ; body = c.frame.body.bodyCtrl ; gui = app.gui
	tab_width = c.frame.tab_width
	
	# New for Python 2.3: may be called during shutdown.
	if app.killed:
		return

	index = body.index("insert")
	row,col = gui.getindex(body,index)
	
	if col &gt; 0:
		if 0: # new code
			s = c.frame.body.getRange(index1,index2)
		else:
			s = body.get("%d.0" % (row),index)
		s = toUnicode(s,app.tkEncoding)
		col = computeWidth(s,tab_width)

	if row != self.lastStatusRow or col != self.lastStatusCol:
		s = "line %d, col %d " % (row,col)
		self.rowColLabel.configure(text=s)
		self.lastStatusRow = row
		self.lastStatusCol = col
		
	# Reschedule this routine 100 ms. later.
	# Don't use after_idle: it hangs Leo.
	self.rowColFrame.after(100,self.updateRowColWidget)</t>
<t tx="ekr.20040108100040">def __init__ (self):
	
	self.lastStatusRow, self.lastStatusCol = -1,-1</t>
<t tx="ekr.20040109080300">@nocolor

1/9/04: nodenavigator.py

- Call updateMarks and UpdateRecent during initialization.
- Put the code that deletes menus in a try/except block.
- Simplified defintion of callback routines: I don't like lambda.
- Removed some old code.

1/9/04: rowcol.py

- Call updatedRowColWidget immediately from addWidgets.
  This seems to be necessary to reserve the proper place in the icon area.

2/1/04: status_line.py:

Adds status line to bottom of Leo window</t>
<t tx="ekr.20040111053758">@nocolor

I now have a version of the plugin that produces HTML output that has syntax
highlighted code using the SilverCity(http://silvercity.sourceforge.net) lexing
package. However, since that requires someone to install not only docutils but
SilverCity, I think it's fine to post the original rest2 plugin that I sent
you. If there is any interest, I can always write a version that looks for the
SilverCity package and uses it if it is present.

---------------------
Sorry for the longish note but I believe that the application of Leo that I 
describe below is important, and I wanted to make you aware of it.

The end-result of this work is to use Leo+docutils to mix program code and 
reST documentation in a way that I believe is very useful.  It builds upon 
the work of the existing rst plugin.

The basic approach is that any Leo node that contains program code that 
needs documentation (in an ideal world it would be every node) has an 
associated child node whose headline is simply '@rst', which, not 
surprisingly, contains reST-style documentation.  While this means that a 
typical program may have dozens (if not hundreds) of these @rst nodes, it 
produces documentation that I think is as close as I have ever seen to 
useful, easy-to-read documentation that is easy to create at the same time 
as an application is being coded.

There are several interelated aspects to this work.

- The reST plugin (renamed rst2) was hacked to manage Leo outlines that 
were a combination of normal code nodes and reSt nodes.

- The plugin now recognizes a @rst directive (that has no associated file 
name) in the headline of a node.

- When it encounters such a @rst Headline node, it writes the contents of 
the body of the @rst node's *parent* (which generally contains program code) 
to the reST output file (HTML) and then adds the reST content that is 
contained in the body of the @rst documentation node to the output HTML 
file,

- These @rst nodes are used in @file-nosent trees and the @rst nodes have an 
@ignore directive (plus @nocolor directive and @wrap directives) so that 
when the @file is updated the application code does not contain the 
reST-style documentation contained in the body of the @rst nodes.  (This was 
the reason I had asked you in the Leo Forum to allow @file-nosent trees to 
work appropriately with @ignore nodes - Thank you for doing this right 
away.)  There is no reason that the reST content couldn't be written to the 
@file as documentation other than I personally believe in a volume of 
documentation (including musings, failed ideas, questions, etc.) that is 
probably best kept separate from the actual *.py files.

- For pure convenience the plugin was also modified so that when you 
double-click on a plain rst node (no associated filename) Leo opens both the 
@rst documentation node and the parent node containing code in an external 
editor *simultaneously*.  I happen to use Textpad and so the code is opened 
with python syntax coloring in one Textpad window and right next to it is 
the reST documentation.  This is really just a convenience but it makes it 
much much easier to code and do documentation at the same time. (Note that 
the plugin assumes that the python extension is '.tp' since that is what I 
use with TextPad.)

---------------------------------------------------------------------
So why is this a big deal? For the first time in my experience the 
documentation process...

1) is completely in sync with the process of code development
2) allows the programmer to write as much documentation as he/she wants 
without the programming code becoming unreadable because of what would be 
considered excessive or intrusive documentation. (This applies whether 
documentation is intended for external consumption or just so a solo 
programmer can remember what he/she was thinking...)

My conclusion is that Leo + reST/docutils provides the perfect platform for 
optimal documentation.  I have never completely understood what is meant by 
Literate Programming but in my mind this is practical Literate Programming.

Frankly, I think this is all a minor miracle but maybe I've lost perspective.

Steve Zatz</t>
<t tx="ekr.20040118081748">"""If a headline starts with @rst &lt;filename&gt;, double-clicking on it will 
write a file in outline order, with the headlines converted to reStructuredText 
section headings.

If the name of the &lt;filename&gt; has the extension .html, .htm or .tex, and if you have
docutils installed, it will generate HTML or LaTeX, respectively."""

# By Josef Dalcolmo: contributed under the same licensed as Leo.py itself.

# EKR: The code now lets other plugins handle @folder and @url nodes.

# S. Zatz: some modifications to create the ability to combine program code and documentation
# using @rst nodes (with no file name) in orde to produce combined code/documentation HTML output.
# See the 'about this plugin' section for more information

from leoPlugins import *
from leoGlobals import *

import os
#import reST_HTML

&lt;&lt; about this plugin &gt;&gt;
&lt;&lt; change log &gt;&gt;

@others

# Register the handlers...
registerHandler("icondclick1",onIconDoubleClick)
__version__ = "2.0"
plugin_signon(__name__)


</t>
<t tx="ekr.20040118081748.1">@ This plugin writes out @rst nodes as a reStructuredText file.

If the filename ends in .html, .htm or .tex and if you have docutils_ (a Python
module) installed, then it will be written as HTML or LaTeX, respectively. The HTML converter is far
from bug-free, but remember, docutils is alpha software. (Perhaps a future
version will allow automatic translation to other formats, like OpenOffice.org
as well).

Headlines are translated into reStructuredText headlines, e.g. underlined
depending on the level and empty line separated from body text otherwise, text
is written as it is. The "#" character is not used for underlining, so it may
be used for a title as in::

    #####
    Title
    #####

Otherwise, section underlining is discouraged, since it is automatically generated.

.. _docutils: http://docutils.sourceforge.net

--------------------------------------------------------

S Zatz modifications

Assumes Leo outlines are in the form

@rst somefilename.[txt/html/tex]
..@file-nosent somefilename.py
....code node
......@rst
......another code node
........@rst
......more code
........@rst

and so on

If you want a table of contents, put the following:  '.. contents:: Table of Contents'
on its own line in the body of the root '@rst somefilename.[txt/html/tex]' node.
(Maybe this should be done in the plugin?)

Double-clicking on a @rst somefilename.ext node generates a reST-structured [txt/html/tex] file that combines
program code nodes with reST documentation from @rst nodes that have no associated filename.

Note: if the SilverCity lexing package is present then code is presented with syntax highlighting.  For the
HTML output to look OK you need the following cascading style sheets:
    1) default.css -&gt; docutils default style sheet
    2) leo_rst.css -&gt; contains some style 'improvements' mostly based on Gunnar Schwant's DocFactory
    3) silver_city.css -&gt; if SilverCity is present, this is the style sheet that supports syntax highlighting
The latter two style sheets are imported at the end of the default.css.  Since I know only enough css to be dangerous,
would be great to have someone clean this up.  I am following David Goodger request that the default docutils
style sheet be kept intact with modifications done via imported style sheets.
</t>
<t tx="ekr.20040118081748.2">@ Change log:

- New tree types: @rst has been added.

- EKR: The code now lets other plugins handle @folder and @url nodes.

- HTML generation: @rst nodes can now generate HTML, if Python docutils_ are
  installed. Simply give the filename an extension .htm or .html. You can try
  this out by renaming the filename in this @rst tree.

- underlines: I changed the order of the underline characters again. The "&gt;" is
  doesn't really look good as an underline in my opinion, so I moved it to a very
  low level.

- JD 2003-03-10 (rev 1.3): some more corrections to the unicode-&gt; encoding translation.
  No only check for missing docutils (doesn't mask other errors any more).

- JD 2003-03-11 (rev 1.4): separated out the file launching code to a different pluging.

- 2003-11-02 Added generation of LaTeX files, just make the extension of the filename '.tex'. --Timo Honkasalo

- 2003-12-24 S Zatz modifications to introduce concept of plain @rst nodes to improve program documentation

- 2004-01-17 S Zatz allow whitespace in paths.</t>
<t tx="ekr.20040118081748.3"># by Josef Dalcolmo 2003-01-13
#
# this does not check for proper filename syntax.
# path is the current dir, or the place @folder points to
# this should probably be changed to @path or so.

def onIconDoubleClick(tag,keywords):

	v = keywords.get("v")
	c = keywords.get("c")
	h = v.headString().strip()

	if match_word(h,0,"@rst"):
		if len(h) &gt; 5:
			fname = h[5:]
			ext = os.path.splitext(fname)[1].lower()
			if ext in ('.htm','.html','.tex'):
				&lt;&lt; write rST as HTML/LaTeX &gt;&gt;
			else:
				&lt;&lt; write rST file &gt;&gt;
		else:
			pass
			# if the headline only contains @rst then open the node and its parent in text editor
			# this works for me but needs to be generalized and should probably be a component
			# of the open_with plugin
			#c.openWith(("os.startfile", None, ".txt"))
			#c.selectVnode(v.parent())
			#c.openWith(("os.startfile", None, ".tp"))


</t>
<t tx="ekr.20040118081748.4">try:
	import docutils
except:
	es('HTML/LaTeX generation requires docutils',color="blue")
	return
else:
	from docutils.core import Publisher
	from docutils.io import StringOutput, StringInput
	import StringIO
	
# Set the writer and encoding for the converted file
if ext in ('.html','.htm'):
	writer='html'
	enc="utf-8"
else:
	writer='latex'
	enc="iso-8859-1"

if writer == 'html':
	try:
		import SilverCity
	except:
		es('SilverCity not present so no syntax highlighting')
		syntax = False
	else:
		&lt;&lt; define code-block &gt;&gt;
		syntax = True     
else:
	syntax = False
	
rstFile = StringIO.StringIO()
writeTreeAsRst(rstFile, fname, v, c, syntax)
rstText = rstFile.getvalue()

# this code snipped has been taken from code contributed by Paul Paterson 2002-12-05
pub = Publisher()
pub.source = StringInput(source=rstText)
pub.destination = StringOutput(pub.settings, encoding=enc)
pub.set_reader('standalone', None, 'restructuredtext')
pub.set_writer(writer)
output = pub.publish(argv=[]) # 1/18/04

convertedFile = file(fname,'w')
convertedFile.write(output)
convertedFile.close()
rstFile.close()
es('written: '+str(fname))</t>
<t tx="ekr.20040118081748.5"># See Syntax-highlighted code blocks for docutils by Kevin Schluff in ASPN Python Cookbook
# this code defines a new "code-block" directive for docutils
import docutils.parsers.rst

def code_block(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine):
	language = arguments[0]
	module = getattr(SilverCity, language)
	generator = getattr(module, language+"HTMLGenerator")
	io = StringIO.StringIO()
	generator().generate_html(io, '\n'.join(content))
	html = '&lt;div class="code-block"&gt;\n%s\n&lt;/div&gt;\n'%io.getvalue()
	raw = docutils.nodes.raw('',html, format='html') #(self, rawsource='', text='', *children, **attributes):
	return [raw]

code_block.arguments = (1,0,0)
code_block.options = {'language' : docutils.parsers.rst.directives.unchanged}
code_block.content = 1
  
# Need to register the directive with docutils
docutils.parsers.rst.directives.register_directive('code-block', code_block)

</t>
<t tx="ekr.20040118081748.6">rstFile = file(fname,'w')
writeTreeAsRst(rstFile, fname, v, c)
rstFile.close()
es('written: '+str(fname))</t>
<t tx="ekr.20040118081748.7">def writeTreeAsRst(rstFile, fname, vnode, c, syntax=None):
	'Writes the tree under vnode to the file rstFile (fname is the filename)'
	# we don't write a title, so the titlepage can be customized
	# use '#' for title under/overline
	directives = scanDirectives(c, v=vnode) # changed name because don't want to use keyword dict
	
	encoding = directives.get("encoding",None)
	if encoding == None:
		encoding = app().config.default_derived_file_encoding
	
	if syntax:
		lang_dict = {'python':'Python', 'ruby':'Ruby', 'perl':'Perl', 'c':'CPP'}
		language = directives['language']
		# SilverCity modules have first letter in caps
		if language in lang_dict:
			code_dir = '**code**:\n\n.. code-block:: %s\n\n'%lang_dict[language]
		else:
			code_dir = '**code**:\n\n.. class:: code\n..\n\n::\n\n'
	else:
		code_dir = '**code**:\n\n.. class:: code\n..\n\n::\n\n'

	s = toEncodedString(fname,encoding,reportErrors=true)
	rstFile.write('.. filename: '+s+'\n')
	rstFile.write('\n')

	s = vnode.bodyString()
	s = toEncodedString(s,encoding,reportErrors=true)
	rstFile.write(s+'\n')		# write body of titlepage
	rstFile.write('\n')
	
	toplevel = vnode.level()+1 #Dec 20
	h = vnode.headString()
	stopHere = vnode.nodeAfterTree()
	v = vnode.threadNext()
	# repeat for all nodes in this tree
	while v != stopHere:
		h = v.headString().strip()
		if match_word(h,0,"@rst"):
			s = v.bodyString()
			s = toEncodedString(s,encoding,reportErrors=true)
			# next line is an total hack to take care of @ignore, @nocolor, @wrap in the @rst nodes
			s = s.split('\n',3)[3]
			rstFile.write('**comments**:\n%s\n'%s)
			rstFile.write('\n')
		else:
			if match_word(h,0,"@file-nosent"):
				h = h[13:]
			h = toEncodedString(h,encoding,reportErrors=true)
			s = v.bodyString()
			s = toEncodedString(s,encoding,reportErrors=true)
			rstFile.write(h+'\n')
			rstFile.write(underline(h,v.level()-toplevel))
			rstFile.write('\n')
			if s.strip():
				rstFile.write(code_dir)
				s = s.split('\n')
				for linenum,linetext in enumerate(s[:-1]):
					if "@others" in linetext: #deleting lines with @other directive from output
						continue
					rstFile.write('\t%2d  %s\n'%(linenum+1,linetext))
			rstFile.write('\n')
			
		v = v.threadNext()</t>
<t tx="ekr.20040118081748.8"># note the first character is intentionally unused, to serve as the underline
# character in a title (in the body of the @rst node)

def underline(h,level):
	str = """#=+*^~"'`-:&gt;&lt;_"""[level]
	return str*max(len(h),4)+'\n'
</t>
<t tx="ekr.20040119044414"></t>
<t tx="ekr.20040119044414.1">@language python

"""
A minimal http plugin for LEO, based on AsyncHttpServer.py.

Based on the asyncore / asynchat framework.
"""

# From http://home.pacbell.net/bwmulder/python/Leo/HttpPlugin.leo
# See also, the related script from the Python Cookbook:
# http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/259148

__version__ = "0.9"

&lt;&lt; how to use this plugin &gt;&gt;
&lt;&lt; imports &gt;&gt;

sockets_to_close = []

@others

applyConfiguration()

if active:
	s=Server('',port,RequestHandler)
	asyncore.read = a_read
	registerHandler("idle", plugin_wrapper)
	
	es("http serving enabled on port %s, version %s" % (port, __version__), color="purple")
</t>
<t tx="ekr.20040119044414.3">import asynchat,asyncore,socket,SimpleHTTPServer, select, urllib, urlparse
import posixpath,sys, cgi,cStringIO, os

import exceptions
import select
import socket
import sys
import time

import shutil
from StringIO import StringIO

from  leoPlugins import registerHandler
from leoGlobals import es, app

import ConfigParser
</t>
<t tx="ekr.20040119044414.5">class delayedSocketStream(asyncore.dispatcher_with_send):
	@others
</t>
<t tx="ekr.20040119044414.6">def __init__(self,sock):
	self.socket=sock
	self.socket.setblocking(0)
	self.closed=1   # compatibility with SocketServer
	self.buffer = []
</t>
<t tx="ekr.20040119044414.7">def write(self,data):
	self.buffer.append(data)
</t>
<t tx="ekr.20040119044414.8">def initiate_sending(self):
	self.out_buffer = ''.join(self.buffer)
	del self.buffer
	self.set_socket(self.socket, None)
	self.socket.setblocking(0)
	self.connected = 1
	try:
		self.addr = self.socket.getpeername()
	except socket.error:
		# The addr isn't crucial
		pass
</t>
<t tx="ekr.20040119044414.9">def handle_read(self):
	pass</t>
<t tx="ekr.20040119044414.10">def writable(self):
	result = (not self.connected) or len(self.out_buffer)
	if not result:
		sockets_to_close.append(self)
	return result
</t>
<t tx="ekr.20040119044414.11">class nodeNotFound(Exception):
	pass</t>
<t tx="ekr.20040119044414.12">class escaped_StringIO(StringIO):
	@others</t>
<t tx="ekr.20040119044414.13">def write_escaped(self, s):
	s = s.replace('&amp;', "&amp;amp;")
	s = s.replace('&lt;', "&amp;lt;")
	s = s.replace('&gt;', "&amp;gt;")
	
	# is there a more elegant way to do this?
	# Replaces blanks with &amp;nbsp; id they are in
	# the beginning of the line.
	lines = s.split('\n')
	result = []
	blank = chr(32)
	for line in lines:
		if line.startswith(blank):
			resultchars = []
			startline = True
			for char in line:
				if char == blank:
					if startline:
						resultchars.append('&amp;nbsp;')
					else:
						resultchars.append(' ')
				else:
					startline = False
					resultchars.append(char)
			result.append(''.join(resultchars))
		else:
			result.append(line)
	s = '\n'.join(result)

	s = s.replace('\n', '&lt;br&gt;')
	s = s.replace(chr(9), '&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;')
	StringIO.write(self, s)
	</t>
<t tx="ekr.20040119044414.14">class RequestHandler(
	asynchat.async_chat,
	SimpleHTTPServer.SimpleHTTPRequestHandler):
	@others
</t>
<t tx="ekr.20040119044414.15">def copyfile(self, source, outputfile):
	"""Copy all data between two file objects.

	The SOURCE argument is a file object open for reading
	(or anything with a read() method) and the DESTINATION
	argument is a file object open for writing (or
	anything with a write() method).

	The only reason for overriding this would be to change
	the block size or perhaps to replace newlines by CRLF
	-- note however that this the default server uses this
	to copy binary data as well.
	 """
	shutil.copyfileobj(source, outputfile, length=255)
</t>
<t tx="ekr.20040119044414.16">def log_message(self, format, *args):
	"""Log an arbitrary message.

	 This is used by all other logging functions.  Override
	 it if you have specific logging wishes.

	 The first argument, FORMAT, is a format string for the
	 message to be logged.  If the format string contains
	 any % escapes requiring parameters, they should be
	 specified as subsequent arguments (it's just like
	 printf!).

	 The client host and current date/time are prefixed to
	 every message.

	 """
	message = "%s - - [%s] %s\n" % (
		self.address_string(),
		self.log_date_time_string(),
		format%args)
	es(message)
</t>
<t tx="ekr.20040119044414.17">def __init__(self,conn,addr,server):
	asynchat.async_chat.__init__(self,conn)
	self.client_address=addr
	self.connection=conn
	self.server=server
	self.wfile = delayedSocketStream(self.socket)
	# sets the terminator : when it is received, this means that the
	# http request is complete ; control will be passed to
	# self.found_terminator
	self.set_terminator ('\r\n\r\n')
	self.buffer=cStringIO.StringIO()
	self.found_terminator=self.handle_request_line
</t>
<t tx="ekr.20040119044414.18">def collect_incoming_data(self,data):
	"""Collects the data arriving on the connexion"""
	self.buffer.write(data)
</t>
<t tx="ekr.20040119044414.19">def prepare_POST(self):
	"""Prepare to read the request body"""
	bytesToRead = int(self.headers.getheader('content-length'))
	# set terminator to length (will read bytesToRead bytes)
	self.set_terminator(bytesToRead)
	self.buffer=cStringIO.StringIO()
	# control will be passed to a new found_terminator
	self.found_terminator=self.handle_post_data
</t>
<t tx="ekr.20040119044414.20">def handle_post_data(self):
	"""Called when a POST request body has been read"""
	self.rfile=cStringIO.StringIO(self.buffer.getvalue())
	self.do_POST()
	self.finish()
</t>
<t tx="ekr.20040119044414.21"></t>
<t tx="ekr.20040119044414.22">def add_leo_links(self, window, node, f):
	"""
	Given a node 'node', add links to:
		The next sibling, if any.
		the next node.
		the parent.
		The children, if any.
	"""

	# Collecting the navigational links.
	if node is None:
		# top level
		child = window.c.rootVnode()
		children = [child]
		next = child.next()
		while next:
			child = next
			children.append(child)
			next = child.next()
		nodename = window.shortFileName()
	else:
		nodename = node.headString()
		threadNext = node.threadNext()
		sibling = node.next()
		parent = node.parent()

		children = []
		firstChild = node.firstChild()
		if firstChild:
			child = firstChild
			while child:
				children.append(child)
				child = child.next()

		if threadNext is not None:
			self.create_leo_reference(window, threadNext,  "next", f)
		f.write("&lt;br&gt;")
		if sibling is not None:
			self.create_leo_reference(window, sibling, "next Sibling", f)
		f.write("&lt;br&gt;")
		if parent is None:
			self.create_href("/", "Top level", f)
		else:
			self.create_leo_reference(window, parent, "Up", f)
		f.write("&lt;br&gt;")
		
	if children:
		f.write("&lt;h2&gt;")
		f.write("Children of ")
		f.write_escaped(nodename)
		f.write("&lt;/h2&gt;\n")
		f.write("&lt;ol&gt;\n")
		for child in children:
			f.write("&lt;li&gt;\n")
			self.create_leo_reference(window, child, child.headString(), f)
		f.write("&lt;/ol&gt;\n")</t>
<t tx="ekr.20040119044414.23">def create_href(self, href, text, f):
	f.write('&lt;a href="%s"&gt;' % href)
	f.write_escaped(text)
	f.write("&lt;/a&gt;\n")

</t>
<t tx="ekr.20040119044414.24">def create_leo_reference(self, window, node, text, f):
	"""
	Create a reference to 'node' in 'window', displaying 'text'
	"""
	parts = [window.shortFileName()] + self.get_leo_nameparts(node)
	href = '_'.join(parts)
	self.create_href(href, text, f)
</t>
<t tx="ekr.20040119044414.25">def format_leo_node(self, window, node):
	"""
	Given a node 'node', return the contents of that node as html text.
	
	Include some navigational references too
	"""

	if node is not None:
		headString = node.headString()
		bodyString = node.bodyString()
	else:
		headString, bodyString = "Top level", ""
	f = escaped_StringIO()
	write, write_escaped = f.write, f.write_escaped
	write("&lt;title&gt;")
	write_escaped(window.shortFileName() + ":" + headString)
	write("&lt;/title&gt;\n")
	# write navigation
	self.add_leo_links(window, node, f)
	# write path
	self.write_path(node, f)
	write("&lt;hr&gt;\n") # horizontal rule
	# f.write('&lt;span style="font-family: monospace;"&gt;')
	write_escaped(bodyString)
	# f.write("&lt;/span&gt;\n")
	return f</t>
<t tx="ekr.20040119044414.26">def get_leo_nameparts(self, node):
	"""
	Given a 'node', construct a list of sibling numbers to get to that node.
	"""
	result = []
	cnode = node
	parent = cnode.parent()
	while parent:
		i = 0
		child = parent.firstChild()
		while child != cnode:
			child = child.next()
			i += 1
		result.append(str(i))
		cnode = parent
		parent = cnode.parent()
	i = 0
	previous = cnode.back()
	while previous:
		i += 1
		previous = previous.back()
	result.append(str(i))
	result.reverse()
	return result
</t>
<t tx="ekr.20040119044414.27">def get_leo_node(self, path):
	"""
	given a path of the form:
		&lt;short filename&gt;_&lt;number1&gt;_&lt;number2&gt;...&lt;numbern&gt;
		identify the leo node which is in that file, and,
		from top to bottom, is the &lt;number1&gt; child of the topmost
		node, the &lt;number2&gt; child of that node, and so on.
		
		Return None if that node can not be identified that way.
	"""
	# Identify the window
	for w in app().windowList:
		if w.shortFileName() == path[0]:
			break
	else:
		return None, None
		
	node = w.c.rootVnode()
	
	if len(path) &gt;= 2:
		for i in range(int(path[1])):
			node = node.next()
			if node is None:
				raise nodeNotFound
		# go to the i'th child for each path element.
		for i in path[2:]:
			node = node.nthChild(int(i))
			if node is None:
				raise nodeNotFound
	else:
		node = None
	return w, node</t>
<t tx="ekr.20040119044414.28">def get_leo_windowlist(self):
	"""
 
	"""
	f = escaped_StringIO()
	write, write_escaped = f.write, f.write_escaped
	write("&lt;title&gt;ROOT for LEO HTTP plugin&lt;/title&gt;\n")
	write("&lt;h2&gt;Windowlist&lt;/h2&gt;\n")
	write("&lt;hr&gt;\n") # horizontal rule
	write("&lt;ul&gt;\n")
	a = app() # get the singleton application instance.
	windows = a.windowList # get the list of all open frames.
	for w in windows:
		write("&lt;li&gt;")
		shortfilename = w.shortFileName()
		write('&lt;a href="%s"&gt;' % shortfilename)
		write("file name: %s" % shortfilename)
		write("&lt;/a&gt;\n")
	write("&lt;/ul&gt;\n")
	write("&lt;hr&gt;\n")
	return f
</t>
<t tx="ekr.20040119044414.29">def write_path(self, node, f):
	result = []
	while node:
		result.append(node.headString())
		node = node.parent()
	result.reverse()
	if result:
		result2 = result[:-1]
		if result2:
			result2 = ' / '.join(result2)
			f.write("&lt;br&gt;\n")
			f.write_escaped(result2)
			f.write("&lt;br&gt;\n")
		f.write("&lt;h2&gt;")
		f.write_escaped(result[-1])
		f.write("&lt;/h2&gt;\n")</t>
<t tx="ekr.20040119044414.30">def send_head(self):
	"""Common code for GET and HEAD commands.

	 This sends the response code and MIME headers.

	 Return value is either a file object (which has to be copied
	 to the outputfile by the caller unless the command was HEAD,
	 and must be closed by the caller under all circumstances), or
	 None, in which case the caller has nothing further to do.

	 """
	try:
		path = self.split_leo_path(self.path)
		if path == '/':
			 f = self.get_leo_windowlist()
		else:
			try:
				window, node = self.get_leo_node(path)
				if window is None:
					self.send_error(404, "File not found")
					return None
				f = self.format_leo_node(window, node)
			except nodeNotFound:
				self.send_error(404, "Node not found")
				return None
		length = f.tell()
		f.seek(0)
		self.send_response(200)
		self.send_header("Content-type", "text/html")
		self.send_header("Content-Length", str(length))
		self.end_headers()
		return f
	except:
		import traceback
		traceback.print_exc()
		raise

</t>
<t tx="ekr.20040119044414.31">def split_leo_path(self, path):
	"""
	A leo node is represented by a string of the form:
		&lt;number1&gt;_&lt;number2&gt;...&lt;numbern&gt;,
	where &lt;number&gt; is the number of sibling of the node.
	"""
	if path == '/':
		return '/'
	if path.startswith("/"):
		path = path[1:]
	return path.split('_')</t>
<t tx="ekr.20040119044414.32">def do_GET(self):
	"""Begins serving a GET request"""
	# nothing more to do before handle_data()
	self.handle_data()
</t>
<t tx="ekr.20040119044414.33">def do_POST(self):
	"""Begins serving a POST request. The request data must be readable
	 on a file-like object called self.rfile"""
	ctype, pdict = cgi.parse_header(self.headers.getheader('content-type'))
	length = int(self.headers.getheader('content-length'))
	if ctype == 'multipart/form-data':
		query=cgi.parse_multipart(self.rfile, pdict)
	elif ctype == 'application/x-www-form-urlencoded':
		qs=self.rfile.read(length)
		query=cgi.parse_qs(qs, keep_blank_values=1)
	else:
		query = ''                   # Unknown content-type
	# some browsers send 2 more bytes...
	[ready_to_read,x,y]=select.select([self.connection],[],[],0)
	if ready_to_read:
		self.rfile.read(2)

	self.QUERY.update(self.query(query))
	self.handle_data()
</t>
<t tx="ekr.20040119044414.34">def query(self,parsedQuery):
	"""Returns the QUERY dictionary, similar to the result of cgi.parse_qs
	 except that :
	 - if the key ends with [], returns the value (a Python list)
	 - if not, returns a string, empty if the list is empty, or with the
	 first value in the list"""
	res={}
	for item in parsedQuery.keys():
		value=parsedQuery[item] # a Python list
		if item.endswith("[]"):
				res[item[:-2]]=value
		else:
				if len(value)==0:
					res[item]=''
				else:
					res[item]=value[0]
	return res
</t>
<t tx="ekr.20040119044414.35">def handle_data(self):
	"""Class to override"""
	f = self.send_head()
	if f:
		self.copyfile(f, self.wfile)
</t>
<t tx="ekr.20040119044414.36">def handle_request_line(self):
	"""Called when the http request line and headers have been received"""

	# prepare attributes needed in parse_request()
	self.rfile=cStringIO.StringIO(self.buffer.getvalue())
	self.raw_requestline=self.rfile.readline()
	self.parse_request()

	# if there is a Query String, decodes it in a QUERY dictionary
	self.path_without_qs,self.qs=self.path,''
	if self.path.find('?')&gt;=0:
		self.qs=self.path[self.path.find('?')+1:]
		self.path_without_qs=self.path[:self.path.find('?')]
	self.QUERY=self.query(cgi.parse_qs(self.qs,1))

	if self.command in ['GET','HEAD']:
		# if method is GET or HEAD, call do_GET or do_HEAD and finish
		method="do_"+self.command
		if hasattr(self,method):
				getattr(self,method)()
				self.finish()
	elif self.command=="POST":
		# if method is POST, call prepare_POST, don't finish before
		self.prepare_POST()
	else:
		self.send_error(501, "Unsupported method (%s)" %self.command)
</t>
<t tx="ekr.20040119044414.37">def finish(self):
	"""Reset terminator (required after POST method), then close"""
	self.set_terminator ('\r\n\r\n')
	self.wfile.initiate_sending()
	# self.close()</t>
<t tx="ekr.20040119044414.38">class Server(asyncore.dispatcher):
	"""Copied from http_server in medusa"""
	@others
</t>
<t tx="ekr.20040119044414.39">def __init__ (self, ip, port,handler):
	self.ip = ip
	self.port = port
	self.handler=handler
	asyncore.dispatcher.__init__ (self)
	self.create_socket (socket.AF_INET, socket.SOCK_STREAM)

	self.set_reuse_addr()
	self.bind ((ip, port))

	# lower this to 5 if your OS complains
	self.listen (1024)
</t>
<t tx="ekr.20040119044414.40">def handle_accept (self):
	try:
		conn, addr = self.accept()
	except socket.error:
		self.log_info ('warning: server accept() threw an exception', 'warning')
		return
	except TypeError:
		self.log_info ('warning: server accept() threw EWOULDBLOCK', 'warning')
		return
	# creates an instance of the handler class to handle the request/response
	# on the incoming connexion
	self.handler(conn,addr,self)
</t>
<t tx="ekr.20040119044414.41">def poll(timeout=0.0):
	global sockets_to_close
	map = asyncore.socket_map
	if not map:
		return False
	while 1:
		r = []; w = []; e = []
		for fd, obj in map.items():
			if obj.readable():
				r.append(fd)
			if obj.writable():
				w.append(fd)
		if not sockets_to_close: # Set by writeable()
			break
		for s in sockets_to_close:
			s.close()
		sockets_to_close = []
	if [] == r == w == e:
		time.sleep(timeout)
	else:
		&lt;&lt; try r, w, e = select.select &gt;&gt;
	for fd in r:
		&lt;&lt; asyncore.read(map.get(fd)) &gt;&gt;
	for fd in w:
		&lt;&lt; asyncore.write(map.get(fd)) &gt;&gt;
	return len(r) &gt; 0 or len(w) &gt; 0
</t>
<t tx="ekr.20040119044414.42">def loop(timeout=5.0, use_poll=0, map=None):
	"""
	Override the loop function of asynchore.
	We poll only until there is not read or
	write request pending.
	"""
	return poll(timeout)</t>
<t tx="ekr.20040119044414.43">def plugin_wrapper(tag, keywords):
	first = True
	while loop(timeout):
		pass</t>
<t tx="ekr.20040119044414.44"></t>
<t tx="ekr.20040119044414.45">def a_read(obj):
	try:
		obj.handle_read_event()
	except asyncore.ExitNow:
		raise
	except:
		obj.handle_error()


</t>
<t tx="ekr.20040119044414.46">def applyConfiguration(config=None):

	"""Called when the user presses the "Apply" button on the Properties form"""

	global timeout, port, active

	if config is None:
		fileName = os.path.join(app().loadDir,"../","plugins","mod_http.ini")
		config = ConfigParser.ConfigParser()
		config.read(fileName)

	timeout = config.getint("Main", "timeout") / 1000.0
	port = config.getint("Main", "port")
	active = config.getboolean("Main", "active")</t>
<t tx="ekr.20040119044414.48">[Main]
active = True
# Should serving be enabled?

port = 8080
# port to be used by the server

timeout = 0
# timeout in miliseconds

</t>
<t tx="ekr.20040119064609">try:
	r, w, e = select.select(r, w, e, timeout)
except select.error, err:
	if err[0] != EINTR:
		raise
	else:
		return False # EKR: added return value.</t>
<t tx="ekr.20040119064609.1">obj = map.get(fd)
if obj is not None:
	asyncore.read(obj)</t>
<t tx="ekr.20040119064609.2"> obj = map.get(fd)
 if obj is not None:
	asyncore.write(obj)
</t>
<t tx="ekr.20040119102021"></t>
<t tx="ekr.20040119102021.1"></t>
<t tx="ekr.20040119102021.2"></t>
<t tx="ekr.20040119102021.3">@
Use this plugin is as follows:

1. Start Leo with the plugin enabled.  You will see a purple message that says something like:

"http serving enabled on port 8080, version 0.9"

2. Start a web browser, and enter the following url: http://localhost:8080/

You will see a a "top" level page containing one link for every open .leo file.  Start clicking :-)

You can use the browser's refresh button to update the top-level view in the browser after you have opened or closed files.</t>
<t tx="ekr.20040126115840"></t>
<t tx="ekr.20040127111023">"""Classes to add helpers to the toolbar 
 
A helper is a class that adds a set of preconfigured nodes to the outline. This 
can be used to generate boiler plate code to quickly build an outline. The nodes 
and body text added can have an adjustable parameter, which is defined from 
the text entry box. 
 
"""

USE_FIXED_SIZES = 1</t>
<t tx="ekr.20040127111023.1">class FlatOptionMenu(Tkinter.OptionMenu):

	"""Flat version of OptionMenu which allows the user to select a value from a menu."""

	def __init__(self, master, variable, value, *values, **kwargs):
		"""Construct an optionmenu widget with the parent MASTER, with 
		the resource textvariable set to VARIABLE, the initially selected 
		value VALUE, the other menu values VALUES and an additional 
		keyword argument command.""" 
		kw = {
			"borderwidth": 2, "textvariable": variable,
			"indicatoron": 1, "relief": "flat", "anchor": "c",
			"highlightthickness": 2}
		Tkinter.Widget.__init__(self, master, "menubutton", kw)
		self.widgetName = 'tk_optionMenu' 
		menu = self.__menu = Tkinter.Menu(self, name="menu", tearoff=0)
		self.menuname = menu._w
		# 'command' is the only supported keyword 
		callback = kwargs.get('command')
		if kwargs.has_key('command'):
			del kwargs['command']
		if kwargs:
			raise TclError, 'unknown option -'+kwargs.keys()[0]
		menu.add_command(label=value,
			command=Tkinter._setit(variable, value, callback))
		for v in values:
			menu.add_command(label=v,
				command=Tkinter._setit(variable, v, callback))
		self["menu"] = menu</t>
<t tx="ekr.20040127111023.2">class Node: 
	"""A node to add"""

	def __init__(self, name="", body="", inherit=0, subnodes=None):
		"""Initialise the node"""
		self.name = name
		self.body = body
		self.subnodes = subnodes or []
		self.inherit = inherit # Set true to inherit the first line from our immediate sibling 

	def processText(self, text, name):
		"""Process some boiler plate text"""
		if name: 
			text = text.replace("XXX", name)
			text = text.replace("xxx", name.lower())
		return text.strip()

	def addTo(self, c, text, parent=None): 
		"""Add our nodes etc"""
		if self.inherit:
			header = c.currentVnode().bodyString().split("\n")[0] + "\n"
		else:
			header = ""
		# 
		c.insertHeadline()
		main = c.currentVnode()
		main.setHeadString(self.processText(self.name, text))
		# 
		main.setBodyStringOrPane(self.processText(header+self.body, text))
		if parent: 
			c.currentVnode().moveToNthChildOf(parent, 0) 
		# 
		parent = c.currentVnode()
		for node in self.subnodes:
			node.addTo(c, text, parent)
			parent = None # Only want first node to be moved, others will go automatically </t>
<t tx="ekr.20040127111023.3">class NodeAdder:

	"""A Class to add a helper button to the toolbar which adds nodes to the outline""" 

	button_name = "Add"

	nodes = () # Should be set in the subclasses 

	def doIt(self, entry):
		"""Create the nodes"""
		c = top()
		name = entry.get()
		for node in self.nodes:
			node.addTo(c, name)</t>
<t tx="ekr.20040127111023.4">class Helper:

	"""A Class to aid in the creating and maintenance of unit test files"""

	def __init__(self, adders):

		"""Initialise with a set of adders"""
	
		self.adders = adders

	def addWidgets(self, tags, keywords):

		"""Add the widgets to Leo"""
		self.commander = keywords['c']
		toolbar = self.commander.frame.iconFrame
		# 
		self.frame = Tkinter.Frame(toolbar)
		self.frame.pack(side="right", padx=2)
		# 
		self.text = Tkinter.Entry(self._getSizer(self.frame, 24, 130))
		self.text.pack(side="left", padx=3, fill="both", expand=1)
		self.text.bind("&lt;Return&gt;", self.doCallback)
		# 
		self.pseudobutton = Tkinter.Frame(self._getSizer(self.frame, 24, 142), relief="raised", borderwidth=2) 
		self.pseudobutton.pack(side="right")
		# 
		self.doit = Tkinter.Button(self._getSizer(self.pseudobutton, 25, 32), text="New", relief="flat", command=self.doCallback)
		self.doit.pack(side="left")
		# 
		options = [adder.button_name for adder in self.adders]
		self.option_value = Tkinter.StringVar()
		self.options = FlatOptionMenu(self._getSizer(self.pseudobutton, 29, 110), self.option_value, *options)
		self.option_value.set(options[0])
		self.options.pack(side="right", fill="both", expand=1)
		
	def _getSizer(self, parent, height, width, pack="left"):
	
		"""Return a sizer object to force a Tk widget to be the right size"""
	
		if USE_FIXED_SIZES:
			sizer = Tkinter.Frame(parent, height=height, width=width)
			sizer.pack_propagate(0) # don't shrink 
			sizer.pack(side=pack)
			return sizer
		else:
			return parent
			
	def doCallback(self, event=None):

		"""Generate a callback to call the specific adder"""
		for adder in self.adders:
			if adder.button_name == self.option_value.get():
				adder.doIt(self.text)
				break
		else:
			raise ValueError("Button name not found: '%s'" % self.option_value.get())</t>
<t tx="ekr.20040127111517">'''Automatically add nodes for common tasks'''

# We must use @file-noref because data below might look like section references,
# so ORDER IS IMPORTANT throughout this tree (we can't use @others).

__name__ = "New Buttons"
__version__ = "0.2" # Converted to @file-noref by EKR.
 
from leoPlugins import *
from leoGlobals import *
import leoFind

try:    import Tkinter
except: Tkinter = None
Tk = Tkinter</t>
<t tx="ekr.20040127113621.5"># Modify these classes or data as you like to create templates that suit you.</t>
<t tx="ekr.20040127113621.6">class AddTestModule(NodeAdder):

	"""Add unit testing node"""

	button_name = "test module"

	nodes = [
		Node(
			name="testxxx.py",
			body=TEST_NODE_BODY,
			subnodes=[ 
				Node(
					name="TestXXX",
					body=TEST_CLASS_BODY,
					subnodes=[ 
						Node(name="setUp",
						body=TEST_SETUP_BODY)])])]</t>
<t tx="ekr.20040127113621.7">class AddTestClass(NodeAdder):

	"""Add unit testing class"""

	button_name = "test class"

	nodes = [
		Node(
			name="TestXXX",
			body=TEST_CLASS_BODY,
			subnodes=[
				Node(
					name="setUp",
					body=TEST_SETUP_BODY)])]</t>
<t tx="ekr.20040127113621.8">TEST_METHOD_BODY = '''
def testXXX(self):

	"""testXXX: TestDescriptionGoesHere"""

'''

class AddTestMethod(NodeAdder):

	"""Add unit testing method"""

	button_name = "test method"

	nodes = [
	Node(
		name="testXXX",
		body=TEST_METHOD_BODY,
		inherit=0)] # EKR: was 1.</t>
<t tx="ekr.20040127113621.9">NEW_CLASS_BODY = '''
class XXX:

	"""DocStringGoesHere"""

	@others
'''

NEW_INIT_BODY = '''
def __init__(self):

	"""Initialise the XXX instance"""

'''

class AddClass(NodeAdder):
	
	"""Add new class"""

	button_name = "class"

	nodes = [
		Node(
			name="class XXX",
			body=NEW_CLASS_BODY,
			subnodes=[
				#Node(
				#	name="&lt;&lt; class XXX declarations &gt;&gt;",
				#	body="@c\npass"),
				Node(
					name="__init__",
					body=NEW_INIT_BODY)] )]
</t>
<t tx="ekr.20040127113621.10">CLASS_METHOD_BODY = '''
def XXX(self):

	"""MethodDocstringGoesHere"""

'''

class AddClassMethod(NodeAdder):

	"""Add class method"""

	button_name = "method"

	nodes = [
		Node(
			name="XXX",
			body=CLASS_METHOD_BODY,
			inherit=0)] # EKR: was 1.</t>
<t tx="ekr.20040127114616">if Tkinter:

	if app.gui is None:
		app.createTkGui(__file__)

	if app.gui.guiName() == "tkinter":
	
		es("Activating newButtons", color="orange")

		buttonList = [
			AddTestModule(),AddTestClass(),
			AddTestMethod(),AddClass(),AddClassMethod()]
	
		helper = Helper(buttonList)

		registerHandler("after-create-leo-frame", helper.addWidgets)
		plugin_signon("newButtons")</t>
<t tx="ekr.20040127120834">TEST_NODE_BODY = '''
import unittest

@others

if __name__ == "__main__":
	unittest.main()
'''

TEST_CLASS_BODY = '''
class TestXXX(unittest.TestCase):

	"""Tests for the XXX class"""

	@others
'''

TEST_SETUP_BODY = '''
def setUp(self):

	"""Create the test fixture"""

'''</t>
<t tx="ekr.20040129151121"></t>
<t tx="ekr.20040130165735"></t>
<t tx="ekr.20040201060959">"""Adds status line to Leo window."""

from leoPlugins import *
from leoGlobals import *

try:
	import Tkinter
except ImportError:
	Tkinter = None

if Tkinter: # Register the handlers...

	def createStatusLine(tag,keywords):
		c = keywords.get("c")
		c.frame.createStatusLine()
		c.frame.putStatusLine("Welcome to Leo")

	if app.gui is None:
		app.createTkGui(__file__)

	if app.gui.guiName() == "tkinter":
		registerHandler("after-create-leo-frame", createStatusLine)
		__version__ = "0.1"
		plugin_signon(__name__)</t>
<t tx="ekr.20040201061422"></t>
<t tx="ekr.20040201061422.1"></t>
<t tx="ekr.20040201061422.2">This creates a status area at the bottom of the Leo Window.  Plugins may write to this area using the status area convenience routines in leoTkinterFrame.py.</t>
<t tx="ekr.20040205071616">"""
mnplugins.py

mnplugins shows how to :
define new Commands  "insertOK" + "insertUser"
create Usermenu with new Commands

new Commands:
insertOK: 
    insert 'OK' in headline and a stamp in the first bodyline
    are there childnodes without 'OK' verhindern OK in actual node
    (insertOK on iconrclick2 too)

insertUser : Shift-F6
	insert a &lt;user/date/time&gt; stamp at the current location in bodytext
	
"""

from leoPlugins import *
from leoGlobals import *

import leoCommands
import time

OKFLAG='OK '  # Space required.

@others

try:
	import Tkinter
except ImportError:
	Tkinter = None
Tk = Tkinter

if Tkinter: 

	if app.gui is None:
		app.createTkGui(__file__)

	if app.gui.guiName() == "tkinter":
		registerHandler("start1", onStart)
		registerHandler("create-optional-menus",create_UserMenu)
		registerHandler("iconrclick2", onRclick)

		__version__ = "0.1"
		plugin_signon(__name__)
		es('mnplug OK+Commands+Menu aktiv',color='green')
		
</t>
<t tx="ekr.20040205071616.1">def mnstamp():

	lt=time.localtime(time.time())
	mndatetime=time.strftime('%y%m%d %H:%M',(lt))
	return '### '+app.leoID+mndatetime


</t>
<t tx="ekr.20040205071616.2">def mnOKstamp():

	lt=time.localtime(time.time())
	mndatetime=time.strftime('%y%m%d %H:%M',(lt))
	return '###'+OKFLAG+app.leoID+mndatetime
</t>
<t tx="ekr.20040205071616.3">def onStart (tag,keywords):

	# insert function insertUser as method of class Commands at runtime
	funcToMethod(insertUser,leoCommands.Commands)
	funcToMethod(insertOKcmd,leoCommands.Commands)

</t>
<t tx="ekr.20040205071616.4">def setHeadOK(v):

	s = OKFLAG + v.headString()
	v.setHeadStringOrHeadline(s)

</t>
<t tx="ekr.20040205071616.5">def insertBodystamp(c,v):

	stamp=mnOKstamp()+'\n'

	# insertAtBegin - ??!! workaround ??!! 
	# insertPointFormat is  ('row.column')
	
	oldip=c.frame.body.getInsertionPoint()
	newip=str(int(string.split(oldip,'.')[0])+1)+'.'+string.split(oldip,'.')[1]

	c.frame.body.setInsertionPoint('0.0')
	c.frame.body.insertAtInsertPoint(stamp)
	c.frame.body.setInsertionPoint(newip)
	c.frame.body.onBodyChanged(v,"Typing")</t>
<t tx="ekr.20040205071616.6">def is_subnodesOK(v):

	if not v.hasChildren():
		return true
	else:
		ok = false
		child=v.firstChild()
		while child:
			s=child.headString()
			ok=s[0:len(OKFLAG)]==OKFLAG
			if not ok:break
			child=child.next()
	return ok

</t>
<t tx="ekr.20040205071616.7">def onRclick(tag,keywords):
	
	"""Handle right click in body pane."""

	c=keywords.get('c')
	insertOKcmd(c)</t>
<t tx="ekr.20040205071616.8">def insertOKcmd(self,event=None):

	c=self; v=c.currentVnode()  
	
	if is_subnodesOK(v) :
		setHeadOK(v)
		insertBodystamp(c,v)
	else: 
		es('OK in child missing')</t>
<t tx="ekr.20040205071616.9">def insertUser (self,event=None):
	
	"""Handle the Insert User command."""

	c = self ; v = c.currentVnode()
	
	oldSel = c.frame.body.getTextSelection()
	c.frame.body.deleteTextSelection() # Works if nothing is selected.
	
	s = mnstamp()
	
	c.frame.body.insertAtInsertPoint(s)
	c.frame.body.onBodyChanged(v,"Typing",oldSel=oldSel)</t>
<t tx="ekr.20040205071616.10">def create_UserMenu (tag,keywords):

	c = keywords.get("c")
	
	c.pluginsMenu = c.frame.menu.createNewMenu("UserMenu")

	table = [
		("insUser", 'Shift+F6', c.insertUser),
		("insOK",'Ctrl+Shift+O',c.insertOKcmd)]

	c.frame.menu.createMenuEntries(c.pluginMenu,table)</t>
<t tx="ekr.20040211080148">"""Add Hoist/De-Hoist buttons to the toolbar.
"""

# By Davide Salomoni.

__version__ = "0.2" # Color mod by EKR.

from leoPlugins import *
from leoGlobals import *

try:
	import Tkinter
except ImportError:
	Tkinter = None
Tk = Tkinter

activeHoistColor = "pink1" # The Tk color to use for the active hoist button.

# Set this to 0 if the sizing of the toolbar controls doesn't look good on your platform. 
USE_FIXED_SIZES = 1 

@others

if Tkinter:
	hoist = HoistButtons()
	
	if app.gui is None:
		app.createTkGui(__file__)
	
	if app.gui.guiName() == "tkinter":
		registerHandler("after-create-leo-frame", hoist.addWidgets)
		registerHandler("idle", hoist.onIdle)
		plugin_signon(__name__)
</t>
<t tx="ekr.20040211080148.1">class HoistButtons:
	"""Hoist/dehoist buttons for the toolbar."""
	@others</t>
<t tx="ekr.20040211080148.2">def _getSizer(self, parent, height, width):
	"""Return a sizer object to force a Tk widget to be the right size"""
	if USE_FIXED_SIZES: 
		sizer = Tkinter.Frame(parent, height=height, width=width)
		sizer.pack_propagate(0) # don't shrink 
		sizer.pack(side="right")
		return sizer
	else:
		return parent</t>
<t tx="ekr.20040211080148.3">def addWidgets(self, tags, keywords):
	"""Add the widgets to the toolbar."""
	self.c = keywords['c'] 
	toolbar = self.c.frame.iconFrame
	# Button De-Hoist
	self.hoistOff = Tkinter.Button(self._getSizer(toolbar, 25, 70), text="De-Hoist", command=self.doHoistOff)
	self.hoistOff.pack(side="right", fill="both", expand=1)
	# Button Hoist
	self.hoistOn = Tkinter.Button(self._getSizer(toolbar, 25, 70), text="Hoist", command=self.doHoistOn)
	self.hoistOn.pack(side="left", fill="both", expand=1)
	self.bgColor = self.hoistOn["background"]
	self.activeBgColor = self.hoistOn["activebackground"]
</t>
<t tx="ekr.20040211080148.4">def doHoistOn(self, *args, **keys):
	self.c.hoist()
</t>
<t tx="ekr.20040211080148.5">def doHoistOff(self, *args, **keys):
	self.c.dehoist()
</t>
<t tx="ekr.20040211080148.6">def onIdle(self, tag, keywords):
	
	c = self.c

	if not hasattr(c,"hoistStack"):
		return
	
	if len(c.hoistStack) &gt; 0:
		self.hoistOn.config(bg=activeHoistColor)
		self.hoistOn.config(activebackground=activeHoistColor)
		self.hoistOn.config(text="Hoist %s" % len(c.hoistStack))
	else:
		self.hoistOn.config(bg=self.bgColor)
		self.hoistOn.config(activebackground=self.activeBgColor)
		self.hoistOn.config(text="Hoist")</t>
</tnodes>
</leo_file>
