wxPython-zombie 3.1.5.8__cp313-cp313-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1175) hide show
  1. wx/__init__.py +22 -0
  2. wx/__version__.py +9 -0
  3. wx/_adv.cp313-win_amd64.pyd +0 -0
  4. wx/_aui.cp313-win_amd64.pyd +0 -0
  5. wx/_core.cp313-win_amd64.pyd +0 -0
  6. wx/_dataview.cp313-win_amd64.pyd +0 -0
  7. wx/_glcanvas.cp313-win_amd64.pyd +0 -0
  8. wx/_grid.cp313-win_amd64.pyd +0 -0
  9. wx/_html.cp313-win_amd64.pyd +0 -0
  10. wx/_html2.cp313-win_amd64.pyd +0 -0
  11. wx/_media.cp313-win_amd64.pyd +0 -0
  12. wx/_msw.cp313-win_amd64.pyd +0 -0
  13. wx/_propgrid.cp313-win_amd64.pyd +0 -0
  14. wx/_ribbon.cp313-win_amd64.pyd +0 -0
  15. wx/_richtext.cp313-win_amd64.pyd +0 -0
  16. wx/_stc.cp313-win_amd64.pyd +0 -0
  17. wx/_xml.cp313-win_amd64.pyd +0 -0
  18. wx/_xrc.cp313-win_amd64.pyd +0 -0
  19. wx/adv.py +124 -0
  20. wx/adv.pyi +5182 -0
  21. wx/aui.py +77 -0
  22. wx/aui.pyi +3655 -0
  23. wx/core.py +3540 -0
  24. wx/core.pyi +50592 -0
  25. wx/dataview.py +173 -0
  26. wx/dataview.pyi +3491 -0
  27. wx/demo/AUI_DockingWindowMgr.py +1154 -0
  28. wx/demo/AUI_MDI.py +117 -0
  29. wx/demo/AUI_Notebook.py +58 -0
  30. wx/demo/About.py +75 -0
  31. wx/demo/AboutBox.py +75 -0
  32. wx/demo/ActiveXWrapper_Acrobat.py +132 -0
  33. wx/demo/ActiveXWrapper_IE.py +187 -0
  34. wx/demo/ActiveX_FlashWindow.py +107 -0
  35. wx/demo/ActiveX_IEHtmlWindow.py +242 -0
  36. wx/demo/ActiveX_PDFWindow.py +204 -0
  37. wx/demo/ActivityIndicator.py +80 -0
  38. wx/demo/AddPrivateFont.py +116 -0
  39. wx/demo/AdjustChannels.py +178 -0
  40. wx/demo/AlphaDrawing.py +77 -0
  41. wx/demo/AnalogClock.py +144 -0
  42. wx/demo/AnimationCtrl.py +104 -0
  43. wx/demo/ArtProvider.py +893 -0
  44. wx/demo/BannerWindow.py +1 -0
  45. wx/demo/BitmapButton.py +87 -0
  46. wx/demo/BitmapComboBox.py +63 -0
  47. wx/demo/BitmapFromBuffer.py +140 -0
  48. wx/demo/Button.py +77 -0
  49. wx/demo/Cairo.py +197 -0
  50. wx/demo/Cairo_Snippets.py +135 -0
  51. wx/demo/Calendar.py +660 -0
  52. wx/demo/CalendarCtrl.py +122 -0
  53. wx/demo/CheckBox.py +74 -0
  54. wx/demo/CheckListBox.py +79 -0
  55. wx/demo/CheckListCtrl.py +99 -0
  56. wx/demo/Choice.py +55 -0
  57. wx/demo/Choicebook.py +80 -0
  58. wx/demo/CollapsibleHeaderCtrl.py +85 -0
  59. wx/demo/CollapsiblePane.py +126 -0
  60. wx/demo/ColorPanel.py +19 -0
  61. wx/demo/ColourDB.py +203 -0
  62. wx/demo/ColourDialog.py +76 -0
  63. wx/demo/ColourSelect.py +119 -0
  64. wx/demo/ComboBox.py +111 -0
  65. wx/demo/ComboCtrl.py +153 -0
  66. wx/demo/ComboTreeBox.py +71 -0
  67. wx/demo/CommandLinkButton.py +50 -0
  68. wx/demo/ContextHelp.py +112 -0
  69. wx/demo/Cursor.py +336 -0
  70. wx/demo/CustomDragAndDrop.py +353 -0
  71. wx/demo/DVC_CustomRenderer.py +204 -0
  72. wx/demo/DVC_DataViewModel.py +365 -0
  73. wx/demo/DVC_IndexListModel.py +257 -0
  74. wx/demo/DVC_ListCtrl.py +69 -0
  75. wx/demo/DVC_TreeCtrl.py +76 -0
  76. wx/demo/DatePickerCtrl.py +68 -0
  77. wx/demo/DelayedResult.py +239 -0
  78. wx/demo/Dialog.py +169 -0
  79. wx/demo/DialogUnits.py +128 -0
  80. wx/demo/DirDialog.py +58 -0
  81. wx/demo/DragAndDrop.py +265 -0
  82. wx/demo/DragImage.py +316 -0
  83. wx/demo/DragScroller.py +59 -0
  84. wx/demo/DrawXXXList.py +436 -0
  85. wx/demo/DynamicSashWindow.py +177 -0
  86. wx/demo/EditableListBox.py +101 -0
  87. wx/demo/Editor.py +70 -0
  88. wx/demo/EventManager.py +291 -0
  89. wx/demo/ExpandoTextCtrl.py +164 -0
  90. wx/demo/FancyText.py +83 -0
  91. wx/demo/FileBrowseButton.py +100 -0
  92. wx/demo/FileCtrl.py +97 -0
  93. wx/demo/FileDialog.py +144 -0
  94. wx/demo/FileHistory.py +140 -0
  95. wx/demo/FindReplaceDialog.py +123 -0
  96. wx/demo/FloatCanvas.py +1959 -0
  97. wx/demo/FontDialog.py +142 -0
  98. wx/demo/FontEnumerator.py +82 -0
  99. wx/demo/Frame.py +85 -0
  100. wx/demo/GLCanvas.py +371 -0
  101. wx/demo/Gauge.py +66 -0
  102. wx/demo/GenericButtons.py +185 -0
  103. wx/demo/GenericCheckBox.py +65 -0
  104. wx/demo/GenericDirCtrl.py +74 -0
  105. wx/demo/GetMouseState.py +159 -0
  106. wx/demo/GraphicsContext.py +236 -0
  107. wx/demo/GraphicsGradient.py +281 -0
  108. wx/demo/Grid.py +95 -0
  109. wx/demo/GridBagSizer.py +170 -0
  110. wx/demo/GridCustEditor.py +247 -0
  111. wx/demo/GridCustTable.py +170 -0
  112. wx/demo/GridDragAndDrop.py +102 -0
  113. wx/demo/GridDragable.py +206 -0
  114. wx/demo/GridEnterHandler.py +66 -0
  115. wx/demo/GridHugeTable.py +89 -0
  116. wx/demo/GridLabelRenderer.py +114 -0
  117. wx/demo/GridSimple.py +270 -0
  118. wx/demo/GridStdEdRend.py +186 -0
  119. wx/demo/Grid_MegaExample.py +490 -0
  120. wx/demo/HTML2_WebView.py +183 -0
  121. wx/demo/HtmlWindow.py +232 -0
  122. wx/demo/I18N.py +237 -0
  123. wx/demo/Image.py +338 -0
  124. wx/demo/ImageAlpha.py +87 -0
  125. wx/demo/ImageBrowser.py +70 -0
  126. wx/demo/ImageFromStream.py +49 -0
  127. wx/demo/Img2PyArtProvider.py +99 -0
  128. wx/demo/InfoBar.py +127 -0
  129. wx/demo/IntCtrl.py +343 -0
  130. wx/demo/ItemsPicker.py +108 -0
  131. wx/demo/Joystick.py +1083 -0
  132. wx/demo/KeyEvents.py +428 -0
  133. wx/demo/LEDNumberCtrl.py +121 -0
  134. wx/demo/LayoutAnchors.py +258 -0
  135. wx/demo/LayoutConstraints.py +149 -0
  136. wx/demo/Layoutf.py +69 -0
  137. wx/demo/ListBox.py +164 -0
  138. wx/demo/ListCtrl.py +538 -0
  139. wx/demo/ListCtrl_edit.py +155 -0
  140. wx/demo/ListCtrl_virtual.py +145 -0
  141. wx/demo/Listbook.py +104 -0
  142. wx/demo/MDIDemo.py +86 -0
  143. wx/demo/MDISashDemo.py +152 -0
  144. wx/demo/MDIWindows.py +66 -0
  145. wx/demo/Main.py +2768 -0
  146. wx/demo/Mask.py +137 -0
  147. wx/demo/MaskedEditControls.py +648 -0
  148. wx/demo/MaskedNumCtrl.py +359 -0
  149. wx/demo/MediaCtrl.py +190 -0
  150. wx/demo/Menu.py +322 -0
  151. wx/demo/MessageDialog.py +54 -0
  152. wx/demo/MimeTypesManager.py +354 -0
  153. wx/demo/MiniFrame.py +67 -0
  154. wx/demo/MouseGestures.py +198 -0
  155. wx/demo/MultiChoiceDialog.py +59 -0
  156. wx/demo/MultiSash.py +95 -0
  157. wx/demo/MultiSplitterWindow.py +168 -0
  158. wx/demo/MultipleChoiceDialog.py +101 -0
  159. wx/demo/Notebook.py +134 -0
  160. wx/demo/NotificationMessage.py +61 -0
  161. wx/demo/OGL.py +433 -0
  162. wx/demo/Overlay.py +209 -0
  163. wx/demo/OwnerDrawnComboBox.py +152 -0
  164. wx/demo/PDFViewer.py +109 -0
  165. wx/demo/PageSetupDialog.py +70 -0
  166. wx/demo/PenAndBrushStyles.py +208 -0
  167. wx/demo/Pickers.py +120 -0
  168. wx/demo/PlateButton.py +430 -0
  169. wx/demo/PopupControl.py +99 -0
  170. wx/demo/PopupMenu.py +156 -0
  171. wx/demo/PopupWindow.py +227 -0
  172. wx/demo/PrintDialog.py +60 -0
  173. wx/demo/PrintFramework.py +227 -0
  174. wx/demo/Process.py +168 -0
  175. wx/demo/ProgressDialog.py +87 -0
  176. wx/demo/PropertyGrid.py +1045 -0
  177. wx/demo/PropertySheetDialog.py +231 -0
  178. wx/demo/PseudoDC.py +350 -0
  179. wx/demo/PyColourChooser.py +60 -0
  180. wx/demo/PyCrust.py +21 -0
  181. wx/demo/PyPlot.py +83 -0
  182. wx/demo/PyShell.py +22 -0
  183. wx/demo/PythonEvents.py +109 -0
  184. wx/demo/README.txt +7 -0
  185. wx/demo/RadioBox.py +67 -0
  186. wx/demo/RadioButton.py +127 -0
  187. wx/demo/RawBitmapAccess.py +208 -0
  188. wx/demo/RearrangeDialog.py +160 -0
  189. wx/demo/RendererNative.py +170 -0
  190. wx/demo/ResizeWidget.py +76 -0
  191. wx/demo/RichMessageDialog.py +85 -0
  192. wx/demo/RichTextCtrl.py +732 -0
  193. wx/demo/RichToolTip.py +145 -0
  194. wx/demo/SVGImage_Bitmap.py +130 -0
  195. wx/demo/SVGImage_Render.py +138 -0
  196. wx/demo/SashWindow.py +151 -0
  197. wx/demo/ScrolledMessageDialog.py +52 -0
  198. wx/demo/ScrolledPanel.py +124 -0
  199. wx/demo/ScrolledWindow.py +260 -0
  200. wx/demo/SearchCtrl.py +115 -0
  201. wx/demo/ShapedWindow.py +145 -0
  202. wx/demo/Simplebook.py +202 -0
  203. wx/demo/SingleChoiceDialog.py +56 -0
  204. wx/demo/SizedControls.py +433 -0
  205. wx/demo/Sizers.py +609 -0
  206. wx/demo/Slider.py +52 -0
  207. wx/demo/Sound.py +95 -0
  208. wx/demo/SpinButton.py +63 -0
  209. wx/demo/SpinCtrl.py +56 -0
  210. wx/demo/SpinCtrlDouble.py +42 -0
  211. wx/demo/SplitTree.py +146 -0
  212. wx/demo/SplitterWindow.py +62 -0
  213. wx/demo/StandardPaths.py +113 -0
  214. wx/demo/StaticBitmap.py +55 -0
  215. wx/demo/StaticBox.py +62 -0
  216. wx/demo/StaticText.py +69 -0
  217. wx/demo/StatusBar.py +144 -0
  218. wx/demo/StockButtons.py +113 -0
  219. wx/demo/StyledTextCtrl_1.py +303 -0
  220. wx/demo/StyledTextCtrl_2.py +410 -0
  221. wx/demo/SystemSettings.py +333 -0
  222. wx/demo/TablePrint.py +215 -0
  223. wx/demo/TestTable.txt +38 -0
  224. wx/demo/TextCtrl.py +187 -0
  225. wx/demo/TextEntryDialog.py +57 -0
  226. wx/demo/Threads.py +258 -0
  227. wx/demo/Throbber.py +250 -0
  228. wx/demo/Ticker.py +147 -0
  229. wx/demo/TimeCtrl.py +240 -0
  230. wx/demo/TimePickerCtrl.py +60 -0
  231. wx/demo/Timer.py +275 -0
  232. wx/demo/ToggleButton.py +54 -0
  233. wx/demo/ToolBar.py +249 -0
  234. wx/demo/ToolTip.py +71 -0
  235. wx/demo/Toolbook.py +111 -0
  236. wx/demo/TreeCtrl.py +199 -0
  237. wx/demo/TreeListCtrl.py +121 -0
  238. wx/demo/TreeMixin.py +269 -0
  239. wx/demo/Treebook.py +117 -0
  240. wx/demo/UIActionSimulator.py +151 -0
  241. wx/demo/URLDragAndDrop.py +130 -0
  242. wx/demo/Unicode.py +146 -0
  243. wx/demo/VListBox.py +176 -0
  244. wx/demo/Validator.py +237 -0
  245. wx/demo/Wizard.py +248 -0
  246. wx/demo/WrapSizer.py +115 -0
  247. wx/demo/XmlResource.py +80 -0
  248. wx/demo/XmlResourceHandler.py +199 -0
  249. wx/demo/XmlResourceSubclass.py +119 -0
  250. wx/demo/__init__.py +9 -0
  251. wx/demo/agw/AGWInfoBar.py +175 -0
  252. wx/demo/agw/AUI.py +3058 -0
  253. wx/demo/agw/AdvancedSplash.py +59 -0
  254. wx/demo/agw/AquaButton.py +146 -0
  255. wx/demo/agw/BalloonTip.py +378 -0
  256. wx/demo/agw/ButtonPanel.py +890 -0
  257. wx/demo/agw/CubeColourDialog.py +83 -0
  258. wx/demo/agw/CustomTreeCtrl.py +2167 -0
  259. wx/demo/agw/Example1 +67 -0
  260. wx/demo/agw/Example2 +49 -0
  261. wx/demo/agw/FlatMenu.py +876 -0
  262. wx/demo/agw/FlatNotebook.py +994 -0
  263. wx/demo/agw/FloatSpin.py +475 -0
  264. wx/demo/agw/FoldPanelBar.py +953 -0
  265. wx/demo/agw/FourWaySplitter.py +300 -0
  266. wx/demo/agw/GenericMessageDialog.py +207 -0
  267. wx/demo/agw/GradientButton.py +156 -0
  268. wx/demo/agw/HyperLinkCtrl.py +144 -0
  269. wx/demo/agw/HyperTreeList.py +2660 -0
  270. wx/demo/agw/KnobCtrl.py +186 -0
  271. wx/demo/agw/LabelBook.py +567 -0
  272. wx/demo/agw/MacLargeDemo.py +360 -0
  273. wx/demo/agw/MultiDirDialog.py +117 -0
  274. wx/demo/agw/PeakMeter.py +194 -0
  275. wx/demo/agw/PersistentControls.py +589 -0
  276. wx/demo/agw/PieCtrl.py +206 -0
  277. wx/demo/agw/PyBusyInfo.py +64 -0
  278. wx/demo/agw/PyCollapsiblePane.py +308 -0
  279. wx/demo/agw/PyGauge.py +162 -0
  280. wx/demo/agw/PyProgress.py +155 -0
  281. wx/demo/agw/RibbonBar.py +925 -0
  282. wx/demo/agw/RulerCtrl.py +454 -0
  283. wx/demo/agw/ScrolledThumbnail.py +128 -0
  284. wx/demo/agw/ShapedButton.py +603 -0
  285. wx/demo/agw/ShortcutEditor.py +397 -0
  286. wx/demo/agw/SpeedMeter.py +668 -0
  287. wx/demo/agw/SuperToolTip.py +396 -0
  288. wx/demo/agw/ThumbDemoConfig.py +603 -0
  289. wx/demo/agw/ThumbnailCtrl.py +149 -0
  290. wx/demo/agw/ToasterBox.py +410 -0
  291. wx/demo/agw/UltimateListCtrl.py +80 -0
  292. wx/demo/agw/UltimateListIconDemo.py +908 -0
  293. wx/demo/agw/UltimateListListDemo.py +124 -0
  294. wx/demo/agw/UltimateReportDemo.py +1146 -0
  295. wx/demo/agw/UltimateVirtualDemo.py +207 -0
  296. wx/demo/agw/Windows7Explorer_Contents.py +368 -0
  297. wx/demo/agw/XLSGrid.py +238 -0
  298. wx/demo/agw/ZoomBar.py +230 -0
  299. wx/demo/agw/__demo__.py +183 -0
  300. wx/demo/agw/bitmaps/Explorer96.png +0 -0
  301. wx/demo/agw/bitmaps/Explorer96Flip40.png +0 -0
  302. wx/demo/agw/bitmaps/Folder96.png +0 -0
  303. wx/demo/agw/bitmaps/Folder96Flip40.png +0 -0
  304. wx/demo/agw/bitmaps/Monitor96.png +0 -0
  305. wx/demo/agw/bitmaps/Monitor96Flip40.png +0 -0
  306. wx/demo/agw/bitmaps/Music96.png +0 -0
  307. wx/demo/agw/bitmaps/Music96Flip40.png +0 -0
  308. wx/demo/agw/bitmaps/Photo96.png +0 -0
  309. wx/demo/agw/bitmaps/Photo96Flip40.png +0 -0
  310. wx/demo/agw/bitmaps/Search96.png +0 -0
  311. wx/demo/agw/bitmaps/Search96Flip40.png +0 -0
  312. wx/demo/agw/bitmaps/Wizard96.png +0 -0
  313. wx/demo/agw/bitmaps/Wizard96Flip40.png +0 -0
  314. wx/demo/agw/bitmaps/advancedsplash.png +0 -0
  315. wx/demo/agw/bitmaps/aquabutton.png +0 -0
  316. wx/demo/agw/bitmaps/aquachecked.ico +0 -0
  317. wx/demo/agw/bitmaps/aquaflagged.ico +0 -0
  318. wx/demo/agw/bitmaps/aquanotchecked.ico +0 -0
  319. wx/demo/agw/bitmaps/aquanotflagged.ico +0 -0
  320. wx/demo/agw/bitmaps/canada.gif +0 -0
  321. wx/demo/agw/bitmaps/checked.ico +0 -0
  322. wx/demo/agw/bitmaps/columns.png +0 -0
  323. wx/demo/agw/bitmaps/contexthelp-16.png +0 -0
  324. wx/demo/agw/bitmaps/contexthelp.png +0 -0
  325. wx/demo/agw/bitmaps/copy.png +0 -0
  326. wx/demo/agw/bitmaps/cut.png +0 -0
  327. wx/demo/agw/bitmaps/editcopy.png +0 -0
  328. wx/demo/agw/bitmaps/editcut.png +0 -0
  329. wx/demo/agw/bitmaps/editpaste.png +0 -0
  330. wx/demo/agw/bitmaps/empty_icon.png +0 -0
  331. wx/demo/agw/bitmaps/exit-16.png +0 -0
  332. wx/demo/agw/bitmaps/exit.ico +0 -0
  333. wx/demo/agw/bitmaps/ffwd.png +0 -0
  334. wx/demo/agw/bitmaps/ffwddisabled.png +0 -0
  335. wx/demo/agw/bitmaps/field-16.png +0 -0
  336. wx/demo/agw/bitmaps/filenew.png +0 -0
  337. wx/demo/agw/bitmaps/fileopen.png +0 -0
  338. wx/demo/agw/bitmaps/filesave.png +0 -0
  339. wx/demo/agw/bitmaps/flagged.ico +0 -0
  340. wx/demo/agw/bitmaps/folder.png +0 -0
  341. wx/demo/agw/bitmaps/folder_new.png +0 -0
  342. wx/demo/agw/bitmaps/ghost.png +0 -0
  343. wx/demo/agw/bitmaps/gradientbutton.png +0 -0
  344. wx/demo/agw/bitmaps/help-16.png +0 -0
  345. wx/demo/agw/bitmaps/help.ico +0 -0
  346. wx/demo/agw/bitmaps/italy.gif +0 -0
  347. wx/demo/agw/bitmaps/lbadd.png +0 -0
  348. wx/demo/agw/bitmaps/lbcharge.png +0 -0
  349. wx/demo/agw/bitmaps/lbdecrypted.png +0 -0
  350. wx/demo/agw/bitmaps/lbnews.png +0 -0
  351. wx/demo/agw/bitmaps/lbroll.png +0 -0
  352. wx/demo/agw/bitmaps/minus1.ico +0 -0
  353. wx/demo/agw/bitmaps/minus2.ico +0 -0
  354. wx/demo/agw/bitmaps/minus3.ico +0 -0
  355. wx/demo/agw/bitmaps/minus4.ico +0 -0
  356. wx/demo/agw/bitmaps/minus5.ico +0 -0
  357. wx/demo/agw/bitmaps/month-16.png +0 -0
  358. wx/demo/agw/bitmaps/new_file.png +0 -0
  359. wx/demo/agw/bitmaps/new_folder.png +0 -0
  360. wx/demo/agw/bitmaps/notchecked.ico +0 -0
  361. wx/demo/agw/bitmaps/notflagged.ico +0 -0
  362. wx/demo/agw/bitmaps/ok-16.png +0 -0
  363. wx/demo/agw/bitmaps/open_folder.png +0 -0
  364. wx/demo/agw/bitmaps/paste.png +0 -0
  365. wx/demo/agw/bitmaps/pause.png +0 -0
  366. wx/demo/agw/bitmaps/pausedisabled.png +0 -0
  367. wx/demo/agw/bitmaps/play.png +0 -0
  368. wx/demo/agw/bitmaps/playdisabled.png +0 -0
  369. wx/demo/agw/bitmaps/plus1.ico +0 -0
  370. wx/demo/agw/bitmaps/plus2.ico +0 -0
  371. wx/demo/agw/bitmaps/plus3.ico +0 -0
  372. wx/demo/agw/bitmaps/plus4.ico +0 -0
  373. wx/demo/agw/bitmaps/plus5.ico +0 -0
  374. wx/demo/agw/bitmaps/record.png +0 -0
  375. wx/demo/agw/bitmaps/recorddisabled.png +0 -0
  376. wx/demo/agw/bitmaps/recording.gif +0 -0
  377. wx/demo/agw/bitmaps/rewind.png +0 -0
  378. wx/demo/agw/bitmaps/rewinddisabled.png +0 -0
  379. wx/demo/agw/bitmaps/round.png +0 -0
  380. wx/demo/agw/bitmaps/save.png +0 -0
  381. wx/demo/agw/bitmaps/separator.gif +0 -0
  382. wx/demo/agw/bitmaps/separatorflip.png +0 -0
  383. wx/demo/agw/bitmaps/smfuel.ico +0 -0
  384. wx/demo/agw/bitmaps/smpi.ico +0 -0
  385. wx/demo/agw/bitmaps/smtemp.ico +0 -0
  386. wx/demo/agw/bitmaps/stop.png +0 -0
  387. wx/demo/agw/bitmaps/stopdisabled.png +0 -0
  388. wx/demo/agw/bitmaps/sttbutton.png +0 -0
  389. wx/demo/agw/bitmaps/sttfont.png +0 -0
  390. wx/demo/agw/bitmaps/sttheader.png +0 -0
  391. wx/demo/agw/bitmaps/stthelp.png +0 -0
  392. wx/demo/agw/bitmaps/view1.png +0 -0
  393. wx/demo/agw/bitmaps/view2.png +0 -0
  394. wx/demo/agw/bitmaps/view_choose.png +0 -0
  395. wx/demo/agw/bitmaps/view_detailed.png +0 -0
  396. wx/demo/agw/bitmaps/view_icon.png +0 -0
  397. wx/demo/agw/bitmaps/view_multicolumn.png +0 -0
  398. wx/demo/agw/bitmaps/viewmag-16.png +0 -0
  399. wx/demo/agw/bitmaps/viewmag-m-16.png +0 -0
  400. wx/demo/agw/bitmaps/viewmag-p-16.png +0 -0
  401. wx/demo/agw/bitmaps/viewmagfit-16.png +0 -0
  402. wx/demo/agw/data/Example_1.xls +0 -0
  403. wx/demo/agw/images.py +6714 -0
  404. wx/demo/bitmaps/AG00028_.gif +0 -0
  405. wx/demo/bitmaps/AG00039_.gif +0 -0
  406. wx/demo/bitmaps/AG00178_.gif +0 -0
  407. wx/demo/bitmaps/AG00183_.gif +0 -0
  408. wx/demo/bitmaps/AG00185_.gif +0 -0
  409. wx/demo/bitmaps/BD13656_.gif +0 -0
  410. wx/demo/bitmaps/advancedsplash.png +0 -0
  411. wx/demo/bitmaps/aquabutton.png +0 -0
  412. wx/demo/bitmaps/aquachecked.ico +0 -0
  413. wx/demo/bitmaps/aquaflagged.ico +0 -0
  414. wx/demo/bitmaps/aquanotchecked.ico +0 -0
  415. wx/demo/bitmaps/aquanotflagged.ico +0 -0
  416. wx/demo/bitmaps/canada.gif +0 -0
  417. wx/demo/bitmaps/checked.ico +0 -0
  418. wx/demo/bitmaps/columns.png +0 -0
  419. wx/demo/bitmaps/contexthelp-16.png +0 -0
  420. wx/demo/bitmaps/contexthelp.png +0 -0
  421. wx/demo/bitmaps/copy.png +0 -0
  422. wx/demo/bitmaps/cropshot24x20.png +0 -0
  423. wx/demo/bitmaps/cut.png +0 -0
  424. wx/demo/bitmaps/editcopy.png +0 -0
  425. wx/demo/bitmaps/editcut.png +0 -0
  426. wx/demo/bitmaps/editpaste.png +0 -0
  427. wx/demo/bitmaps/exit-16.png +0 -0
  428. wx/demo/bitmaps/exit.ico +0 -0
  429. wx/demo/bitmaps/ffwd.png +0 -0
  430. wx/demo/bitmaps/ffwddisabled.png +0 -0
  431. wx/demo/bitmaps/field-16.png +0 -0
  432. wx/demo/bitmaps/filenew.png +0 -0
  433. wx/demo/bitmaps/fileopen.png +0 -0
  434. wx/demo/bitmaps/filesave.png +0 -0
  435. wx/demo/bitmaps/flagged.ico +0 -0
  436. wx/demo/bitmaps/folder_new.png +0 -0
  437. wx/demo/bitmaps/ghost.png +0 -0
  438. wx/demo/bitmaps/gradientbutton.png +0 -0
  439. wx/demo/bitmaps/help-16.png +0 -0
  440. wx/demo/bitmaps/help.ico +0 -0
  441. wx/demo/bitmaps/honeycomb300.png +0 -0
  442. wx/demo/bitmaps/image.bmp +0 -0
  443. wx/demo/bitmaps/image.gif +0 -0
  444. wx/demo/bitmaps/image.ico +0 -0
  445. wx/demo/bitmaps/image.jpg +0 -0
  446. wx/demo/bitmaps/image.png +0 -0
  447. wx/demo/bitmaps/image.tif +0 -0
  448. wx/demo/bitmaps/italy.gif +0 -0
  449. wx/demo/bitmaps/lbadd.png +0 -0
  450. wx/demo/bitmaps/lbcharge.png +0 -0
  451. wx/demo/bitmaps/lbdecrypted.png +0 -0
  452. wx/demo/bitmaps/lbnews.png +0 -0
  453. wx/demo/bitmaps/lbroll.png +0 -0
  454. wx/demo/bitmaps/minus1.ico +0 -0
  455. wx/demo/bitmaps/minus2.ico +0 -0
  456. wx/demo/bitmaps/minus3.ico +0 -0
  457. wx/demo/bitmaps/minus4.ico +0 -0
  458. wx/demo/bitmaps/minus5.ico +0 -0
  459. wx/demo/bitmaps/month-16.png +0 -0
  460. wx/demo/bitmaps/new_file.png +0 -0
  461. wx/demo/bitmaps/new_folder.png +0 -0
  462. wx/demo/bitmaps/notchecked.ico +0 -0
  463. wx/demo/bitmaps/notflagged.ico +0 -0
  464. wx/demo/bitmaps/ok-16.png +0 -0
  465. wx/demo/bitmaps/open_folder.png +0 -0
  466. wx/demo/bitmaps/paste.png +0 -0
  467. wx/demo/bitmaps/pause.png +0 -0
  468. wx/demo/bitmaps/pausedisabled.png +0 -0
  469. wx/demo/bitmaps/phoenix_title.png +0 -0
  470. wx/demo/bitmaps/phoenix_top.png +0 -0
  471. wx/demo/bitmaps/play.png +0 -0
  472. wx/demo/bitmaps/playdisabled.png +0 -0
  473. wx/demo/bitmaps/plus1.ico +0 -0
  474. wx/demo/bitmaps/plus2.ico +0 -0
  475. wx/demo/bitmaps/plus3.ico +0 -0
  476. wx/demo/bitmaps/plus4.ico +0 -0
  477. wx/demo/bitmaps/plus5.ico +0 -0
  478. wx/demo/bitmaps/record.png +0 -0
  479. wx/demo/bitmaps/recorddisabled.png +0 -0
  480. wx/demo/bitmaps/rewind.png +0 -0
  481. wx/demo/bitmaps/rewinddisabled.png +0 -0
  482. wx/demo/bitmaps/round.png +0 -0
  483. wx/demo/bitmaps/save.png +0 -0
  484. wx/demo/bitmaps/smfuel.ico +0 -0
  485. wx/demo/bitmaps/smpi.ico +0 -0
  486. wx/demo/bitmaps/smtemp.ico +0 -0
  487. wx/demo/bitmaps/snakey_render.png +0 -0
  488. wx/demo/bitmaps/splash.png +0 -0
  489. wx/demo/bitmaps/stop.png +0 -0
  490. wx/demo/bitmaps/stopdisabled.png +0 -0
  491. wx/demo/bitmaps/sttbutton.png +0 -0
  492. wx/demo/bitmaps/sttfont.png +0 -0
  493. wx/demo/bitmaps/sttheader.png +0 -0
  494. wx/demo/bitmaps/stthelp.png +0 -0
  495. wx/demo/bitmaps/toucan.png +0 -0
  496. wx/demo/bitmaps/view1.png +0 -0
  497. wx/demo/bitmaps/view2.png +0 -0
  498. wx/demo/bitmaps/view_choose.png +0 -0
  499. wx/demo/bitmaps/view_detailed.png +0 -0
  500. wx/demo/bitmaps/view_icon.png +0 -0
  501. wx/demo/bitmaps/view_multicolumn.png +0 -0
  502. wx/demo/bitmaps/viewmag-16.png +0 -0
  503. wx/demo/bitmaps/viewmag-m-16.png +0 -0
  504. wx/demo/bitmaps/viewmag-p-16.png +0 -0
  505. wx/demo/bitmaps/viewmagfit-16.png +0 -0
  506. wx/demo/bmp_source/001.png +0 -0
  507. wx/demo/bmp_source/002.png +0 -0
  508. wx/demo/bmp_source/003.png +0 -0
  509. wx/demo/bmp_source/004.png +0 -0
  510. wx/demo/bmp_source/005.png +0 -0
  511. wx/demo/bmp_source/006.png +0 -0
  512. wx/demo/bmp_source/007.png +0 -0
  513. wx/demo/bmp_source/008.png +0 -0
  514. wx/demo/bmp_source/009.png +0 -0
  515. wx/demo/bmp_source/010.png +0 -0
  516. wx/demo/bmp_source/011.png +0 -0
  517. wx/demo/bmp_source/012.png +0 -0
  518. wx/demo/bmp_source/013.png +0 -0
  519. wx/demo/bmp_source/014.png +0 -0
  520. wx/demo/bmp_source/015.png +0 -0
  521. wx/demo/bmp_source/016.png +0 -0
  522. wx/demo/bmp_source/017.png +0 -0
  523. wx/demo/bmp_source/018.png +0 -0
  524. wx/demo/bmp_source/019.png +0 -0
  525. wx/demo/bmp_source/020.png +0 -0
  526. wx/demo/bmp_source/021.png +0 -0
  527. wx/demo/bmp_source/022.png +0 -0
  528. wx/demo/bmp_source/023.png +0 -0
  529. wx/demo/bmp_source/024.png +0 -0
  530. wx/demo/bmp_source/025.png +0 -0
  531. wx/demo/bmp_source/026.png +0 -0
  532. wx/demo/bmp_source/027.png +0 -0
  533. wx/demo/bmp_source/028.png +0 -0
  534. wx/demo/bmp_source/029.png +0 -0
  535. wx/demo/bmp_source/030.png +0 -0
  536. wx/demo/bmp_source/DbDec.bmp +0 -0
  537. wx/demo/bmp_source/DbInc.bmp +0 -0
  538. wx/demo/bmp_source/Dec.bmp +0 -0
  539. wx/demo/bmp_source/FRM_0.png +0 -0
  540. wx/demo/bmp_source/FRM_1.png +0 -0
  541. wx/demo/bmp_source/FRM_2.png +0 -0
  542. wx/demo/bmp_source/FRM_3.png +0 -0
  543. wx/demo/bmp_source/FRM_4.png +0 -0
  544. wx/demo/bmp_source/FRM_5.png +0 -0
  545. wx/demo/bmp_source/FRM_6.png +0 -0
  546. wx/demo/bmp_source/FRM_7.png +0 -0
  547. wx/demo/bmp_source/FRM_8.png +0 -0
  548. wx/demo/bmp_source/GridBG.gif +0 -0
  549. wx/demo/bmp_source/Inc.bmp +0 -0
  550. wx/demo/bmp_source/LB01.png +0 -0
  551. wx/demo/bmp_source/LB02.png +0 -0
  552. wx/demo/bmp_source/LB03.png +0 -0
  553. wx/demo/bmp_source/LB04.png +0 -0
  554. wx/demo/bmp_source/LB05.png +0 -0
  555. wx/demo/bmp_source/LB06.png +0 -0
  556. wx/demo/bmp_source/LB07.png +0 -0
  557. wx/demo/bmp_source/LB08.png +0 -0
  558. wx/demo/bmp_source/LB09.png +0 -0
  559. wx/demo/bmp_source/LB10.png +0 -0
  560. wx/demo/bmp_source/LB11.png +0 -0
  561. wx/demo/bmp_source/LB12.png +0 -0
  562. wx/demo/bmp_source/Pt.bmp +0 -0
  563. wx/demo/bmp_source/Vippi.png +0 -0
  564. wx/demo/bmp_source/backgrnd.png +0 -0
  565. wx/demo/bmp_source/book.png +0 -0
  566. wx/demo/bmp_source/book_blue.png +0 -0
  567. wx/demo/bmp_source/book_green.png +0 -0
  568. wx/demo/bmp_source/book_red.png +0 -0
  569. wx/demo/bmp_source/bp_btn1.png +0 -0
  570. wx/demo/bmp_source/bp_btn2.png +0 -0
  571. wx/demo/bmp_source/bp_btn3.png +0 -0
  572. wx/demo/bmp_source/bp_btn4.png +0 -0
  573. wx/demo/bmp_source/bulb1.bmp +0 -0
  574. wx/demo/bmp_source/bulb2.bmp +0 -0
  575. wx/demo/bmp_source/carrot.png +0 -0
  576. wx/demo/bmp_source/clipboard.png +0 -0
  577. wx/demo/bmp_source/code.png +0 -0
  578. wx/demo/bmp_source/core.png +0 -0
  579. wx/demo/bmp_source/custom.png +0 -0
  580. wx/demo/bmp_source/customcontrol.png +0 -0
  581. wx/demo/bmp_source/deletedocs.png +0 -0
  582. wx/demo/bmp_source/deleteperspective.png +0 -0
  583. wx/demo/bmp_source/demo.png +0 -0
  584. wx/demo/bmp_source/dialog.png +0 -0
  585. wx/demo/bmp_source/exit.png +0 -0
  586. wx/demo/bmp_source/expansion.png +0 -0
  587. wx/demo/bmp_source/find.png +0 -0
  588. wx/demo/bmp_source/findnext.png +0 -0
  589. wx/demo/bmp_source/floatcanvas.png +0 -0
  590. wx/demo/bmp_source/frame.png +0 -0
  591. wx/demo/bmp_source/images.png +0 -0
  592. wx/demo/bmp_source/inspect.png +0 -0
  593. wx/demo/bmp_source/layout.png +0 -0
  594. wx/demo/bmp_source/logo.png +0 -0
  595. wx/demo/bmp_source/miscellaneous.png +0 -0
  596. wx/demo/bmp_source/modifiedexists.png +0 -0
  597. wx/demo/bmp_source/mondrian.ico +0 -0
  598. wx/demo/bmp_source/morecontrols.png +0 -0
  599. wx/demo/bmp_source/moredialog.png +0 -0
  600. wx/demo/bmp_source/noicon.png +0 -0
  601. wx/demo/bmp_source/overview.png +0 -0
  602. wx/demo/bmp_source/pencil.png +0 -0
  603. wx/demo/bmp_source/pointy.png +0 -0
  604. wx/demo/bmp_source/process.png +0 -0
  605. wx/demo/bmp_source/pyshell.png +0 -0
  606. wx/demo/bmp_source/recent.png +0 -0
  607. wx/demo/bmp_source/rest.png +0 -0
  608. wx/demo/bmp_source/robin.jpg +0 -0
  609. wx/demo/bmp_source/rt_alignleft.xpm +24 -0
  610. wx/demo/bmp_source/rt_alignright.xpm +24 -0
  611. wx/demo/bmp_source/rt_bold.xpm +24 -0
  612. wx/demo/bmp_source/rt_centre.xpm +24 -0
  613. wx/demo/bmp_source/rt_colour.xpm +59 -0
  614. wx/demo/bmp_source/rt_copy.xpm +44 -0
  615. wx/demo/bmp_source/rt_cut.xpm +46 -0
  616. wx/demo/bmp_source/rt_font.xpm +25 -0
  617. wx/demo/bmp_source/rt_idea.xpm +47 -0
  618. wx/demo/bmp_source/rt_indentless.xpm +25 -0
  619. wx/demo/bmp_source/rt_indentmore.xpm +25 -0
  620. wx/demo/bmp_source/rt_italic.xpm +25 -0
  621. wx/demo/bmp_source/rt_open.xpm +57 -0
  622. wx/demo/bmp_source/rt_paste.xpm +46 -0
  623. wx/demo/bmp_source/rt_redo.xpm +58 -0
  624. wx/demo/bmp_source/rt_sample.xpm +44 -0
  625. wx/demo/bmp_source/rt_save.xpm +42 -0
  626. wx/demo/bmp_source/rt_smiley.xpm +42 -0
  627. wx/demo/bmp_source/rt_underline.xpm +25 -0
  628. wx/demo/bmp_source/rt_undo.xpm +58 -0
  629. wx/demo/bmp_source/rt_zebra.xpm +409 -0
  630. wx/demo/bmp_source/saveperspective.png +0 -0
  631. wx/demo/bmp_source/sm_down.bmp +0 -0
  632. wx/demo/bmp_source/sm_up.bmp +0 -0
  633. wx/demo/bmp_source/smiles2.bmp +0 -0
  634. wx/demo/bmp_source/test2.bmp +0 -0
  635. wx/demo/bmp_source/testmask.bmp +0 -0
  636. wx/demo/bmp_source/teststar.png +0 -0
  637. wx/demo/bmp_source/thekid.png +0 -0
  638. wx/demo/bmp_source/tog1.bmp +0 -0
  639. wx/demo/bmp_source/tog2.bmp +0 -0
  640. wx/demo/bmp_source/wiztest1.bmp +0 -0
  641. wx/demo/bmp_source/wiztest2.bmp +0 -0
  642. wx/demo/bmp_source/wxpdemo.ico +0 -0
  643. wx/demo/cursors/paperairplane_arrow_blue.cur +0 -0
  644. wx/demo/cursors/paperairplane_arrow_blue_fadeout80.cur +0 -0
  645. wx/demo/cursors/paperairplane_arrow_colorshift.ani +0 -0
  646. wx/demo/cursors/paperairplane_arrow_dark.cur +0 -0
  647. wx/demo/cursors/paperairplane_arrow_grey.cur +0 -0
  648. wx/demo/cursors/paperairplane_arrow_red.cur +0 -0
  649. wx/demo/cursors/paperairplane_arrow_white.cur +0 -0
  650. wx/demo/cursors/paperairplane_arrow_white24.png +0 -0
  651. wx/demo/data/0-tiger.svg +725 -0
  652. wx/demo/data/Asteroid_blaster.swf +0 -0
  653. wx/demo/data/SIL_OPEN_FONT_LICENSE.txt +97 -0
  654. wx/demo/data/SourceCodePro-Regular.ttf +0 -0
  655. wx/demo/data/accessories-calculator.svg +636 -0
  656. wx/demo/data/accessories-text-editor.svg +554 -0
  657. wx/demo/data/anykey.wav +0 -0
  658. wx/demo/data/applications-internet.svg +623 -0
  659. wx/demo/data/desktop-accessibility.svg +245 -0
  660. wx/demo/data/desktop-keyboard-shortcuts.svg +839 -0
  661. wx/demo/data/desktop-locale.svg +878 -0
  662. wx/demo/data/desktop-remote-desktop.svg +1479 -0
  663. wx/demo/data/desktop-theme.svg +882 -0
  664. wx/demo/data/desktop-wallpaper.svg +747 -0
  665. wx/demo/data/echo.py +25 -0
  666. wx/demo/data/imagemap.htm +20 -0
  667. wx/demo/data/imagemap.png +0 -0
  668. wx/demo/data/internet-group-chat.svg +312 -0
  669. wx/demo/data/internet-mail.svg +440 -0
  670. wx/demo/data/locale/af/LC_MESSAGES/wxpydemo.mo +0 -0
  671. wx/demo/data/locale/de/LC_MESSAGES/wxpydemo.mo +0 -0
  672. wx/demo/data/locale/es/LC_MESSAGES/wxpydemo.mo +0 -0
  673. wx/demo/data/locale/fr/LC_MESSAGES/wxpydemo.mo +0 -0
  674. wx/demo/data/locale/it/LC_MESSAGES/wxpydemo.mo +0 -0
  675. wx/demo/data/locale-src/af.po +23 -0
  676. wx/demo/data/locale-src/de.po +23 -0
  677. wx/demo/data/locale-src/es.po +22 -0
  678. wx/demo/data/locale-src/fr.po +22 -0
  679. wx/demo/data/locale-src/install +15 -0
  680. wx/demo/data/locale-src/it.po +23 -0
  681. wx/demo/data/locale-src/wxpydemo.po +21 -0
  682. wx/demo/data/office-calendar.svg +316 -0
  683. wx/demo/data/pic.png +0 -0
  684. wx/demo/data/pic2.bmp +0 -0
  685. wx/demo/data/plan.wav +0 -0
  686. wx/demo/data/proclamation.txt +115 -0
  687. wx/demo/data/resource.wdr +0 -0
  688. wx/demo/data/resource_wdr.xrc +146 -0
  689. wx/demo/data/romedalen.png +0 -0
  690. wx/demo/data/stc.h.html +3544 -0
  691. wx/demo/data/system-session.svg +510 -0
  692. wx/demo/data/system-users.svg +539 -0
  693. wx/demo/data/tables.htm +116 -0
  694. wx/demo/data/test-gradient-pen.svg +14 -0
  695. wx/demo/data/test-opacity.svg +7 -0
  696. wx/demo/data/test.htm +253 -0
  697. wx/demo/data/testmovie.mpg +0 -0
  698. wx/demo/data/testtable.txt +38 -0
  699. wx/demo/data/tips.txt +73 -0
  700. wx/demo/data/utilities-system-monitor.svg +435 -0
  701. wx/demo/data/utilities-terminal.svg +500 -0
  702. wx/demo/data/widgetTest.htm +70 -0
  703. wx/demo/data/world.dat +24055 -0
  704. wx/demo/demo.py +4 -0
  705. wx/demo/demo.pyw +4 -0
  706. wx/demo/demodata.py +310 -0
  707. wx/demo/encode_bitmaps.py +181 -0
  708. wx/demo/images.py +6812 -0
  709. wx/demo/infoframe.py +149 -0
  710. wx/demo/run.py +171 -0
  711. wx/demo/snippets/__init__.py +13 -0
  712. wx/demo/snippets/arc.py +21 -0
  713. wx/demo/snippets/arc_negative.py +21 -0
  714. wx/demo/snippets/clip.py +13 -0
  715. wx/demo/snippets/clip_image.py +13 -0
  716. wx/demo/snippets/curve_rectangle.py +53 -0
  717. wx/demo/snippets/curve_to.py +17 -0
  718. wx/demo/snippets/dash.py +18 -0
  719. wx/demo/snippets/ellipse.py +33 -0
  720. wx/demo/snippets/fill_and_stroke.py +12 -0
  721. wx/demo/snippets/fill_and_stroke2.py +18 -0
  722. wx/demo/snippets/fill_style.py +31 -0
  723. wx/demo/snippets/glyph_path.py +21 -0
  724. wx/demo/snippets/gradient.py +16 -0
  725. wx/demo/snippets/gradient_mask.py +12 -0
  726. wx/demo/snippets/group.py +16 -0
  727. wx/demo/snippets/image.py +14 -0
  728. wx/demo/snippets/imagepattern.py +23 -0
  729. wx/demo/snippets/path.py +7 -0
  730. wx/demo/snippets/set_line_cap.py +19 -0
  731. wx/demo/snippets/set_line_join.py +21 -0
  732. wx/demo/snippets/show_glyphs.py +15 -0
  733. wx/demo/snippets/text.py +22 -0
  734. wx/demo/snippets/text_align_center.py +26 -0
  735. wx/demo/snippets/text_extents.py +27 -0
  736. wx/demo/template.py +36 -0
  737. wx/demo/throbImages.py +1277 -0
  738. wx/demo/version.py +3 -0
  739. wx/demo/widgetTest.py +72 -0
  740. wx/demo/wxpdemo.ico +0 -0
  741. wx/glcanvas.py +10 -0
  742. wx/glcanvas.pyi +458 -0
  743. wx/grid.py +229 -0
  744. wx/grid.pyi +4959 -0
  745. wx/html.py +35 -0
  746. wx/html.pyi +2965 -0
  747. wx/html2.py +40 -0
  748. wx/html2.pyi +772 -0
  749. wx/lib/CDate.py +202 -0
  750. wx/lib/ClickableHtmlWindow.py +57 -0
  751. wx/lib/__init__.py +0 -0
  752. wx/lib/activex.py +178 -0
  753. wx/lib/activexwrapper.py +153 -0
  754. wx/lib/agw/__init__.py +128 -0
  755. wx/lib/agw/advancedsplash.py +564 -0
  756. wx/lib/agw/aquabutton.py +1127 -0
  757. wx/lib/agw/artmanager.py +2110 -0
  758. wx/lib/agw/aui/__init__.py +295 -0
  759. wx/lib/agw/aui/aui_constants.py +2628 -0
  760. wx/lib/agw/aui/aui_switcherdialog.py +1227 -0
  761. wx/lib/agw/aui/aui_utilities.py +672 -0
  762. wx/lib/agw/aui/auibar.py +4031 -0
  763. wx/lib/agw/aui/auibook.py +6289 -0
  764. wx/lib/agw/aui/dockart.py +1198 -0
  765. wx/lib/agw/aui/framemanager.py +10409 -0
  766. wx/lib/agw/aui/tabart.py +2771 -0
  767. wx/lib/agw/aui/tabmdi.py +679 -0
  768. wx/lib/agw/balloontip.py +1158 -0
  769. wx/lib/agw/buttonpanel.py +2823 -0
  770. wx/lib/agw/cubecolourdialog.py +3529 -0
  771. wx/lib/agw/customtreectrl.py +8963 -0
  772. wx/lib/agw/data/ShortcutEditor_1.png +0 -0
  773. wx/lib/agw/data/ShortcutEditor_1_thumb.png +0 -0
  774. wx/lib/agw/data/ShortcutEditor_2.png +0 -0
  775. wx/lib/agw/data/ShortcutEditor_2_thumb.png +0 -0
  776. wx/lib/agw/data/ShortcutEditor_3.png +0 -0
  777. wx/lib/agw/data/ShortcutEditor_3_thumb.png +0 -0
  778. wx/lib/agw/data/ShortcutEditor_4.png +0 -0
  779. wx/lib/agw/data/ShortcutEditor_4_thumb.png +0 -0
  780. wx/lib/agw/data/default_help_text.html +105 -0
  781. wx/lib/agw/flatmenu.py +7333 -0
  782. wx/lib/agw/flatnotebook.py +6672 -0
  783. wx/lib/agw/floatspin.py +1823 -0
  784. wx/lib/agw/fmcustomizedlg.py +540 -0
  785. wx/lib/agw/fmresources.py +407 -0
  786. wx/lib/agw/foldpanelbar.py +2282 -0
  787. wx/lib/agw/fourwaysplitter.py +1130 -0
  788. wx/lib/agw/genericmessagedialog.py +1549 -0
  789. wx/lib/agw/gradientbutton.py +732 -0
  790. wx/lib/agw/hyperlink.py +664 -0
  791. wx/lib/agw/hypertreelist.py +5374 -0
  792. wx/lib/agw/infobar.py +885 -0
  793. wx/lib/agw/knobctrl.py +945 -0
  794. wx/lib/agw/labelbook.py +3029 -0
  795. wx/lib/agw/multidirdialog.py +615 -0
  796. wx/lib/agw/peakmeter.py +1029 -0
  797. wx/lib/agw/persist/__init__.py +188 -0
  798. wx/lib/agw/persist/persist_constants.py +284 -0
  799. wx/lib/agw/persist/persist_handlers.py +2614 -0
  800. wx/lib/agw/persist/persistencemanager.py +864 -0
  801. wx/lib/agw/piectrl.py +1082 -0
  802. wx/lib/agw/pybusyinfo.py +399 -0
  803. wx/lib/agw/pycollapsiblepane.py +940 -0
  804. wx/lib/agw/pygauge.py +570 -0
  805. wx/lib/agw/pyprogress.py +917 -0
  806. wx/lib/agw/ribbon/__init__.py +198 -0
  807. wx/lib/agw/ribbon/art.py +219 -0
  808. wx/lib/agw/ribbon/art_aui.py +1284 -0
  809. wx/lib/agw/ribbon/art_default.py +81 -0
  810. wx/lib/agw/ribbon/art_internal.py +244 -0
  811. wx/lib/agw/ribbon/art_msw.py +2736 -0
  812. wx/lib/agw/ribbon/art_osx.py +52 -0
  813. wx/lib/agw/ribbon/bar.py +1261 -0
  814. wx/lib/agw/ribbon/buttonbar.py +1320 -0
  815. wx/lib/agw/ribbon/control.py +205 -0
  816. wx/lib/agw/ribbon/gallery.py +974 -0
  817. wx/lib/agw/ribbon/page.py +946 -0
  818. wx/lib/agw/ribbon/panel.py +1170 -0
  819. wx/lib/agw/ribbon/toolbar.py +1442 -0
  820. wx/lib/agw/rulerctrl.py +1887 -0
  821. wx/lib/agw/scrolledthumbnail.py +2119 -0
  822. wx/lib/agw/shapedbutton.py +1809 -0
  823. wx/lib/agw/shortcuteditor.py +2634 -0
  824. wx/lib/agw/speedmeter.py +1801 -0
  825. wx/lib/agw/supertooltip.py +1444 -0
  826. wx/lib/agw/thumbnailctrl.py +529 -0
  827. wx/lib/agw/toasterbox.py +1327 -0
  828. wx/lib/agw/ultimatelistctrl.py +13666 -0
  829. wx/lib/agw/xlsgrid.py +2113 -0
  830. wx/lib/agw/zoombar.py +1339 -0
  831. wx/lib/analogclock/__init__.py +140 -0
  832. wx/lib/analogclock/analogclock.py +631 -0
  833. wx/lib/analogclock/helpers.py +991 -0
  834. wx/lib/analogclock/lib_setup/__init__.py +0 -0
  835. wx/lib/analogclock/lib_setup/buttontreectrlpanel.py +297 -0
  836. wx/lib/analogclock/lib_setup/fontselect.py +57 -0
  837. wx/lib/analogclock/setup.py +490 -0
  838. wx/lib/analogclock/styles.py +47 -0
  839. wx/lib/anchors.py +103 -0
  840. wx/lib/art/__init__.py +4 -0
  841. wx/lib/art/flagart.py +1583 -0
  842. wx/lib/art/img2pyartprov.py +56 -0
  843. wx/lib/busy.py +146 -0
  844. wx/lib/buttons.py +1141 -0
  845. wx/lib/calendar.py +1597 -0
  846. wx/lib/checkbox.py +837 -0
  847. wx/lib/colourchooser/__init__.py +38 -0
  848. wx/lib/colourchooser/canvas.py +145 -0
  849. wx/lib/colourchooser/intl.py +24 -0
  850. wx/lib/colourchooser/pycolourbox.py +89 -0
  851. wx/lib/colourchooser/pycolourchooser.py +629 -0
  852. wx/lib/colourchooser/pycolourslider.py +100 -0
  853. wx/lib/colourchooser/pypalette.py +211 -0
  854. wx/lib/colourdb.py +740 -0
  855. wx/lib/colourselect.py +385 -0
  856. wx/lib/colourutils.py +118 -0
  857. wx/lib/combotreebox.py +944 -0
  858. wx/lib/delayedresult.py +420 -0
  859. wx/lib/dialogs.py +510 -0
  860. wx/lib/docview.py +3210 -0
  861. wx/lib/dragscroller.py +79 -0
  862. wx/lib/editor/README.txt +77 -0
  863. wx/lib/editor/__init__.py +24 -0
  864. wx/lib/editor/editor.py +974 -0
  865. wx/lib/editor/images.py +15 -0
  866. wx/lib/editor/selection.py +44 -0
  867. wx/lib/embeddedimage.py +76 -0
  868. wx/lib/eventStack.py +136 -0
  869. wx/lib/eventwatcher.py +440 -0
  870. wx/lib/evtmgr.py +521 -0
  871. wx/lib/expando.py +393 -0
  872. wx/lib/fancytext.py +505 -0
  873. wx/lib/filebrowsebutton.py +459 -0
  874. wx/lib/flashwin.py +262 -0
  875. wx/lib/flashwin_old.py +651 -0
  876. wx/lib/floatcanvas/FCEvents.py +53 -0
  877. wx/lib/floatcanvas/FCObjects.py +2923 -0
  878. wx/lib/floatcanvas/FloatCanvas.py +1027 -0
  879. wx/lib/floatcanvas/GUIMode.py +396 -0
  880. wx/lib/floatcanvas/NavCanvas.py +161 -0
  881. wx/lib/floatcanvas/Resources.py +319 -0
  882. wx/lib/floatcanvas/ScreenShot.py +1788 -0
  883. wx/lib/floatcanvas/Utilities/BBox.py +314 -0
  884. wx/lib/floatcanvas/Utilities/Colors.py +137 -0
  885. wx/lib/floatcanvas/Utilities/GUI.py +91 -0
  886. wx/lib/floatcanvas/Utilities/__init__.py +7 -0
  887. wx/lib/floatcanvas/__init__.py +124 -0
  888. wx/lib/foldmenu.py +89 -0
  889. wx/lib/gestures.py +310 -0
  890. wx/lib/gizmos/__init__.py +18 -0
  891. wx/lib/gizmos/dynamicsash.py +1202 -0
  892. wx/lib/gizmos/ledctrl.py +300 -0
  893. wx/lib/gizmos/treelistctrl.py +87 -0
  894. wx/lib/graphics.py +1939 -0
  895. wx/lib/gridmovers.py +511 -0
  896. wx/lib/iewin.py +249 -0
  897. wx/lib/iewin_old.py +894 -0
  898. wx/lib/imagebrowser.py +856 -0
  899. wx/lib/imageutils.py +163 -0
  900. wx/lib/infoframe.py +490 -0
  901. wx/lib/inspection.py +1255 -0
  902. wx/lib/intctrl.py +1001 -0
  903. wx/lib/itemspicker.py +256 -0
  904. wx/lib/langlistctrl.py +480 -0
  905. wx/lib/layoutf.py +271 -0
  906. wx/lib/masked/__init__.py +27 -0
  907. wx/lib/masked/combobox.py +839 -0
  908. wx/lib/masked/ctrl.py +108 -0
  909. wx/lib/masked/ipaddrctrl.py +242 -0
  910. wx/lib/masked/maskededit.py +7279 -0
  911. wx/lib/masked/numctrl.py +2001 -0
  912. wx/lib/masked/textctrl.py +465 -0
  913. wx/lib/masked/timectrl.py +1466 -0
  914. wx/lib/mixins/__init__.py +17 -0
  915. wx/lib/mixins/grid.py +47 -0
  916. wx/lib/mixins/gridlabelrenderer.py +251 -0
  917. wx/lib/mixins/imagelist.py +77 -0
  918. wx/lib/mixins/inspection.py +184 -0
  919. wx/lib/mixins/listctrl.py +894 -0
  920. wx/lib/mixins/rubberband.py +404 -0
  921. wx/lib/mixins/treemixin.py +678 -0
  922. wx/lib/msgpanel.py +95 -0
  923. wx/lib/multisash.py +747 -0
  924. wx/lib/myole4ax.idl +178 -0
  925. wx/lib/myole4ax.tlb +0 -0
  926. wx/lib/newevent.py +229 -0
  927. wx/lib/nvdlg.py +156 -0
  928. wx/lib/ogl/__init__.py +13 -0
  929. wx/lib/ogl/basic.py +3991 -0
  930. wx/lib/ogl/bmpshape.py +87 -0
  931. wx/lib/ogl/canvas.py +467 -0
  932. wx/lib/ogl/composit.py +1577 -0
  933. wx/lib/ogl/diagram.py +230 -0
  934. wx/lib/ogl/divided.py +483 -0
  935. wx/lib/ogl/drawn.py +900 -0
  936. wx/lib/ogl/lines.py +1811 -0
  937. wx/lib/ogl/oglmisc.py +608 -0
  938. wx/lib/pdfviewer/__init__.py +113 -0
  939. wx/lib/pdfviewer/bitmaps/ArrowLeft.png +0 -0
  940. wx/lib/pdfviewer/bitmaps/ArrowRight.png +0 -0
  941. wx/lib/pdfviewer/bitmaps/DirectionH.png +0 -0
  942. wx/lib/pdfviewer/bitmaps/DirectionV.png +0 -0
  943. wx/lib/pdfviewer/bitmaps/PlayerFirst.png +0 -0
  944. wx/lib/pdfviewer/bitmaps/PlayerLast.png +0 -0
  945. wx/lib/pdfviewer/bitmaps/PlayerNext.png +0 -0
  946. wx/lib/pdfviewer/bitmaps/PlayerPrev.png +0 -0
  947. wx/lib/pdfviewer/bitmaps/Printer.png +0 -0
  948. wx/lib/pdfviewer/bitmaps/ReadMe.txt +28 -0
  949. wx/lib/pdfviewer/bitmaps/Save.png +0 -0
  950. wx/lib/pdfviewer/bitmaps/ZoomIn.png +0 -0
  951. wx/lib/pdfviewer/bitmaps/ZoomOut.png +0 -0
  952. wx/lib/pdfviewer/bitmaps/encode_bitmaps.py +37 -0
  953. wx/lib/pdfviewer/buttonpanel.py +279 -0
  954. wx/lib/pdfviewer/images.py +240 -0
  955. wx/lib/pdfviewer/viewer.py +1077 -0
  956. wx/lib/pdfwin.py +295 -0
  957. wx/lib/pdfwin_old.py +789 -0
  958. wx/lib/platebtn.py +789 -0
  959. wx/lib/plot/CHANGELOG.md +150 -0
  960. wx/lib/plot/README.md +16 -0
  961. wx/lib/plot/__init__.py +46 -0
  962. wx/lib/plot/__main__.py +5 -0
  963. wx/lib/plot/examples/__init__.py +0 -0
  964. wx/lib/plot/examples/demo.py +1009 -0
  965. wx/lib/plot/examples/simple_example.py +54 -0
  966. wx/lib/plot/plotcanvas.py +2981 -0
  967. wx/lib/plot/polyobjects.py +1525 -0
  968. wx/lib/plot/utils.py +327 -0
  969. wx/lib/popupctl.py +250 -0
  970. wx/lib/printout.py +1157 -0
  971. wx/lib/progressindicator.py +151 -0
  972. wx/lib/pubsub/LICENSE_BSD_Simple.txt +23 -0
  973. wx/lib/pubsub/README_WxPython.txt +22 -0
  974. wx/lib/pubsub/RELEASE_NOTES.txt +71 -0
  975. wx/lib/pubsub/__init__.py +25 -0
  976. wx/lib/pubsub/core/__init__.py +92 -0
  977. wx/lib/pubsub/core/arg1/__init__.py +16 -0
  978. wx/lib/pubsub/core/arg1/listenerimpl.py +97 -0
  979. wx/lib/pubsub/core/arg1/publisher.py +40 -0
  980. wx/lib/pubsub/core/arg1/publishermixin.py +34 -0
  981. wx/lib/pubsub/core/arg1/topicargspecimpl.py +66 -0
  982. wx/lib/pubsub/core/arg1/topicmgrimpl.py +19 -0
  983. wx/lib/pubsub/core/callables.py +191 -0
  984. wx/lib/pubsub/core/imp2.py +63 -0
  985. wx/lib/pubsub/core/itopicdefnprovider.py +0 -0
  986. wx/lib/pubsub/core/kwargs/__init__.py +16 -0
  987. wx/lib/pubsub/core/kwargs/datamsg.py +27 -0
  988. wx/lib/pubsub/core/kwargs/listenerimpl.py +93 -0
  989. wx/lib/pubsub/core/kwargs/publisher.py +77 -0
  990. wx/lib/pubsub/core/kwargs/publishermixin.py +65 -0
  991. wx/lib/pubsub/core/kwargs/topicargspecimpl.py +217 -0
  992. wx/lib/pubsub/core/kwargs/topicmgrimpl.py +13 -0
  993. wx/lib/pubsub/core/listener.py +40 -0
  994. wx/lib/pubsub/core/listenerbase.py +185 -0
  995. wx/lib/pubsub/core/notificationmgr.py +185 -0
  996. wx/lib/pubsub/core/publisherbase.py +191 -0
  997. wx/lib/pubsub/core/topicargspec.py +77 -0
  998. wx/lib/pubsub/core/topicdefnprovider.py +632 -0
  999. wx/lib/pubsub/core/topicexc.py +72 -0
  1000. wx/lib/pubsub/core/topicmgr.py +456 -0
  1001. wx/lib/pubsub/core/topicobj.py +472 -0
  1002. wx/lib/pubsub/core/topictreetraverser.py +143 -0
  1003. wx/lib/pubsub/core/topicutils.py +118 -0
  1004. wx/lib/pubsub/core/treeconfig.py +21 -0
  1005. wx/lib/pubsub/core/validatedefnargs.py +29 -0
  1006. wx/lib/pubsub/core/weakmethod.py +102 -0
  1007. wx/lib/pubsub/policies.py +24 -0
  1008. wx/lib/pubsub/pub.py +199 -0
  1009. wx/lib/pubsub/py2and3.py +608 -0
  1010. wx/lib/pubsub/setuparg1.py +47 -0
  1011. wx/lib/pubsub/setupkwargs.py +29 -0
  1012. wx/lib/pubsub/utils/__init__.py +27 -0
  1013. wx/lib/pubsub/utils/exchandling.py +100 -0
  1014. wx/lib/pubsub/utils/misc.py +100 -0
  1015. wx/lib/pubsub/utils/notification.py +331 -0
  1016. wx/lib/pubsub/utils/topictreeprinter.py +195 -0
  1017. wx/lib/pubsub/utils/xmltopicdefnprovider.py +287 -0
  1018. wx/lib/pydocview.py +3300 -0
  1019. wx/lib/rcsizer.py +229 -0
  1020. wx/lib/resizewidget.py +357 -0
  1021. wx/lib/scrolledpanel.py +225 -0
  1022. wx/lib/sheet.py +350 -0
  1023. wx/lib/sized_controls.py +691 -0
  1024. wx/lib/softwareupdate.py +361 -0
  1025. wx/lib/splitter.py +925 -0
  1026. wx/lib/statbmp.py +199 -0
  1027. wx/lib/stattext.py +322 -0
  1028. wx/lib/throbber.py +425 -0
  1029. wx/lib/ticker.py +295 -0
  1030. wx/lib/ticker_xrc.py +48 -0
  1031. wx/lib/utils.py +89 -0
  1032. wx/lib/wordwrap.py +97 -0
  1033. wx/lib/wxcairo/__init__.py +124 -0
  1034. wx/lib/wxcairo/wx_cairocffi.py +200 -0
  1035. wx/lib/wxcairo/wx_pycairo.py +463 -0
  1036. wx/lib/wxpTag.py +274 -0
  1037. wx/locale/af/LC_MESSAGES/wxstd.mo +0 -0
  1038. wx/locale/an/LC_MESSAGES/wxstd.mo +0 -0
  1039. wx/locale/ar/LC_MESSAGES/wxstd.mo +0 -0
  1040. wx/locale/ca/LC_MESSAGES/wxstd.mo +0 -0
  1041. wx/locale/ca@valencia/LC_MESSAGES/wxstd.mo +0 -0
  1042. wx/locale/cs/LC_MESSAGES/wxstd.mo +0 -0
  1043. wx/locale/da/LC_MESSAGES/wxstd.mo +0 -0
  1044. wx/locale/de/LC_MESSAGES/wxstd.mo +0 -0
  1045. wx/locale/el/LC_MESSAGES/wxstd.mo +0 -0
  1046. wx/locale/es/LC_MESSAGES/wxstd.mo +0 -0
  1047. wx/locale/eu/LC_MESSAGES/wxstd.mo +0 -0
  1048. wx/locale/fa_IR/LC_MESSAGES/wxstd.mo +0 -0
  1049. wx/locale/fi/LC_MESSAGES/wxstd.mo +0 -0
  1050. wx/locale/fr/LC_MESSAGES/wxstd.mo +0 -0
  1051. wx/locale/gl_ES/LC_MESSAGES/wxstd.mo +0 -0
  1052. wx/locale/hi/LC_MESSAGES/wxstd.mo +0 -0
  1053. wx/locale/hr/LC_MESSAGES/wxstd.mo +0 -0
  1054. wx/locale/hu/LC_MESSAGES/wxstd.mo +0 -0
  1055. wx/locale/id/LC_MESSAGES/wxstd.mo +0 -0
  1056. wx/locale/it/LC_MESSAGES/wxstd.mo +0 -0
  1057. wx/locale/ja/LC_MESSAGES/wxstd.mo +0 -0
  1058. wx/locale/ka/LC_MESSAGES/wxstd.mo +0 -0
  1059. wx/locale/ko_KR/LC_MESSAGES/wxstd.mo +0 -0
  1060. wx/locale/lt/LC_MESSAGES/wxstd.mo +0 -0
  1061. wx/locale/lv/LC_MESSAGES/wxstd.mo +0 -0
  1062. wx/locale/ms/LC_MESSAGES/wxstd.mo +0 -0
  1063. wx/locale/nb/LC_MESSAGES/wxstd.mo +0 -0
  1064. wx/locale/ne/LC_MESSAGES/wxstd.mo +0 -0
  1065. wx/locale/nl/LC_MESSAGES/wxstd.mo +0 -0
  1066. wx/locale/pl/LC_MESSAGES/wxstd.mo +0 -0
  1067. wx/locale/pt/LC_MESSAGES/wxstd.mo +0 -0
  1068. wx/locale/pt_BR/LC_MESSAGES/wxstd.mo +0 -0
  1069. wx/locale/ro/LC_MESSAGES/wxstd.mo +0 -0
  1070. wx/locale/ru/LC_MESSAGES/wxstd.mo +0 -0
  1071. wx/locale/sk/LC_MESSAGES/wxstd.mo +0 -0
  1072. wx/locale/sl/LC_MESSAGES/wxstd.mo +0 -0
  1073. wx/locale/sq/LC_MESSAGES/wxstd.mo +0 -0
  1074. wx/locale/sv/LC_MESSAGES/wxstd.mo +0 -0
  1075. wx/locale/ta/LC_MESSAGES/wxstd.mo +0 -0
  1076. wx/locale/tr/LC_MESSAGES/wxstd.mo +0 -0
  1077. wx/locale/uk/LC_MESSAGES/wxstd.mo +0 -0
  1078. wx/locale/vi/LC_MESSAGES/wxstd.mo +0 -0
  1079. wx/locale/zh_CN/LC_MESSAGES/wxstd.mo +0 -0
  1080. wx/locale/zh_TW/LC_MESSAGES/wxstd.mo +0 -0
  1081. wx/media.py +27 -0
  1082. wx/media.pyi +223 -0
  1083. wx/msw.py +13 -0
  1084. wx/msw.pyi +65 -0
  1085. wx/propgrid.py +1451 -0
  1086. wx/propgrid.pyi +7914 -0
  1087. wx/py/CHANGES.txt +796 -0
  1088. wx/py/Py.ico +0 -0
  1089. wx/py/PyAlaCarte.py +34 -0
  1090. wx/py/PyAlaMode.py +34 -0
  1091. wx/py/PyAlaModeTest.py +33 -0
  1092. wx/py/PyCrust.ico +0 -0
  1093. wx/py/PyCrust.py +78 -0
  1094. wx/py/PyCrust_16.png +0 -0
  1095. wx/py/PyCrust_32.png +0 -0
  1096. wx/py/PyFilling.py +35 -0
  1097. wx/py/PyShell.py +78 -0
  1098. wx/py/PySlices.ico +0 -0
  1099. wx/py/PySlices.py +98 -0
  1100. wx/py/PySlicesShell.py +94 -0
  1101. wx/py/PySlices_16.png +0 -0
  1102. wx/py/PySlices_32.png +0 -0
  1103. wx/py/PyWrap.py +52 -0
  1104. wx/py/README.txt +77 -0
  1105. wx/py/__init__.py +20 -0
  1106. wx/py/buffer.py +136 -0
  1107. wx/py/crust.py +403 -0
  1108. wx/py/crustslices.py +403 -0
  1109. wx/py/dispatcher.py +259 -0
  1110. wx/py/document.py +37 -0
  1111. wx/py/editor.py +844 -0
  1112. wx/py/editwindow.py +299 -0
  1113. wx/py/filling.py +357 -0
  1114. wx/py/frame.py +978 -0
  1115. wx/py/images.py +212 -0
  1116. wx/py/interpreter.py +170 -0
  1117. wx/py/introspect.py +393 -0
  1118. wx/py/magic.py +98 -0
  1119. wx/py/parse.py +134 -0
  1120. wx/py/path.py +36 -0
  1121. wx/py/pseudo.py +99 -0
  1122. wx/py/shell.py +1588 -0
  1123. wx/py/sliceshell.py +3814 -0
  1124. wx/py/tests/test_interpreter.py +71 -0
  1125. wx/py/tests/test_introspect.py +862 -0
  1126. wx/py/tests/test_pseudo.py +70 -0
  1127. wx/py/tests/test_version.py +36 -0
  1128. wx/py/tests/testall.py +22 -0
  1129. wx/py/version.py +7 -0
  1130. wx/ribbon.py +45 -0
  1131. wx/ribbon.pyi +2494 -0
  1132. wx/richtext.py +142 -0
  1133. wx/richtext.pyi +12113 -0
  1134. wx/siplib.cp313-win_amd64.pyd +0 -0
  1135. wx/stc.py +58 -0
  1136. wx/stc.pyi +8463 -0
  1137. wx/svg/__init__.py +364 -0
  1138. wx/svg/_nanosvg.cp313-win_amd64.pyd +0 -0
  1139. wx/tools/__init__.py +18 -0
  1140. wx/tools/dbg.py +268 -0
  1141. wx/tools/genaxmodule.py +50 -0
  1142. wx/tools/helpviewer.py +92 -0
  1143. wx/tools/img2img.py +85 -0
  1144. wx/tools/img2png.py +54 -0
  1145. wx/tools/img2py.py +309 -0
  1146. wx/tools/img2xpm.py +54 -0
  1147. wx/tools/pywxrc.py +949 -0
  1148. wx/tools/wxget.py +254 -0
  1149. wx/tools/wxget_docs_demo.py +186 -0
  1150. wx/wxbase315u_net_vc140_x64.dll +0 -0
  1151. wx/wxbase315u_vc140_x64.dll +0 -0
  1152. wx/wxbase315u_xml_vc140_x64.dll +0 -0
  1153. wx/wxmsw315u_adv_vc140_x64.dll +0 -0
  1154. wx/wxmsw315u_aui_vc140_x64.dll +0 -0
  1155. wx/wxmsw315u_core_vc140_x64.dll +0 -0
  1156. wx/wxmsw315u_gl_vc140_x64.dll +0 -0
  1157. wx/wxmsw315u_html_vc140_x64.dll +0 -0
  1158. wx/wxmsw315u_media_vc140_x64.dll +0 -0
  1159. wx/wxmsw315u_propgrid_vc140_x64.dll +0 -0
  1160. wx/wxmsw315u_qa_vc140_x64.dll +0 -0
  1161. wx/wxmsw315u_ribbon_vc140_x64.dll +0 -0
  1162. wx/wxmsw315u_richtext_vc140_x64.dll +0 -0
  1163. wx/wxmsw315u_stc_vc140_x64.dll +0 -0
  1164. wx/wxmsw315u_webview_vc140_x64.dll +0 -0
  1165. wx/wxmsw315u_xrc_vc140_x64.dll +0 -0
  1166. wx/xml.py +15 -0
  1167. wx/xml.pyi +575 -0
  1168. wx/xrc.py +65 -0
  1169. wx/xrc.pyi +742 -0
  1170. wxPython_zombie-3.1.5.8.dist-info/LICENSE.txt +950 -0
  1171. wxPython_zombie-3.1.5.8.dist-info/METADATA +107 -0
  1172. wxPython_zombie-3.1.5.8.dist-info/RECORD +1175 -0
  1173. wxPython_zombie-3.1.5.8.dist-info/WHEEL +5 -0
  1174. wxPython_zombie-3.1.5.8.dist-info/entry_points.txt +2 -0
  1175. wxPython_zombie-3.1.5.8.dist-info/top_level.txt +1 -0
wx/py/sliceshell.py ADDED
@@ -0,0 +1,3814 @@
1
+ #----------------------------------------------------------------------
2
+ # Name: sliceshell.py
3
+ # Author: David N. Mashburn, Patrick K. O'Brien
4
+ # Tags: phoenix-port
5
+ #----------------------------------------------------------------------
6
+ """Slices is an interactive text control in which a user types in
7
+ commands to be sent to the interpreter. This particular shell is
8
+ based on wxPython's wxStyledTextCtrl.
9
+
10
+ Sponsored by Orbtech - Your source for Python programming expertise.
11
+ Slices is a version of shell modified by David Mashburn."""
12
+
13
+ __author__ = "David N. Mashburn <david.n.mashburn@gmail.com> / "
14
+ __author__ += "Patrick K. O'Brien <pobrien@orbtech.com>"
15
+
16
+ import wx
17
+ from wx import stc
18
+ from six import PY3
19
+
20
+ import keyword
21
+ import os
22
+ import sys
23
+ import time
24
+ from functools import cmp_to_key
25
+
26
+ from .buffer import Buffer
27
+ from . import dispatcher
28
+ from . import editor
29
+ from . import editwindow
30
+ from . import document
31
+ from . import frame
32
+ from .pseudo import PseudoFileIn
33
+ from .pseudo import PseudoFileOut
34
+ from .pseudo import PseudoFileErr
35
+ from .version import VERSION
36
+ from .magic import magic
37
+ from .parse import testForContinuations
38
+ from .path import ls,cd,pwd,sx
39
+
40
+
41
+ sys.ps3 = '<-- ' # Input prompt.
42
+ USE_MAGIC=True
43
+ # Force updates from long-running commands after this many seconds
44
+ PRINT_UPDATE_MAX_TIME=2
45
+
46
+ NAVKEYS = (wx.WXK_HOME, wx.WXK_END, wx.WXK_LEFT, wx.WXK_RIGHT,
47
+ wx.WXK_UP, wx.WXK_DOWN, wx.WXK_PAGEUP, wx.WXK_PAGEDOWN)
48
+
49
+ GROUPING_SELECTING=0
50
+ IO_SELECTING = 1
51
+
52
+ GROUPING_START = 2
53
+ GROUPING_START_FOLDED = 3
54
+ GROUPING_MIDDLE = 4
55
+ GROUPING_END = 5
56
+ INPUT_START = 6
57
+ INPUT_START_FOLDED = 7
58
+ INPUT_MIDDLE = 8
59
+ INPUT_END = 9
60
+ OUTPUT_START = 10
61
+ OUTPUT_START_FOLDED = 11
62
+ OUTPUT_MIDDLE = 12
63
+ OUTPUT_END = 13
64
+
65
+ OUTPUT_BG = 14
66
+ READLINE_BG = 15
67
+ INPUT_READLINE = 16
68
+
69
+ # Could add C integration right into the markers...
70
+ # Non-editable file marker for auto-loaded files...
71
+ # Weave VariableInput = 15
72
+ # Weave C code = 16
73
+ # C code = 17 (only for use with Pyrex)
74
+ # Pyrex / Cython code = 18
75
+
76
+ GROUPING_MASK = ( 1<<GROUPING_START | 1<<GROUPING_START_FOLDED |
77
+ 1<<GROUPING_MIDDLE | 1<<GROUPING_END )
78
+
79
+ INPUT_MASK = ( 1<<INPUT_START | 1<<INPUT_START_FOLDED |
80
+ 1<<INPUT_MIDDLE | 1<<INPUT_END )
81
+ OUTPUT_MASK = ( 1<<OUTPUT_START | 1<<OUTPUT_START_FOLDED |
82
+ 1<<OUTPUT_MIDDLE | 1<<OUTPUT_END )
83
+ IO_MASK = ( INPUT_MASK | OUTPUT_MASK )
84
+
85
+ IO_START_MASK = ( 1<<INPUT_START | 1<<OUTPUT_START )
86
+ IO_START_FOLDED_MASK = ( 1<<INPUT_START_FOLDED | 1<<OUTPUT_START_FOLDED )
87
+ IO_ANY_START_MASK = ( 1<<INPUT_START | 1<<OUTPUT_START |
88
+ 1<<INPUT_START_FOLDED | 1<<OUTPUT_START_FOLDED )
89
+ IO_MIDDLE_MASK = ( 1<<INPUT_MIDDLE | 1<<OUTPUT_MIDDLE )
90
+ IO_END_MASK = ( 1<<INPUT_END | 1<<OUTPUT_END )
91
+
92
+ usrBinEnvPythonText = '#!/usr/bin/env python\n'
93
+ pyslicesFormatHeaderText = ['#PySlices Save Format Version 1.1 (PySlices v0.9.7.8 and later)\n',
94
+ '#PySlices Save Format Version 1.2 (PySlices v0.9.8 and later)\n']
95
+ groupingStartText = '#PySlices Marker Information -- Begin Grouping Slice\n'
96
+ inputStartText = '#PySlices Marker Information -- Begin Input Slice\n'
97
+ outputStartText = '#PySlices Marker Information -- Begin Output Slice\n'
98
+
99
+ tutorialText = """
100
+
101
+ Tutorial!!!
102
+ ------------------------------------------------------------------------
103
+ PySlices is the newest member of the Py suite!
104
+ It is a modified version of PyCrust that supports multi-line commands.
105
+
106
+ Input and output are contained in "Slices" shown as markers in the left margin.
107
+ Input Slices have RED margins (active, editable).
108
+ Output Slices have BLUE margins (frozen, not editable).
109
+
110
+ Commands in slices can be on more than one line, as with Sage or Mathematica.
111
+ For example, the command:
112
+ a=1
113
+ b=2
114
+ print(a+b)
115
+ will all run in sequence, much like a script.
116
+ Try running the above Input Slice by clicking somewhere in its text and
117
+ using Ctrl-Return, Shift-Return, or Numpad Enter to execute.
118
+ Previous commands (Old Slices) can be re-edited and run again in place.
119
+
120
+ Slices can also be:
121
+ * selceted (click on the margin, Shift-click for multiple selection)
122
+ * folded (click the margin twice)
123
+ * selected and deleted (hit delete while selected)
124
+ * divided (Ctrl-D)
125
+ * merged (Ctrl-M while selecting adjacent, like-colored slices)
126
+
127
+ Try deleting the slice above this one by clicking on the red margin.
128
+
129
+ If you want a more traditional shell feel, try enabling "Shell Mode" in
130
+ "Options->Settings->Shell Mode" (or try PyCrust).
131
+ In Shell Mode, two returns in a row executes the command, and
132
+ Ctrl-Return and Shift-Return always print newlines.
133
+
134
+ Saving and opening "sessions" is now supported! This is a little
135
+ different to other shells where the history is saved. With PySlices,
136
+ the whole document is saved in a simple text format!
137
+
138
+ To disable this Tutorial on startup, uncheck it in the menu at:
139
+ "Options->Startup->Show PySlices tutorial"
140
+
141
+ PySlices may not be the best thing since sliced bread, but
142
+ I hope it makes using Python a little bit sweeter!
143
+ """
144
+
145
+ class SlicesShellFrame(frame.Frame, frame.ShellFrameMixin):
146
+ """Frame containing the sliceshell component."""
147
+
148
+ name = 'SlicesShell Frame'
149
+
150
+ def __init__(self, parent=None, id=-1, title='PySlicesShell',
151
+ pos=wx.DefaultPosition, size=wx.DefaultSize,
152
+ style=wx.DEFAULT_FRAME_STYLE, locals=None,
153
+ InterpClass=None,
154
+ config=None, dataDir=None, filename=None,
155
+ *args, **kwds):
156
+ """Create SlicesShellFrame instance."""
157
+ frame.Frame.__init__(self, parent, id, title, pos, size, style,shellName='PySlices')
158
+ frame.ShellFrameMixin.__init__(self, config, dataDir)
159
+
160
+ if size == wx.DefaultSize:
161
+ self.SetSize((750, 525))
162
+
163
+ intro = 'PySlices %s - The Flakiest Python Shell... Cut Up!' % VERSION
164
+ self.SetStatusText(intro.replace('\n', ', '))
165
+ self.sliceshell = SlicesShell(parent=self, id=-1, introText=intro,
166
+ locals=locals, InterpClass=InterpClass,
167
+ startupScript=self.startupScript,
168
+ execStartupScript=self.execStartupScript,
169
+ showPySlicesTutorial=self.showPySlicesTutorial,
170
+ enableShellMode=self.enableShellMode,
171
+ hideFoldingMargin=self.hideFoldingMargin,
172
+ *args, **kwds)
173
+ self.shell = self.sliceshell
174
+ self.buffer = self.sliceshell.buffer
175
+
176
+ # Override the shell so that status messages go to the status bar.
177
+ self.sliceshell.setStatusText = self.SetStatusText
178
+
179
+ self.sliceshell.SetFocus()
180
+ self.LoadSettings()
181
+
182
+ self.currentDirectory = os.path.expanduser('~')
183
+
184
+ if filename!=None:
185
+ self.bufferOpen(filename)
186
+
187
+ self.Bind(wx.EVT_IDLE, self.OnIdle)
188
+
189
+
190
+ def OnClose(self, event):
191
+ """Event handler for closing."""
192
+ self.bufferClose()
193
+ # This isn't working the way I want, but I'll leave it for now.
194
+ #if self.sliceshell.waiting:
195
+ # if event.CanVeto():
196
+ # event.Veto(True)
197
+ #else:
198
+ # # TODO: Add check for saving
199
+ # self.SaveSettings()
200
+ # self.sliceshell.destroy()
201
+ # self.Destroy()
202
+
203
+ def OnAbout(self, event):
204
+ """Display an About window."""
205
+ title = 'About PySliceShell'
206
+ text = 'PySliceShell %s\n\n' % VERSION + \
207
+ 'Yet another Python shell, only flakier.\n\n' + \
208
+ 'Half-baked by Patrick K. O\'Brien,\n' + \
209
+ 'the other half is still in the oven.\n\n' + \
210
+ 'Platform: %s\n' % sys.platform + \
211
+ 'Python Version: %s\n' % sys.version.split()[0] + \
212
+ 'wxPython Version: %s\n' % wx.VERSION_STRING + \
213
+ ('\t(%s)\n' % ", ".join(wx.PlatformInfo[1:]))
214
+ dialog = wx.MessageDialog(self, text, title,
215
+ wx.OK | wx.ICON_INFORMATION)
216
+ dialog.ShowModal()
217
+ dialog.Destroy()
218
+
219
+
220
+ def OnHelp(self, event):
221
+ """Show a help dialog."""
222
+ frame.ShellFrameMixin.OnHelp(self, event)
223
+
224
+
225
+ def LoadSettings(self):
226
+ if self.config is not None:
227
+ frame.ShellFrameMixin.LoadSettings(self)
228
+ frame.Frame.LoadSettings(self, self.config)
229
+ self.sliceshell.LoadSettings(self.config)
230
+
231
+ def SaveSettings(self, force=False):
232
+ if self.config is not None:
233
+ frame.ShellFrameMixin.SaveSettings(self,force)
234
+ if self.autoSaveSettings or force:
235
+ frame.Frame.SaveSettings(self, self.config)
236
+ self.sliceshell.SaveSettings(self.config)
237
+
238
+ def DoSaveSettings(self):
239
+ if self.config is not None:
240
+ self.SaveSettings(force=True)
241
+ self.config.Flush()
242
+
243
+ def OnEnableShellMode(self,event):
244
+ """Change between Slices Mode and Shell Mode"""
245
+ frame.Frame.OnEnableShellMode(self,event)
246
+ self.sliceshell.ToggleShellMode(self.enableShellMode)
247
+
248
+ def OnHideFoldingMargin(self,event):
249
+ """Change between Slices Mode and Shell Mode"""
250
+ frame.Frame.OnHideFoldingMargin(self,event)
251
+ self.sliceshell.ToggleFoldingMargin(self.hideFoldingMargin)
252
+ # Copied Straight from crustslices.py (update both with any changes...)
253
+ # Stolen Straight from editor.EditorFrame
254
+ # Modified a little... :)
255
+ # ||
256
+ # \/
257
+ def OnIdle(self, event):
258
+ """Event handler for idle time."""
259
+ self._updateTitle()
260
+ event.Skip()
261
+
262
+ def _updateTitle(self):
263
+ """Show current title information."""
264
+ title = self.GetTitle()
265
+ if self.bufferHasChanged():
266
+ if title.startswith('* '):
267
+ pass
268
+ else:
269
+ self.SetTitle('* ' + title)
270
+ else:
271
+ if title.startswith('* '):
272
+ self.SetTitle(title[2:])
273
+
274
+ def hasBuffer(self):
275
+ """Return True if there is a current buffer."""
276
+ if self.buffer:
277
+ return True
278
+ else:
279
+ return False
280
+
281
+ def bufferClose(self):
282
+ """Close buffer."""
283
+ if self.buffer.hasChanged():
284
+ cancel = self.bufferSuggestSave()
285
+ if cancel:
286
+ #event.Veto()
287
+ return cancel
288
+ self.SaveSettings()
289
+ self.sliceshell.destroy()
290
+ self.bufferDestroy()
291
+ self.Destroy()
292
+
293
+ return False
294
+
295
+ def bufferCreate(self, filename=None):
296
+ """Create new buffer."""
297
+ self.bufferDestroy()
298
+ buffer = Buffer()
299
+ self.panel = panel = wx.Panel(parent=self, id=-1)
300
+ panel.Bind (wx.EVT_ERASE_BACKGROUND, lambda x: x)
301
+ editor = Editor(parent=panel)
302
+ panel.editor = editor
303
+ sizer = wx.BoxSizer(wx.VERTICAL)
304
+ sizer.Add(editor.window, 1, wx.EXPAND)
305
+ panel.SetSizer(sizer)
306
+ panel.SetAutoLayout(True)
307
+ sizer.Layout()
308
+ buffer.addEditor(editor)
309
+ buffer.open(filename)
310
+ self.setEditor(editor)
311
+ self.editor.setFocus()
312
+ self.SendSizeEvent()
313
+
314
+
315
+ def bufferDestroy(self):
316
+ """Destroy the current buffer."""
317
+ if self.buffer:
318
+ self.editor = None
319
+ self.buffer = None
320
+
321
+
322
+ def bufferHasChanged(self):
323
+ """Return True if buffer has changed since last save."""
324
+ if self.buffer:
325
+ return self.buffer.hasChanged()
326
+ else:
327
+ return False
328
+
329
+ def bufferNew(self):
330
+ """Create new buffer."""
331
+ cancel = self.bufferSuggestSave()
332
+ if cancel:
333
+ return cancel
334
+ #self.bufferCreate()
335
+ self.clear()
336
+ self.SetTitle( 'PySlices')
337
+ self.sliceshell.NeedsCheckForSave=False
338
+ self.sliceshell.SetSavePoint()
339
+ self.buffer.doc = document.Document()
340
+ self.buffer.name = 'This shell'
341
+ self.buffer.modulename = self.buffer.doc.filebase
342
+ cancel = False
343
+ return cancel
344
+
345
+ def bufferOpen(self,file=None):
346
+ """Open file in buffer."""
347
+ if self.bufferHasChanged():
348
+ cancel = self.bufferSuggestSave()
349
+ if cancel:
350
+ return cancel
351
+
352
+ if file==None:
353
+ file=wx.FileSelector('Open a PySlices File',
354
+ wildcard='*.pyslices',
355
+ default_path=self.currentDirectory)
356
+ if file!=None and file!=u'':
357
+ with open(file,'r') as fid:
358
+ self.sliceshell.LoadPySlicesFile(fid)
359
+
360
+ self.currentDirectory = os.path.split(file)[0]
361
+ self.SetTitle( os.path.split(file)[1] + ' - PySlices')
362
+ self.sliceshell.NeedsCheckForSave=False
363
+ self.sliceshell.SetSavePoint()
364
+ self.buffer.doc = document.Document(file)
365
+ self.buffer.name = self.buffer.doc.filename
366
+ self.buffer.modulename = self.buffer.doc.filebase
367
+ self.sliceshell.ScrollToLine(0)
368
+ return
369
+
370
+ ## def bufferPrint(self):
371
+ ## """Print buffer."""
372
+ ## pass
373
+
374
+ ## def bufferRevert(self):
375
+ ## """Revert buffer to version of file on disk."""
376
+ ## pass
377
+
378
+ # was self.buffer.save(self): # """Save buffer."""
379
+ def simpleSave(self,confirmed=False):
380
+ filepath = self.buffer.doc.filepath
381
+ self.buffer.confirmed = confirmed
382
+ if not filepath:
383
+ return # XXX Get filename
384
+ if not os.path.exists(filepath):
385
+ self.buffer.confirmed = True
386
+ if not self.buffer.confirmed:
387
+ self.buffer.confirmed = self.buffer.overwriteConfirm(filepath)
388
+ if self.buffer.confirmed:
389
+ with open(filepath, 'wb') as fid:
390
+ self.sliceshell.SavePySlicesFile(fid)
391
+
392
+ self.sliceshell.SetSavePoint()
393
+ self.SetTitle( os.path.split(filepath)[1] + ' - PySlices')
394
+ self.sliceshell.NeedsCheckForSave=False
395
+
396
+ def bufferSave(self):
397
+ """Save buffer to its file."""
398
+ if self.buffer.doc.filepath:
399
+ # self.buffer.save()
400
+ self.simpleSave(confirmed=True)
401
+ cancel = False
402
+ else:
403
+ cancel = self.bufferSaveAs()
404
+ return cancel
405
+
406
+ def bufferSaveAs(self):
407
+ """Save buffer to a new filename."""
408
+ if self.bufferHasChanged() and self.buffer.doc.filepath:
409
+ cancel = self.bufferSuggestSave()
410
+ if cancel:
411
+ return cancel
412
+ filedir = ''
413
+ if self.buffer and self.buffer.doc.filedir:
414
+ filedir = self.buffer.doc.filedir
415
+ result = editor.saveSingle(title='Save PySlices File',directory=filedir,
416
+ wildcard='PySlices Files (*.pyslices)|*.pyslices')
417
+ if result.path not in ['',None]:
418
+ if result.path[-9:]!=".pyslices":
419
+ result.path+=".pyslices"
420
+
421
+ self.buffer.doc = document.Document(result.path)
422
+ self.buffer.name = self.buffer.doc.filename
423
+ self.buffer.modulename = self.buffer.doc.filebase
424
+ self.simpleSave(confirmed=True) # allow overwrite
425
+ cancel = False
426
+ else:
427
+ cancel = True
428
+ return cancel
429
+
430
+ def bufferSaveACopy(self):
431
+ """Save buffer to a new filename."""
432
+ filedir = ''
433
+ if self.buffer and self.buffer.doc.filedir:
434
+ filedir = self.buffer.doc.filedir
435
+ result = editor.saveSingle(title='Save a Copy of PySlices File',directory=filedir,
436
+ wildcard='PySlices Files (*.pyslices)|*.pyslices')
437
+
438
+ if result.path not in ['',None]:
439
+ if result.path[-9:]!=".pyslices":
440
+ result.path+=".pyslices"
441
+
442
+ # if not os.path.exists(result.path):
443
+ # Allow overwrite...
444
+ with open(result.path, 'wb') as fid:
445
+ self.sliceshell.SavePySlicesFile(fid)
446
+
447
+ cancel = False
448
+ else:
449
+ cancel = True
450
+ return cancel
451
+
452
+ def bufferSuggestSave(self):
453
+ """Suggest saving changes. Return True if user selected Cancel."""
454
+ result = editor.messageDialog(parent=None,
455
+ message='%s has changed.\n'
456
+ 'Would you like to save it first'
457
+ '?' % self.buffer.name,
458
+ title='Save current file?',
459
+ style=wx.YES_NO | wx.CANCEL | wx.NO_DEFAULT |
460
+ wx.CENTRE | wx.ICON_QUESTION )
461
+ if result.positive:
462
+ cancel = self.bufferSave()
463
+ else:
464
+ cancel = result.text == 'Cancel'
465
+ return cancel
466
+
467
+ def updateNamespace(self):
468
+ """Update the buffer namespace for autocompletion and calltips."""
469
+ if self.buffer.updateNamespace():
470
+ self.SetStatusText('Namespace updated')
471
+ else:
472
+ self.SetStatusText('Error executing, unable to update namespace')
473
+
474
+
475
+
476
+ # TODO : Update the help text
477
+ HELP_TEXT = """\
478
+ * Key bindings:
479
+ Home Go to the beginning of the line.
480
+ End Go to the end of the line.
481
+ Shift+Home Select to the beginning of the line.
482
+ Shift+End Select to the end of the line.
483
+ Ctrl-Home Jump to the beginning of the slice;
484
+ If already there, jump to beginning of previous slice
485
+ Ctrl-End Jump to the end of the slice;
486
+ If already there, jump to end of next slice
487
+ Ctrl-PageUp Jump to the beginning of the shell
488
+ Ctrl-PageDown Jump to the end of the shell
489
+ Ctrl+C Copy selected text, removing prompts.
490
+ Ctrl+Shift+C Copy selected text, retaining prompts.
491
+ Alt+C Copy to the clipboard, including prefixed prompts.
492
+ Ctrl+X Cut selected text.
493
+ Ctrl+V Paste from clipboard.
494
+ Ctrl+Shift+V Paste and run multiple commands from clipboard.
495
+ Ctrl+Up Arrow Retrieve Previous History item.
496
+ Alt+P Retrieve Previous History item.
497
+ Ctrl+Down Arrow Retrieve Next History item.
498
+ Alt+N Retrieve Next History item.
499
+ Shift+Up Arrow Insert Previous History item.
500
+ Shift+Down Arrow Insert Next History item.
501
+ F8 Command-completion of History item.
502
+ (Type a few characters of a previous command and press F8.)
503
+ Ctrl+] Increase font size.
504
+ Ctrl+[ Decrease font size.
505
+ Ctrl+= Default font size.
506
+
507
+ Ctrl-Space Show Auto Completion.
508
+ Ctrl-Shift-Space Show Call Tip.
509
+ Ctrl-Shift-H Complete Text from History.
510
+
511
+ Ctrl+F Search
512
+ Ctrl+G Search next
513
+ F12 on/off "free-edit" mode
514
+ For testing only -- This does not preserve markers!
515
+
516
+ In "Slices Mode":
517
+ Return Insert new line
518
+ Enter (Numpad) Run command in slice
519
+ Ctrl+Return ""
520
+ Shift+Return ""
521
+
522
+ In "Shell Mode":
523
+ Return or Enter Insert a new line
524
+ Ctrl+Return ""
525
+ Shift+Return ""
526
+ 2 Returns in a row Run command in slice
527
+ """
528
+
529
+ class SlicesShellFacade:
530
+ """Simplified interface to all shell-related functionality.
531
+
532
+ This is a semi-transparent facade, in that all attributes of other
533
+ are accessible, even though only some are visible to the user."""
534
+
535
+ name = 'SlicesShell Interface'
536
+
537
+ def __init__(self, other):
538
+ """Create a SlicesShellFacade instance."""
539
+ d = self.__dict__
540
+ d['other'] = other
541
+ d['helpText'] = HELP_TEXT
542
+
543
+ def help(self):
544
+ """Display some useful information about how to use the slices shell."""
545
+ self.write(self.helpText,type='Output')
546
+
547
+ def __getattr__(self, name):
548
+ if hasattr(self.other, name):
549
+ return getattr(self.other, name)
550
+ else:
551
+ raise AttributeError(name)
552
+
553
+ def __setattr__(self, name, value):
554
+ if name in self.__dict__:
555
+ self.__dict__[name] = value
556
+ elif hasattr(self.other, name):
557
+ setattr(self.other, name, value)
558
+ else:
559
+ raise AttributeError(name)
560
+
561
+ def _getAttributeNames(self):
562
+ """Return list of magic attributes to extend introspection."""
563
+ list = [
564
+ 'about',
565
+ 'ask',
566
+ 'autoCallTip',
567
+ 'autoComplete',
568
+ 'autoCompleteAutoHide',
569
+ 'autoCompleteCaseInsensitive',
570
+ 'autoCompleteIncludeDouble',
571
+ 'autoCompleteIncludeMagic',
572
+ 'autoCompleteIncludeSingle',
573
+ 'callTipInsert',
574
+ 'clear',
575
+ 'pause',
576
+ 'prompt',
577
+ 'quit',
578
+ 'redirectStderr',
579
+ 'redirectStdin',
580
+ 'redirectStdout',
581
+ 'run',
582
+ 'runfile',
583
+ 'wrap',
584
+ 'zoom',
585
+ ]
586
+ list.sort()
587
+ return list
588
+
589
+ DISPLAY_TEXT="""
590
+ Author: %r
591
+ Py Version: %s
592
+ Python Version: %s
593
+ wxPython Version: %s
594
+ wxPython PlatformInfo: %s
595
+ Platform: %s"""
596
+
597
+ class SlicesShell(editwindow.EditWindow):
598
+ """Notebook Shell based on StyledTextCtrl."""
599
+
600
+ name = 'SlicesShell'
601
+
602
+ def __init__(self, parent, id=-1, pos=wx.DefaultPosition,
603
+ size=wx.DefaultSize, style=wx.CLIP_CHILDREN,
604
+ introText='', locals=None, InterpClass=None,
605
+ startupScript=None, execStartupScript=True,
606
+ showPySlicesTutorial=True,enableShellMode=False,
607
+ useStockId=True,
608
+ hideFoldingMargin=False, *args, **kwds):
609
+ """Create Shell instance."""
610
+ editwindow.EditWindow.__init__(self, parent, id, pos, size, style)
611
+ self.wrap()
612
+ if locals is None:
613
+ import __main__
614
+ locals = __main__.__dict__
615
+
616
+ # Grab these so they can be restored by self.redirect* methods.
617
+ self.stdin = sys.stdin
618
+ self.stdout = sys.stdout
619
+ self.stderr = sys.stderr
620
+
621
+ # Import a default interpreter class if one isn't provided.
622
+ if InterpClass is None:
623
+ from .interpreter import Interpreter
624
+ else:
625
+ Interpreter = InterpClass
626
+
627
+ # Create a replacement for stdin.
628
+ self.reader = PseudoFileIn(self.readline, self.readlines)
629
+ self.reader.input = ''
630
+ self.reader.isreading = False
631
+
632
+ # Set up the interpreter.
633
+ self.interp = Interpreter(locals=locals,
634
+ rawin=self.raw_input,
635
+ stdin=self.reader,
636
+ stdout=PseudoFileOut(self.writeOut),
637
+ stderr=PseudoFileErr(self.writeErr),
638
+ *args, **kwds)
639
+
640
+ # Set up the buffer.
641
+ self.buffer = Buffer()
642
+ self.id = self.GetId()
643
+ self.buffer.addEditor(self)
644
+ self.buffer.name='This shell'
645
+ self.NeedsCheckForSave=False
646
+
647
+ # Find out for which keycodes the interpreter will autocomplete.
648
+ self.autoCompleteKeys = self.interp.getAutoCompleteKeys()
649
+
650
+ # Keep track of the last non-continuation prompt positions.
651
+ # Removed all references to these... solved a lot of odd bugs...
652
+ # self.promptPosStart = 0
653
+ # self.promptPosEnd = 0
654
+
655
+ # Keep track of multi-line commands.
656
+ self.more = False
657
+
658
+ # Use Margins to track input / output / slice number
659
+ self.margins = True
660
+
661
+ # For use with forced updates during long-running scripts
662
+ self.lastUpdate=None
663
+
664
+ if self.margins:
665
+ # margin 1 is already defined for the line numbers
666
+ # may eventually change it back to 0 like it ought to be...
667
+ self.SetMarginType(2, stc.STC_MARGIN_SYMBOL)
668
+ self.SetMarginType(3, stc.STC_MARGIN_SYMBOL)
669
+ self.SetMarginType(4, stc.STC_MARGIN_SYMBOL)
670
+ self.SetMarginWidth(2, 22)
671
+ self.SetMarginWidth(3, 22)
672
+ self.SetMarginWidth(4, 12)
673
+ self.SetMarginSensitive(2,True)
674
+ self.SetMarginSensitive(3,True)
675
+ self.SetMarginSensitive(4,True)
676
+ self.SetProperty("fold", "1")
677
+ # tabs are bad, use spaces
678
+ self.SetProperty("tab.timmy.whinge.level", "4")
679
+ self.SetMargins(0,0)
680
+
681
+
682
+ self.SetMarginMask(2, GROUPING_MASK | 1<<GROUPING_SELECTING )
683
+ # Display Markers -24...
684
+ self.SetMarginMask(3, IO_MASK | 1<<IO_SELECTING | 1<<READLINE_BG | 1<<INPUT_READLINE )
685
+ self.SetMarginMask(4, stc.STC_MASK_FOLDERS)
686
+ # Set the mask for the line markers, too...
687
+ self.SetMarginMask(1, 0)
688
+
689
+ if hideFoldingMargin:
690
+ self.SetMarginWidth(4, 0)
691
+ self.hideFoldingMargin=hideFoldingMargin
692
+
693
+ sel_color="#E0E0E0"
694
+ grouping_color="black"
695
+ input_color="red"
696
+ output_color="blue"
697
+
698
+ self.MarkerDefine(GROUPING_SELECTING, stc.STC_MARK_FULLRECT,
699
+ sel_color, sel_color)
700
+ self.MarkerDefine(IO_SELECTING, stc.STC_MARK_FULLRECT,
701
+ sel_color, sel_color)
702
+
703
+ self.MarkerDefine(GROUPING_START, stc.STC_MARK_BOXMINUS,
704
+ "white", grouping_color)
705
+ self.MarkerDefine(GROUPING_START_FOLDED, stc.STC_MARK_BOXPLUS,
706
+ "white", grouping_color)
707
+ self.MarkerDefine(GROUPING_MIDDLE, stc.STC_MARK_VLINE,
708
+ "white", grouping_color)
709
+ self.MarkerDefine(GROUPING_END, stc.STC_MARK_LCORNER,
710
+ "white", grouping_color)
711
+
712
+ self.MarkerDefine(READLINE_BG, stc.STC_MARK_FULLRECT,
713
+ wx.Colour(191,191,191), wx.Colour(191,191,191))
714
+ self.MarkerDefine(INPUT_READLINE, stc.STC_MARK_CHARACTER+ord('<'),
715
+ input_color, wx.Colour(191,191,191))
716
+
717
+ if enableShellMode:
718
+ self.mode='ShellMode'
719
+ else:
720
+ self.mode='SlicesMode'
721
+
722
+ self.execOnNextReturn=False
723
+ if self.mode=='SlicesMode':
724
+ self.MarkerDefine(INPUT_START, stc.STC_MARK_BOXMINUS,
725
+ "white", input_color)
726
+ self.MarkerDefine(INPUT_START_FOLDED, stc.STC_MARK_BOXPLUS,
727
+ "white", input_color)
728
+ self.MarkerDefine(INPUT_MIDDLE, stc.STC_MARK_VLINE,
729
+ "white", input_color)
730
+ self.MarkerDefine(INPUT_END, stc.STC_MARK_LCORNER,
731
+ "white", input_color)
732
+ elif self.mode=='ShellMode':
733
+ self.MarkerDefine(INPUT_START, stc.STC_MARK_ARROWS,
734
+ input_color, "white")
735
+ self.MarkerDefine(INPUT_START_FOLDED, stc.STC_MARK_BOXPLUS,
736
+ "white", input_color)
737
+ self.MarkerDefine(INPUT_MIDDLE, stc.STC_MARK_DOTDOTDOT,
738
+ input_color, "white")
739
+ self.MarkerDefine(INPUT_END, stc.STC_MARK_DOTDOTDOT,
740
+ input_color, "white")
741
+
742
+ self.MarkerDefine(OUTPUT_START, stc.STC_MARK_BOXMINUS,
743
+ "white", output_color)
744
+ self.MarkerDefine(OUTPUT_START_FOLDED, stc.STC_MARK_BOXPLUS,
745
+ "white", output_color)
746
+ self.MarkerDefine(OUTPUT_MIDDLE, stc.STC_MARK_VLINE,
747
+ "white", output_color)
748
+ self.MarkerDefine(OUTPUT_END, stc.STC_MARK_LCORNER,
749
+ "white", output_color)
750
+
751
+ self.MarkerDefine(OUTPUT_BG, stc.STC_MARK_BACKGROUND,
752
+ "white", wx.Colour(242,242,255))
753
+
754
+ # Markers for folding margin...
755
+ self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN, stc.STC_MARK_BOXMINUS,
756
+ "white", "#808080")
757
+ self.MarkerDefine(stc.STC_MARKNUM_FOLDER, stc.STC_MARK_BOXPLUS,
758
+ "white", "#808080")
759
+ self.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB, stc.STC_MARK_VLINE,
760
+ "white", "#808080")
761
+ self.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL, stc.STC_MARK_LCORNER,
762
+ "white", "#808080")
763
+ self.MarkerDefine(stc.STC_MARKNUM_FOLDEREND, stc.STC_MARK_BOXPLUSCONNECTED,
764
+ "white", "#808080")
765
+ self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, stc.STC_MARK_BOXMINUSCONNECTED,
766
+ "white", "#808080")
767
+ self.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, stc.STC_MARK_TCORNER,
768
+ "white", "#808080")
769
+
770
+ # Create the command history. Commands are added into the
771
+ # front of the list (ie. at index 0) as they are entered.
772
+ # self.historyIndex is the current position in the history; it
773
+ # gets incremented as you retrieve the previous command,
774
+ # decremented as you retrieve the next, and reset when you hit
775
+ # Enter. self.historyIndex == -1 means you're on the current
776
+ # command, not in the history.
777
+ self.history = []
778
+ self.historyIndex = -1
779
+
780
+ #DNM -- disable these markers...
781
+ #seb add mode for "free edit"
782
+ self.noteMode = 0
783
+ #self.MarkerDefine(0,stc.STC_MARK_ROUNDRECT) # marker for hidden
784
+ self.searchTxt = ""
785
+
786
+ # Assign handlers for keyboard events.
787
+ self.Bind(wx.EVT_CHAR, self.OnChar)
788
+ self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
789
+
790
+ self.Bind(wx.stc.EVT_STC_MARGINCLICK, self.OnMarginClick)
791
+ # TODO : Add a general functions to handle mouse clicks in the
792
+ # TODO: STC window whose sole purpose is to make it so
793
+ # TODO: that margin selection becomes unselected...
794
+
795
+ # Assign handler for the context menu
796
+ self.Bind(wx.EVT_CONTEXT_MENU, self.OnContextMenu)
797
+ self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateUI)
798
+
799
+ # add the option to not use the stock IDs; otherwise the context menu
800
+ # may not work on Mac without adding the proper IDs to the menu bar
801
+ if useStockId:
802
+ self.ID_CUT = wx.ID_CUT
803
+ self.ID_COPY = wx.ID_COPY
804
+ self.ID_PASTE = wx.ID_PASTE
805
+ self.ID_SELECTALL = wx.ID_SELECTALL
806
+ self.ID_CLEAR = wx.ID_CLEAR
807
+ self.ID_UNDO = wx.ID_UNDO
808
+ self.ID_REDO = wx.ID_REDO
809
+ else:
810
+ self.ID_CUT = wx.NewIdRef()
811
+ self.ID_COPY = wx.NewIdRef()
812
+ self.ID_PASTE = wx.NewIdRef()
813
+ self.ID_SELECTALL = wx.NewIdRef()
814
+ self.ID_CLEAR = wx.NewIdRef()
815
+ self.ID_UNDO = wx.NewIdRef()
816
+ self.ID_REDO = wx.NewIdRef()
817
+
818
+ # Assign handlers for edit events
819
+ self.Bind(wx.EVT_MENU, lambda evt: self.Cut(), id=self.ID_CUT)
820
+ self.Bind(wx.EVT_MENU, lambda evt: self.Copy(), id=self.ID_COPY)
821
+ self.Bind(wx.EVT_MENU, lambda evt: self.CopyWithPrompts(), id=frame.ID_COPY_PLUS)
822
+ self.Bind(wx.EVT_MENU, lambda evt: self.Paste(), id=self.ID_PASTE)
823
+ self.Bind(wx.EVT_MENU, lambda evt: self.PasteAndRun(), id=frame.ID_PASTE_PLUS)
824
+ self.Bind(wx.EVT_MENU, lambda evt: self.SelectAll(), id=self.ID_SELECTALL)
825
+ self.Bind(wx.EVT_MENU, lambda evt: self.Clear(), id=self.ID_CLEAR)
826
+ self.Bind(wx.EVT_MENU, lambda evt: self.Undo(), id=self.ID_UNDO)
827
+ self.Bind(wx.EVT_MENU, lambda evt: self.Redo(), id=self.ID_REDO)
828
+
829
+ # Assign handler for idle time.
830
+ self.waiting = False
831
+ self.Bind(wx.EVT_IDLE, self.OnIdle)
832
+
833
+ # Display the introductory banner information.
834
+ self.showIntro(introText)
835
+
836
+ outStart,outEnd,inStart,inMiddle,inEnd = [[],[],[],[],[]]
837
+
838
+ # Make "executed startup script move to the top..."
839
+ if showPySlicesTutorial:
840
+ self.write(tutorialText,'Output')
841
+ tutStart=5
842
+ testStart=16
843
+ outStart=[tutStart,testStart+3]
844
+ outEnd=[tutStart-1,testStart-1]
845
+ inStart=[testStart]
846
+ inMiddle=[testStart+1]
847
+ inEnd=[testStart+2]
848
+
849
+ # Assign some pseudo keywords to the interpreter's namespace.
850
+ self.setBuiltinKeywords()
851
+
852
+ # Add 'shell' to the interpreter's local namespace.
853
+ self.setLocalShell()
854
+
855
+ # Do this last so the user has complete control over their
856
+ # environment. They can override anything they want.
857
+ if execStartupScript:
858
+ if startupScript is None:
859
+ startupScript = os.environ.get('PYTHONSTARTUP')
860
+ self.execStartupScript(startupScript)
861
+ else:
862
+ self.prompt()
863
+
864
+ outStart+=[0]
865
+ outEnd+=[self.GetLineCount()-2]
866
+ inStart+=[self.GetLineCount()-1]
867
+ # Set all the line markers to the proper initial states...
868
+ for i in range(self.GetLineCount()):
869
+ self.clearGroupingMarkers(i)
870
+ self.clearIOMarkers(i)
871
+ if i in outStart:
872
+ self.MarkerAdd(i,GROUPING_START)
873
+ self.MarkerAdd(i,OUTPUT_START)
874
+ # Background color is confusing for tutorial... skip it!
875
+ #self.MarkerAdd(i,OUTPUT_BG)
876
+ elif i in outEnd:
877
+ self.MarkerAdd(i,GROUPING_END)
878
+ self.MarkerAdd(i,OUTPUT_END)
879
+ #self.MarkerAdd(i,OUTPUT_BG)
880
+ elif i in inStart:
881
+ self.MarkerAdd(i,GROUPING_START)
882
+ self.MarkerAdd(i,INPUT_START)
883
+ elif i in inMiddle:
884
+ self.MarkerAdd(i,GROUPING_MIDDLE)
885
+ self.MarkerAdd(i,INPUT_MIDDLE)
886
+ elif i in inEnd:
887
+ self.MarkerAdd(i,GROUPING_END)
888
+ self.MarkerAdd(i,INPUT_END)
889
+ else:
890
+ self.MarkerAdd(i,GROUPING_MIDDLE)
891
+ self.MarkerAdd(i,OUTPUT_MIDDLE)
892
+ #self.MarkerAdd(i,OUTPUT_BG)
893
+
894
+ self.SliceSelection=False
895
+ self.runningSlice=None
896
+
897
+ ## NOTE: See note at bottom of this file...
898
+ ## #seb: File drag and drop
899
+ ## self.SetDropTarget( FileDropTarget(self) )
900
+
901
+ #ADD UNDO
902
+ # Everywhere "ADD UNDO" appears, there is new code to handle markers
903
+ self.EmptyUndoBuffer()
904
+
905
+ wx.CallAfter(self.ScrollToLine, 0)
906
+
907
+ def ToggleShellMode(self,enableShellMode=None):
908
+ if enableShellMode==None:
909
+ if self.mode=='ShellMode': self.mode='SlicesMode'
910
+ elif self.mode=='SlicesMode': self.mode='ShellMode'
911
+ elif enableShellMode:
912
+ self.mode='ShellMode'
913
+ else:
914
+ self.mode='SlicesMode'
915
+
916
+ input_color="red"
917
+ if self.mode=='SlicesMode':
918
+ self.MarkerDefine(INPUT_START, stc.STC_MARK_BOXMINUS,
919
+ "white", input_color)
920
+ self.MarkerDefine(INPUT_START_FOLDED, stc.STC_MARK_BOXPLUS,
921
+ "white", input_color)
922
+ self.MarkerDefine(INPUT_MIDDLE, stc.STC_MARK_VLINE,
923
+ "white", input_color)
924
+ self.MarkerDefine(INPUT_END, stc.STC_MARK_LCORNER,
925
+ "white", input_color)
926
+ elif self.mode=='ShellMode':
927
+ self.MarkerDefine(INPUT_START, stc.STC_MARK_ARROWS,
928
+ input_color, "white")
929
+ self.MarkerDefine(INPUT_START_FOLDED, stc.STC_MARK_BOXPLUS,
930
+ "white", input_color)
931
+ self.MarkerDefine(INPUT_MIDDLE, stc.STC_MARK_DOTDOTDOT,
932
+ input_color, "white")
933
+ self.MarkerDefine(INPUT_END, stc.STC_MARK_DOTDOTDOT,
934
+ input_color, "white")
935
+
936
+ def ToggleFoldingMargin(self,hideFoldingMargin=None):
937
+ if hideFoldingMargin==None:
938
+ self.hideFoldingMargin = not self.hideFoldingMargin
939
+ else:
940
+ self.hideFoldingMargin = hideFoldingMargin
941
+
942
+ if self.hideFoldingMargin:
943
+ self.SetMarginWidth(4, 0)
944
+ else:
945
+ self.SetMarginWidth(4, 12)
946
+
947
+ def clearHistory(self):
948
+ self.history = []
949
+ self.historyIndex = -1
950
+ dispatcher.send(signal="SlicesShell.clearHistory")
951
+
952
+
953
+ def destroy(self):
954
+ del self.interp
955
+
956
+ def setFocus(self):
957
+ """Set focus to the slices shell."""
958
+ self.SetFocus()
959
+
960
+ def OnIdle(self, event):
961
+ """Free the CPU to do other things."""
962
+ if self.waiting:
963
+ time.sleep(0.05)
964
+ event.Skip()
965
+
966
+ def showIntro(self, text=''):
967
+ """Display introductory text in the slices shell."""
968
+ if text:
969
+ self.write(text,type='Output')
970
+ try:
971
+ if self.interp.introText:
972
+ if text and not text.endswith(os.linesep):
973
+ self.write(os.linesep,type='Output')
974
+ self.write(self.interp.introText,type='Output')
975
+ except AttributeError:
976
+ pass
977
+
978
+ def setBuiltinKeywords(self):
979
+ """Create pseudo keywords as part of builtins.
980
+
981
+ This sets "close", "exit" and "quit" to a helpful string.
982
+ """
983
+ from six import PY3
984
+ if PY3:
985
+ import builtins
986
+ else:
987
+ import __builtin__
988
+ builtins = __builtin__
989
+ builtins.close = builtins.exit = builtins.quit = \
990
+ 'Click on the close button to leave the application.'
991
+ builtins.cd = cd
992
+ builtins.ls = ls
993
+ builtins.pwd = pwd
994
+ builtins.sx = sx
995
+
996
+
997
+ def quit(self):
998
+ """Quit the application."""
999
+ # XXX Good enough for now but later we want to send a close event.
1000
+ # In the close event handler we can make sure they want to
1001
+ # quit. Other applications, like PythonCard, may choose to
1002
+ # hide rather than quit so we should just post the event and
1003
+ # let the surrounding app decide what it wants to do.
1004
+ self.write('Click on the close button to leave the application.',
1005
+ type='Output')
1006
+
1007
+
1008
+ def setLocalShell(self):
1009
+ """Add 'slicesshell' to locals as reference to ShellFacade instance."""
1010
+ self.interp.locals['slicesshell'] = SlicesShellFacade(other=self)
1011
+
1012
+
1013
+ def execStartupScript(self, startupScript):
1014
+ """Execute the user's PYTHONSTARTUP script if they have one."""
1015
+ if startupScript and os.path.isfile(startupScript):
1016
+ text = 'Startup script executed: ' + startupScript
1017
+ if PY3:
1018
+ self.push('print(%r)' % text)
1019
+ self.push('with open(%r, "r") as f:\n'
1020
+ ' exec(f.read())\n' % (startupScript))
1021
+ else:
1022
+ self.push('print(%r); execfile(%r)' % (text, startupScript))
1023
+ self.interp.startupScript = startupScript
1024
+ else:
1025
+ self.push('')
1026
+
1027
+
1028
+ def about(self):
1029
+ """Display information about Py."""
1030
+ text = DISPLAY_TEXT % \
1031
+ (__author__, VERSION,
1032
+ sys.version.split()[0], wx.VERSION_STRING, str(wx.PlatformInfo),
1033
+ sys.platform)
1034
+ self.write(text.strip(),type='Output')
1035
+
1036
+ def BreakTextIntoCommands(self,text):
1037
+ """Turn a text block into multiple multi-line commands."""
1038
+
1039
+ #text = text.lstrip() # This should not be done!
1040
+ text = self.fixLineEndings(text)
1041
+ text = self.lstripPrompt(text)
1042
+ text = text.replace(os.linesep, '\n')
1043
+ lines = text.split('\n')
1044
+
1045
+ continuations = testForContinuations(text)
1046
+
1047
+ if len(continuations)==2: # Error case...
1048
+ return None,continuations[1]
1049
+ elif len(continuations)==4:
1050
+ stringContinuationList,indentationBlockList, \
1051
+ lineContinuationList,parentheticalContinuationList = continuations
1052
+
1053
+ commands = []
1054
+ command = ''
1055
+ for j,line in enumerate(lines):
1056
+ lstrip = line.lstrip()
1057
+
1058
+ # Get the first alnum word:
1059
+ first_word=[]
1060
+ for i in lstrip:
1061
+ if i.isalnum():
1062
+ first_word.append(i)
1063
+ else:
1064
+ break
1065
+ first_word = ''.join(first_word)
1066
+
1067
+ # Continue the command if it is blank, has indentation,
1068
+ # starts with else, elif,except, or finally
1069
+ # or previous line had a line continuation \
1070
+
1071
+ if j==0:
1072
+ stringCont = False
1073
+ lineCont=False
1074
+ else:
1075
+ stringCont = stringContinuationList[j-1]
1076
+ lineCont = lineContinuationList[j-1]
1077
+
1078
+ if line.strip() == '' or lstrip != line or \
1079
+ first_word in ['else','elif','except','finally'] or \
1080
+ stringCont or lineCont:
1081
+ # Multiline command. Add to the command.
1082
+ command += '\n'
1083
+ command += line
1084
+ else:
1085
+ # New command.
1086
+ if command:
1087
+ # Add the previous command to the list.
1088
+ commands.append(command)
1089
+ # Start a new command, which may be multiline.
1090
+ command = line
1091
+
1092
+ commands.append(command)
1093
+
1094
+ return commands
1095
+
1096
+ def MarkerSet(self,line,markerBitsSet):
1097
+ """MarkerSet is the Set command for MarkerGet"""
1098
+ markerBits=self.MarkerGet(line)
1099
+
1100
+ numMarkers=14
1101
+ for i in range(numMarkers):
1102
+ if (markerBitsSet & (1<<i)) and not (markerBits & (1<<i)):
1103
+ self.MarkerAdd(line,i)
1104
+ elif not (markerBitsSet & (1<<i)) and (markerBits & (1<<i)):
1105
+ self.MarkerDelete(line,i)
1106
+ def GetGroupingSlice(self,line_num=None):
1107
+ """Get the start/stop lines for the slice based on any line in the slice"""
1108
+ if line_num==None:
1109
+ line_num=self.GetCurrentLine()
1110
+
1111
+ num_lines=self.GetLineCount()
1112
+
1113
+ for i in range(line_num,-1,-1):
1114
+ if self.MarkerGet(i) & (1<<GROUPING_START | 1<<GROUPING_START_FOLDED):
1115
+ break
1116
+ start_line=i
1117
+
1118
+ addition=0
1119
+
1120
+ for i in range(line_num,num_lines):
1121
+ if self.MarkerGet(i) & 1<<GROUPING_END:
1122
+ break
1123
+ elif (i>line_num) and ( self.MarkerGet(i)
1124
+ & (1<<GROUPING_START | 1<<GROUPING_START_FOLDED) ):
1125
+ addition=-1
1126
+ break # the solo case...
1127
+ stop_line=i+addition
1128
+
1129
+ return start_line,stop_line
1130
+
1131
+ def GetIOSlice(self,line_num=None):
1132
+ """Get the start/stop lines for the slice based on any line in the slice"""
1133
+ if line_num==None:
1134
+ line_num=self.GetCurrentLine()
1135
+
1136
+ num_lines=self.GetLineCount()
1137
+
1138
+ for i in range(line_num,-1,-1):
1139
+ if self.MarkerGet(i) & IO_ANY_START_MASK:
1140
+ break
1141
+ start_line=i
1142
+
1143
+ addition=0
1144
+
1145
+ for i in range(line_num,num_lines):
1146
+ if self.MarkerGet(i) & IO_END_MASK:
1147
+ break
1148
+ elif (i>line_num) and (self.MarkerGet(i) & IO_ANY_START_MASK):
1149
+ addition=-1
1150
+ break # the solo case...
1151
+ stop_line=i+addition
1152
+
1153
+ return start_line,stop_line
1154
+
1155
+ def FoldGroupingSlice(self,line_num=None):
1156
+ if line_num==None:
1157
+ line_num=self.GetCurrentLine()
1158
+
1159
+ start,end=self.GetGroupingSlice(line_num)
1160
+ self.HideLines(start+1,end)
1161
+ marker=self.MarkerGet(start)
1162
+ self.clearGroupingMarkers(start)
1163
+ self.MarkerAdd(start,GROUPING_START_FOLDED)
1164
+ self.clearIOMarkers(start)
1165
+ if marker & ( 1<<INPUT_START | 1<<INPUT_START_FOLDED ):
1166
+ self.MarkerAdd(start,INPUT_START_FOLDED)
1167
+ elif marker & ( 1<<OUTPUT_START | 1<<OUTPUT_START_FOLDED ):
1168
+ self.MarkerAdd(start,OUTPUT_START_FOLDED)
1169
+ self.MarkerAdd(start,OUTPUT_BG)
1170
+ else:
1171
+ pass #print('Bad Markers!!!')
1172
+ def FoldIOSlice(self,line_num=None):
1173
+ if line_num==None:
1174
+ line_num=self.GetCurrentLine()
1175
+
1176
+ start,end=self.GetIOSlice(line_num)
1177
+ self.HideLines(start+1,end)
1178
+ marker=self.MarkerGet(start)
1179
+ if (self.MarkerGet(start) & \
1180
+ (1<<GROUPING_START | 1<<GROUPING_START_FOLDED )) and \
1181
+ (self.MarkerGet(end) & 1<<GROUPING_END):
1182
+ self.clearGroupingMarkers(start)
1183
+ self.MarkerAdd(start,GROUPING_START_FOLDED)
1184
+ self.clearIOMarkers(start)
1185
+ if marker & ( 1<<INPUT_START | 1<<INPUT_START_FOLDED ):
1186
+ self.MarkerAdd(start,INPUT_START_FOLDED)
1187
+ elif marker & ( 1<<OUTPUT_START | 1<<OUTPUT_START_FOLDED ):
1188
+ self.MarkerAdd(start,OUTPUT_START_FOLDED)
1189
+ self.MarkerAdd(start,OUTPUT_BG)
1190
+ else:
1191
+ pass #print('Bad Markers!!!')
1192
+ def UnFoldGroupingSlice(self,line_num=None):
1193
+ if line_num==None:
1194
+ line_num=self.GetCurrentLine()
1195
+
1196
+ start,end=self.GetGroupingSlice(line_num)
1197
+ self.ShowLines(start+1,end)
1198
+ self.clearGroupingMarkers(start)
1199
+ self.MarkerAdd(start,GROUPING_START)
1200
+ for i in range(start,end):
1201
+ marker=self.MarkerGet(i)
1202
+ if marker & (1<<INPUT_START | 1<<INPUT_START_FOLDED):
1203
+ self.clearIOMarkers(i)
1204
+ self.MarkerAdd(i,INPUT_START)
1205
+ elif marker & (1<<OUTPUT_START | 1<<OUTPUT_START_FOLDED):
1206
+ self.clearIOMarkers(i)
1207
+ self.MarkerAdd(i,OUTPUT_START)
1208
+ self.MarkerAdd(i,OUTPUT_BG)
1209
+
1210
+ def UnFoldIOSlice(self,line_num=None):
1211
+ if line_num==None:
1212
+ line_num=self.GetCurrentLine()
1213
+
1214
+ start,end=self.GetIOSlice(line_num)
1215
+ self.ShowLines(start+1,end)
1216
+ marker=self.MarkerGet(start)
1217
+ if (self.MarkerGet(start) & \
1218
+ (1<<GROUPING_START | 1<<GROUPING_START_FOLDED )) and \
1219
+ (self.MarkerGet(end) & 1<<GROUPING_END):
1220
+ self.clearGroupingMarkers(start)
1221
+ self.MarkerAdd(start,GROUPING_START)
1222
+ self.clearIOMarkers(start)
1223
+ if marker & 1<<INPUT_START_FOLDED:
1224
+ self.MarkerAdd(start,INPUT_START)
1225
+ elif marker & 1<<OUTPUT_START_FOLDED:
1226
+ self.MarkerAdd(start,OUTPUT_START)
1227
+ self.MarkerAdd(start,OUTPUT_BG)
1228
+
1229
+ def DeleteOutputSlicesAfter(self,line_num=None):
1230
+ """Delete all outputs after an input"""
1231
+ if line_num==None:
1232
+ line_num=self.GetCurrentLine()
1233
+
1234
+ num_lines=self.GetLineCount()
1235
+
1236
+ if self.MarkerGet(line_num) & OUTPUT_MASK:
1237
+ #print('You can only run "DeleteOutputSlicesAfter" from an Input slice!')
1238
+ return
1239
+
1240
+ startIn,endIn=self.GetIOSlice(line_num)
1241
+ startGrouping,endGrouping=self.GetGroupingSlice(line_num)
1242
+
1243
+ if endIn<endGrouping:
1244
+ self.SetSelection(self.PositionFromLine(endIn+1),
1245
+ self.PositionFromLine(endGrouping+1))
1246
+ self.ReplaceSelection('',sliceDeletion=True)
1247
+
1248
+ new_pos=self.GetLineEndPosition(line_num)
1249
+ self.SetCurrentPos(new_pos)
1250
+ self.SetSelection(new_pos,new_pos)
1251
+
1252
+ def SplitSlice(self,line_num=None):
1253
+ if line_num==None:
1254
+ line_num=self.GetCurrentLine()
1255
+
1256
+ start_num,end_num=self.GetIOSlice(line_num)
1257
+
1258
+ if self.MarkerGet(line_num) & INPUT_MASK:
1259
+ type='Input'
1260
+ start=INPUT_START
1261
+ end=INPUT_END
1262
+ splitGrouping=True
1263
+ elif self.MarkerGet(line_num) & OUTPUT_MASK:
1264
+ type='Output'
1265
+ start=OUTPUT_START
1266
+ end=OUTPUT_END
1267
+ splitGrouping=False
1268
+
1269
+ if start_num==end_num:
1270
+ return # Can't split one line!
1271
+ elif start_num==line_num:
1272
+ self.clearIOMarkers(line_num+1)
1273
+ self.MarkerAdd(line_num+1,start)
1274
+ if type=='Output': self.MarkerAdd(line_num+1,OUTPUT_BG)
1275
+ if splitGrouping:
1276
+ self.clearGroupingMarkers(line_num+1)
1277
+ self.MarkerAdd(line_num+1,GROUPING_START)
1278
+ else:
1279
+ self.clearIOMarkers(line_num)
1280
+ self.MarkerAdd(line_num,start)
1281
+ if type=='Output': self.MarkerAdd(line_num,OUTPUT_BG)
1282
+ if splitGrouping:
1283
+ self.clearGroupingMarkers(line_num)
1284
+ self.MarkerAdd(line_num,GROUPING_START)
1285
+ if line_num-1>start_num:
1286
+ self.clearIOMarkers(line_num-1)
1287
+ self.MarkerAdd(line_num-1,end)
1288
+ if type=='Output': self.MarkerAdd(line_num-1,OUTPUT_BG)
1289
+ if splitGrouping:
1290
+ self.clearGroupingMarkers(line_num-1)
1291
+ self.MarkerAdd(line_num-1,GROUPING_END)
1292
+
1293
+ def BackspaceWMarkers(self,force=False):
1294
+ # Warning: This is not good at checking for bad markers!
1295
+ c_before=self.GetCharAt(self.GetCurrentPos() - 1)
1296
+ c_after=self.GetCharAt(self.GetCurrentPos())
1297
+
1298
+ if c_before==0:
1299
+ # Disallow deleting the first line or it will destroy the markers...
1300
+ return False
1301
+ elif c_before in (ord('\n'),ord('\r')):
1302
+ line_num=self.GetCurrentLine()
1303
+
1304
+ marker=self.MarkerGet(line_num)
1305
+ marker_before=self.MarkerGet(line_num-1)
1306
+ marker_after=self.MarkerGet(line_num+1)
1307
+ if marker_before & ( 1<<GROUPING_END ) :
1308
+ return False # Disallow deleting lines between slices...
1309
+ elif marker & ( 1<<GROUPING_START | 1<<GROUPING_START_FOLDED ) :
1310
+ return False # Disallow deleting lines between slices...
1311
+ else:
1312
+ if marker_before & ( 1<<GROUPING_START | 1<<GROUPING_START_FOLDED ) :
1313
+ self.clearGroupingMarkers(line_num)
1314
+ elif marker & ( 1<<GROUPING_END ) :
1315
+ self.clearGroupingMarkers(line_num-1)
1316
+
1317
+ if (marker_before & 1<<INPUT_END) and force:
1318
+ # Special case for use in processLine
1319
+ self.clearIOMarkers(line_num)
1320
+ elif marker_before & (1<<INPUT_END | 1<<OUTPUT_END):
1321
+ return False # Disallow deleting lines between slices...
1322
+ elif marker & ( 1<<INPUT_START | 1<<INPUT_START_FOLDED ) :
1323
+ return False # Disallow deleting lines between slices...
1324
+ else:
1325
+ if marker_before & (1<<INPUT_START | 1<<INPUT_START_FOLDED |
1326
+ 1<<OUTPUT_START | 1<<OUTPUT_START_FOLDED):
1327
+ self.clearIOMarkers(line_num)
1328
+ elif marker & ( 1<<INPUT_END | 1<<OUTPUT_END ) :
1329
+ self.clearIOMarkers(line_num-1)
1330
+
1331
+ return True # If everything went well, return True and do the delete...
1332
+
1333
+ def ForwardDeleteWMarkers(self):
1334
+ c_before=self.GetCharAt(self.GetCurrentPos() - 1)
1335
+ c_after=self.GetCharAt(self.GetCurrentPos())
1336
+ if c_after==0:
1337
+ # Disallow deleting the first line or it will destroy the markers...
1338
+ return False
1339
+ elif c_after in (ord('\n'),ord('\r')):
1340
+ line_num=self.GetCurrentLine()
1341
+
1342
+ marker=self.MarkerGet(line_num)
1343
+ marker_before=self.MarkerGet(line_num-1)
1344
+ marker_after=self.MarkerGet(line_num+1)
1345
+ if marker & ( 1<<GROUPING_END ) :
1346
+ return False # Disallow deleting lines between slices...
1347
+ elif marker_after & ( 1<<GROUPING_START | 1<<GROUPING_START_FOLDED ) :
1348
+ return False # Disallow deleting lines between slices...
1349
+ else:
1350
+ if marker & ( 1<<GROUPING_START | 1<<GROUPING_START_FOLDED ) :
1351
+ self.clearGroupingMarkers(line_num+1)
1352
+ elif marker_after & ( 1<<GROUPING_END ) :
1353
+ self.clearGroupingMarkers(line_num)
1354
+
1355
+ if marker & ( 1<<INPUT_END | 1<<OUTPUT_END ) :
1356
+ return False # Disallow deleting lines between slices...
1357
+ elif marker_after & ( 1<<INPUT_START | 1<<INPUT_START_FOLDED ) :
1358
+ return False # Disallow deleting lines between slices...
1359
+ else:
1360
+ if marker & (1<<INPUT_START | 1<<INPUT_START_FOLDED |
1361
+ 1<<OUTPUT_START | 1<<OUTPUT_START_FOLDED) :
1362
+ self.clearIOMarkers(line_num+1)
1363
+ elif marker_after & ( 1<<INPUT_END | 1<<OUTPUT_END ) :
1364
+ self.clearIOMarkers(line_num)
1365
+
1366
+ return True
1367
+
1368
+ def GetIOSelection(self):
1369
+ started=False
1370
+ start=0
1371
+ end=self.GetLineCount()-1
1372
+ type=None
1373
+ for i in range(self.GetLineCount()):
1374
+ if self.MarkerGet(i) & 1<<IO_SELECTING:
1375
+ if started==False:
1376
+ start=i
1377
+ if self.MarkerGet(i) & INPUT_MASK:
1378
+ type='input'
1379
+ elif self.MarkerGet(i) & OUTPUT_MASK:
1380
+ type='output'
1381
+ else:
1382
+ if self.MarkerGet(i) & INPUT_MASK:
1383
+ if type=='output':
1384
+ end=i-1
1385
+ break
1386
+ elif self.MarkerGet(i) & OUTPUT_MASK:
1387
+ if type=='input':
1388
+ end=i-1
1389
+ break
1390
+ started=True
1391
+ elif started==True:
1392
+ end=i-1
1393
+ break
1394
+
1395
+ if started==False:
1396
+ #print('No Selection!!')
1397
+ self.SliceSelection=False
1398
+
1399
+ return start,end
1400
+
1401
+ def MergeAdjacentSlices(self):
1402
+ """This function merges all adjacent selected slices.\n""" + \
1403
+ """Right now, only IO Merging is allowed."""
1404
+ started=False
1405
+ start=0
1406
+ end=self.GetLineCount()-1
1407
+ type=None
1408
+ for i in range(self.GetLineCount()):
1409
+ if self.MarkerGet(i) & 1<<IO_SELECTING:
1410
+ if started==False:
1411
+ start=i
1412
+ if self.MarkerGet(i) & INPUT_MASK:
1413
+ type='input'
1414
+ elif self.MarkerGet(i) & OUTPUT_MASK:
1415
+ type='output'
1416
+ else:
1417
+ if self.MarkerGet(i) & INPUT_MASK:
1418
+ if type=='output':
1419
+ end=i-1
1420
+ break
1421
+ else:
1422
+ self.clearIOMarkers(i)
1423
+ self.clearGroupingMarkers(i)
1424
+ self.MarkerAdd(i,INPUT_MIDDLE)
1425
+ self.MarkerAdd(i,GROUPING_MIDDLE)
1426
+ elif self.MarkerGet(i) & OUTPUT_MASK:
1427
+ if type=='input':
1428
+ end=i-1
1429
+ break
1430
+ else:
1431
+ self.clearIOMarkers(i)
1432
+ self.clearGroupingMarkers(i)
1433
+ self.MarkerAdd(i,OUTPUT_MIDDLE)
1434
+ self.MarkerAdd(i,OUTPUT_BG)
1435
+ self.MarkerAdd(i,GROUPING_MIDDLE)
1436
+ started=True
1437
+ elif started==True:
1438
+ end=i-1
1439
+ break
1440
+
1441
+ if started and end!=start:
1442
+ self.clearIOMarkers(end)
1443
+ self.clearGroupingMarkers(end)
1444
+ if type=='input':
1445
+ self.MarkerAdd(end,INPUT_END)
1446
+ if end+1<self.GetLineCount():
1447
+ if self.MarkerGet(end+1) & OUTPUT_MASK:
1448
+ self.MarkerAdd(end,GROUPING_MIDDLE)
1449
+ else:
1450
+ self.MarkerAdd(end,GROUPING_END)
1451
+ else:
1452
+ self.MarkerAdd(end,GROUPING_END)
1453
+ else:
1454
+ if self.MarkerGet(start) & 1<<GROUPING_END:
1455
+ self.clearGroupingMarkers(start)
1456
+ self.MarkerAdd(start,GROUPING_MIDDLE)
1457
+ self.MarkerAdd(end,OUTPUT_END)
1458
+ self.MarkerAdd(end,OUTPUT_BG)
1459
+ self.MarkerAdd(end,GROUPING_END)
1460
+
1461
+
1462
+ def SliceSelectionDelete(self):
1463
+ """Deletion of any selected and possibly discontinuous slices."""
1464
+ if not self.SliceSelection:
1465
+ return
1466
+
1467
+ # collect the line numbers to be deleted...
1468
+ selectedSlices=[]
1469
+ start,end=None,None
1470
+ for i in range(self.GetLineCount()):
1471
+ if self.MarkerGet(i) & (1<<GROUPING_SELECTING | 1<<IO_SELECTING):
1472
+ if start==None:
1473
+ start=i
1474
+ end=i
1475
+ elif start!=None:
1476
+ selectedSlices.append([start,end])
1477
+ start,end=None,None
1478
+ if start!=None:
1479
+ selectedSlices.append([start,end])
1480
+
1481
+ # Unselect everything
1482
+ self.MarginUnselectAll()
1483
+ self.SliceSelection=False
1484
+
1485
+ # Going in reverse, delete the selections, fixing the markers as we go...
1486
+ for i in range(len(selectedSlices)-1,-1,-1):
1487
+ self.SetSelection(self.PositionFromLine(selectedSlices[i][0]),
1488
+ self.GetLineEndPosition(selectedSlices[i][1])+1)
1489
+
1490
+ markerNext = self.MarkerGet(selectedSlices[i][1]+1)
1491
+
1492
+ self.ReplaceSelection('',sliceDeletion=True)
1493
+
1494
+ cur_line=self.GetCurrentLine()
1495
+
1496
+ # If we've made a mess of the grouping markers, clean it up...
1497
+ if ((self.MarkerGet(cur_line-1) & 1<<GROUPING_END) and
1498
+ (self.MarkerGet(cur_line) & ( 1<<GROUPING_MIDDLE | 1<<GROUPING_END ) )):
1499
+ self.clearGroupingMarkers(cur_line)
1500
+ self.MarkerAdd(cur_line,GROUPING_START)
1501
+ elif (( self.MarkerGet(cur_line-1) & 1<<GROUPING_MIDDLE ) and
1502
+ ( self.MarkerGet(cur_line) &
1503
+ ( 1<<GROUPING_START | 1<<GROUPING_START_FOLDED ) )):
1504
+ self.clearGroupingMarkers(cur_line-1)
1505
+ self.MarkerAdd(cur_line-1,GROUPING_END)
1506
+
1507
+ if markerNext & 1<<OUTPUT_START:
1508
+ self.clearIOMarkers(cur_line)
1509
+ self.MarkerAdd(cur_line,OUTPUT_START)
1510
+ self.MarkerAdd(cur_line,OUTPUT_BG)
1511
+ elif markerNext & 1<<OUTPUT_START_FOLDED:
1512
+ self.clearIOMarkers(cur_line)
1513
+ self.MarkerAdd(cur_line,OUTPUT_START_FOLDED)
1514
+ self.MarkerAdd(cur_line,OUTPUT_BG)
1515
+
1516
+ return
1517
+
1518
+ def OnChar(self, event):
1519
+ """Keypress event handler.
1520
+
1521
+ Only receives an event if OnKeyDown calls event.Skip() for the
1522
+ corresponding event."""
1523
+
1524
+ if self.noteMode:
1525
+ event.Skip()
1526
+ return
1527
+
1528
+ # Prevent modification of output slices
1529
+ if not self.CanEdit():
1530
+ return
1531
+ key = event.GetKeyCode()
1532
+ currpos = self.GetCurrentPos()
1533
+ stoppos = self.PositionFromLine(self.GetCurrentLine())
1534
+
1535
+ # Return (Enter) needs to be ignored in this handler.
1536
+ if key in [wx.WXK_RETURN, wx.WXK_NUMPAD_ENTER]:
1537
+ pass
1538
+ elif key in self.autoCompleteKeys:
1539
+ # Usually the dot (period) key activates auto completion.
1540
+ # Get the command between the prompt and the cursor. Add
1541
+ # the autocomplete character to the end of the command.
1542
+ if self.AutoCompActive():
1543
+ self.AutoCompCancel()
1544
+ command = self.GetTextRange(stoppos, currpos) + chr(key)
1545
+
1546
+ # write with undo wrapper...
1547
+ cpos=self.GetCurrentPos()
1548
+ s=chr(key)
1549
+ #ADD UNDO
1550
+ self.UpdateUndoHistoryBefore('insert',s,cpos,cpos+len(s),
1551
+ forceNewAction=False)
1552
+ self.write(s,type='Input')
1553
+ self.UpdateUndoHistoryAfter()
1554
+
1555
+ if self.autoComplete:
1556
+ self.autoCompleteShow(command)
1557
+ elif key == ord('('):
1558
+ # The left paren activates a call tip and cancels an
1559
+ # active auto completion.
1560
+ if self.AutoCompActive():
1561
+ self.AutoCompCancel()
1562
+ # Get the command between the prompt and the cursor. Add
1563
+ # the '(' to the end of the command.
1564
+ self.ReplaceSelection('')
1565
+ command = self.GetTextRange(stoppos, currpos) + '('
1566
+
1567
+ # write with undo wrapper...
1568
+ cpos=self.GetCurrentPos()
1569
+ s='('
1570
+ self.UpdateUndoHistoryBefore('insert',s,cpos,cpos+len(s),
1571
+ forceNewAction=True)
1572
+ self.undoHistory[self.undoIndex]['allowsAppend']=True
1573
+ self.write(s,type='Input')
1574
+ self.UpdateUndoHistoryAfter()
1575
+
1576
+ self.autoCallTipShow(command,
1577
+ self.GetCurrentPos() == self.GetTextLength())
1578
+ else:
1579
+ # Allow the normal event handling to take place.
1580
+ # Use undo wrapper
1581
+ cpos=self.GetCurrentPos()
1582
+ try:
1583
+ s=chr(key)
1584
+ self.UpdateUndoHistoryBefore('insert',s,cpos,cpos+len(s))
1585
+ event.Skip()
1586
+ self.UpdateUndoHistoryAfter()
1587
+ except:
1588
+ event.Skip()
1589
+
1590
+ def AutoCompActiveCallback(self):
1591
+ numChars=self.GetTextLength()-self.TotalLengthForAutoCompActiveCallback
1592
+ if numChars==0:
1593
+ self.undoIndex-=1
1594
+ del(self.undoHistory[-1])
1595
+ else:
1596
+ uH=self.undoHistory
1597
+ uI=self.undoIndex
1598
+ cpos=uH[uI]['posStart']
1599
+ s=''.join([chr(self.GetCharAt(cpos+i)) for i in range(numChars)])
1600
+ s.replace(os.linesep,'\n')
1601
+ self.undoHistory[self.undoIndex]['charList'] = s
1602
+ self.undoHistory[self.undoIndex]['posEnd'] = cpos + numChars
1603
+ self.undoHistory[self.undoIndex]['numLines'] = len(s.split('\n'))
1604
+ self.UpdateUndoHistoryAfter()
1605
+
1606
+ def OnKeyDown(self, event):
1607
+ """Key down event handler."""
1608
+
1609
+ key = event.GetKeyCode()
1610
+ # If the auto-complete window is up let it do its thing.
1611
+ if self.AutoCompActive():
1612
+ if key in [wx.WXK_RETURN, wx.WXK_NUMPAD_ENTER]:
1613
+ cpos=self.GetCurrentPos()
1614
+ self.UpdateUndoHistoryBefore('insert','dummy',cpos,cpos+5,
1615
+ forceNewAction=True)
1616
+ self.undoHistory[self.undoIndex]['allowsAppend'] = True
1617
+ self.TotalLengthForAutoCompActiveCallback=self.GetTextLength()
1618
+ event.Skip()
1619
+ wx.CallAfter(self.AutoCompActiveCallback)
1620
+ if key in [wx.WXK_DELETE,wx.WXK_BACK]:
1621
+ self.AutoCompCancel()
1622
+ else:
1623
+ event.Skip()
1624
+ return
1625
+
1626
+ #DNM
1627
+ # Prevent modification of output slices
1628
+ controlDown = event.ControlDown()
1629
+ altDown = event.AltDown()
1630
+ shiftDown = event.ShiftDown()
1631
+ currpos = self.GetCurrentPos()
1632
+ endpos = self.GetTextLength()
1633
+ selecting = self.GetSelectionStart() != self.GetSelectionEnd()
1634
+
1635
+ if key == wx.WXK_F12: #seb
1636
+ if self.noteMode:
1637
+ # self.promptPosStart not used anyway - or ?
1638
+ ## # We don't need to do this any more!
1639
+ ## self.promptPosEnd = self.PositionFromLine(self.GetLineCount()-1 ) +
1640
+ ## len(str(sys.ps1))
1641
+ ## self.GotoLine(self.GetLineCount())
1642
+ ## self.GotoPos(self.promptPosEnd)
1643
+ ## self.prompt() #make sure we have a prompt
1644
+ self.SetCaretForeground("black")
1645
+ self.SetCaretWidth(1) #default
1646
+ self.SetCaretPeriod(500) #default
1647
+ else:
1648
+ self.SetCaretForeground("red")
1649
+ self.SetCaretWidth(4)
1650
+ self.SetCaretPeriod(0) #steady
1651
+
1652
+ self.noteMode = not self.noteMode
1653
+ return
1654
+ if self.noteMode:
1655
+ event.Skip()
1656
+ return
1657
+
1658
+ doLineBreak=False
1659
+ doSubmitCommand=False
1660
+ doPass=False
1661
+ # Return is used to insert a line break.
1662
+ # In Shell Mode, hit Return or Enter twice to submit a command
1663
+ if ((not controlDown and not shiftDown and not altDown) and
1664
+ key in [wx.WXK_RETURN,]):
1665
+ if self.mode=='SlicesMode':
1666
+ doLineBreak=True
1667
+ elif self.mode=='ShellMode':
1668
+ startLine,endLine = self.GetIOSlice()
1669
+ startpos = self.PositionFromLine(startLine)
1670
+ endpos = self.GetLineEndPosition(endLine)
1671
+ command = self.GetTextRange(startpos, endpos)
1672
+ strCont,indentBlock,lineCont,parenCont = testForContinuations(command,ignoreErrors=True)
1673
+
1674
+ lastLine = command.split('\n')[-1]
1675
+ if lastLine.lstrip()=='': # all whitespace...
1676
+ stillIndented=False
1677
+ elif lastLine[0]==' ':
1678
+ stillIndented=True
1679
+ else:
1680
+ stillIndented=False
1681
+
1682
+ if strCont[-1] or indentBlock[-1] or lineCont[-1] or \
1683
+ parenCont[-1]:
1684
+ doLineBreak=True
1685
+ elif stillIndented:
1686
+ new_pos=self.GetLineEndPosition(endLine)
1687
+ self.SetCurrentPos(new_pos)
1688
+ self.SetSelection(new_pos,new_pos)
1689
+ doLineBreak=True
1690
+ elif self.GetCurrentLine()!=endLine:
1691
+ new_pos=self.GetLineEndPosition(endLine)
1692
+ self.SetCurrentPos(new_pos)
1693
+ self.SetSelection(new_pos,new_pos)
1694
+ doPass = True
1695
+ else:
1696
+ doSubmitCommand=True
1697
+ # Enter (Shift/Ctrl + Enter/Return) submits a command to the interpreter.
1698
+ # In Shell Mode, hit Return or Enter twice to submit a command
1699
+ elif ( key in [wx.WXK_NUMPAD_ENTER,] or
1700
+ ( (shiftDown or controlDown) and key in [wx.WXK_RETURN,
1701
+ wx.WXK_NUMPAD_ENTER] ) ):
1702
+ if self.mode=='SlicesMode':
1703
+ doSubmitCommand=True
1704
+ elif self.mode=='ShellMode':
1705
+ doLineBreak=True
1706
+
1707
+ #Only relevant in ShellMode...
1708
+
1709
+ if doPass:
1710
+ pass
1711
+ elif doLineBreak or doSubmitCommand:
1712
+ if self.CallTipActive():
1713
+ self.CallTipCancel()
1714
+ elif self.SliceSelection:
1715
+ for i in range(self.GetLineCount()):
1716
+ if self.MarkerGet(i) & 1<<GROUPING_SELECTING:
1717
+ self.DoMarginClick(i, 2, shiftDown, controlDown)
1718
+ break
1719
+ elif self.MarkerGet(i) & 1<<IO_SELECTING:
1720
+ self.DoMarginClick(i, 3, shiftDown, controlDown)
1721
+ break
1722
+ elif doLineBreak:
1723
+ self.insertLineBreak()
1724
+ #Only relevant in ShellMode...
1725
+ elif doSubmitCommand:
1726
+ self.DeleteOutputSlicesAfter()
1727
+ self.processLine()
1728
+
1729
+ # Let Ctrl-Alt-* get handled normally.
1730
+ elif controlDown and altDown:
1731
+ event.Skip()
1732
+
1733
+ # Clear the current, unexecuted command.
1734
+ elif key == wx.WXK_ESCAPE:
1735
+ if self.CallTipActive():
1736
+ event.Skip()
1737
+ # Clear the current command
1738
+ elif key == wx.WXK_BACK and controlDown and shiftDown:
1739
+ self.clearCommand()
1740
+
1741
+ # Increase font size.
1742
+ elif controlDown and key in (ord(']'), wx.WXK_NUMPAD_ADD):
1743
+ dispatcher.send(signal='FontIncrease')
1744
+
1745
+ # Decrease font size.
1746
+ elif controlDown and key in (ord('['), wx.WXK_NUMPAD_SUBTRACT):
1747
+ dispatcher.send(signal='FontDecrease')
1748
+
1749
+ # Default font size.
1750
+ elif controlDown and key in (ord('='), wx.WXK_NUMPAD_DIVIDE):
1751
+ dispatcher.send(signal='FontDefault')
1752
+
1753
+ # Cut to the clipboard.
1754
+ elif (controlDown and key in (ord('X'), ord('x'))) \
1755
+ or (shiftDown and key == wx.WXK_DELETE):
1756
+ self.Cut()
1757
+
1758
+ # Copy to the clipboard.
1759
+ elif controlDown and not shiftDown \
1760
+ and key in (ord('C'), ord('c'), wx.WXK_INSERT):
1761
+ self.Copy()
1762
+
1763
+ # Copy to the clipboard, including prompts.
1764
+ elif controlDown and shiftDown \
1765
+ and key in (ord('C'), ord('c'), wx.WXK_INSERT):
1766
+ self.CopyWithPrompts()
1767
+
1768
+ # Copy to the clipboard, including prefixed prompts.
1769
+ elif altDown and not controlDown \
1770
+ and key in (ord('C'), ord('c'), wx.WXK_INSERT):
1771
+ self.CopyWithPromptsPrefixed()
1772
+
1773
+ # Home needs to be aware of the prompt.
1774
+ elif controlDown and key == wx.WXK_HOME:
1775
+ # Go to the beginning of the IO Slice
1776
+ curLine = self.GetCurrentLine()
1777
+ IOstart = self.GetIOSlice(curLine)[0]
1778
+ home = self.PositionFromLine(IOstart)
1779
+ if currpos == home and \
1780
+ IOstart > 0:
1781
+ home = self.PositionFromLine(self.GetIOSlice(curLine-1)[0])
1782
+ self.SetCurrentPos(home)
1783
+ if not selecting and not shiftDown:
1784
+ self.SetAnchor(home)
1785
+ self.EnsureCaretVisible()
1786
+
1787
+ elif controlDown and key == wx.WXK_END:
1788
+ curLine = self.GetCurrentLine()
1789
+ IOend = self.GetIOSlice(curLine)[1]
1790
+ end = self.GetLineEndPosition(IOend)
1791
+ if currpos == end and \
1792
+ IOend < self.GetLineCount()-1:
1793
+ end = self.GetLineEndPosition(self.GetIOSlice(curLine+1)[1])
1794
+ self.SetCurrentPos(end)
1795
+ if not selecting and not shiftDown:
1796
+ self.SetAnchor(end)
1797
+ self.EnsureCaretVisible()
1798
+
1799
+ elif controlDown and key == wx.WXK_PAGEUP:
1800
+ pos=0
1801
+ if currpos > pos:
1802
+ self.SetCurrentPos(pos)
1803
+ if not selecting and not shiftDown:
1804
+ self.SetAnchor(pos)
1805
+ self.EnsureCaretVisible()
1806
+
1807
+ elif controlDown and key == wx.WXK_PAGEDOWN:
1808
+ pos = self.GetLineEndPosition(self.GetLineCount()-1)
1809
+ if currpos < pos:
1810
+ self.SetCurrentPos(pos)
1811
+ if not selecting and not shiftDown:
1812
+ self.SetAnchor(pos)
1813
+ self.EnsureCaretVisible()
1814
+
1815
+ elif selecting and key not in NAVKEYS and not self.CanEdit():
1816
+ pass
1817
+
1818
+ # Paste from the clipboard.
1819
+ elif (controlDown and not shiftDown and key in (ord('V'), ord('v'))) \
1820
+ or (shiftDown and not controlDown and key == wx.WXK_INSERT):
1821
+ self.Paste()
1822
+
1823
+ # Paste from the clipboard, run commands.
1824
+ elif controlDown and shiftDown and \
1825
+ key in (ord('V'), ord('v')) and self.CanEdit():
1826
+ self.PasteAndRun()
1827
+
1828
+ # Replace with the previous command from the history buffer.
1829
+ elif (controlDown and not shiftDown and key == wx.WXK_UP) \
1830
+ or (altDown and key in (ord('P'), ord('p'))) and self.CanEdit():
1831
+ self.OnHistoryReplace(step=+1)
1832
+
1833
+ # Replace with the next command from the history buffer.
1834
+ elif (controlDown and not shiftDown and key == wx.WXK_DOWN) \
1835
+ or (altDown and key in (ord('N'), ord('n'))) and self.CanEdit():
1836
+ self.OnHistoryReplace(step=-1)
1837
+
1838
+ # Insert the previous command from the history buffer.
1839
+ elif (controlDown and shiftDown and key == wx.WXK_UP) and \
1840
+ self.CanEdit():
1841
+ self.OnHistoryInsert(step=+1)
1842
+
1843
+ # Insert the next command from the history buffer.
1844
+ elif (controlDown and shiftDown and key == wx.WXK_DOWN) and \
1845
+ self.CanEdit():
1846
+ self.OnHistoryInsert(step=-1)
1847
+
1848
+ # Ctrl-Space shows Auto Completion
1849
+ # Ctrl-Shift-Space shows CallTips
1850
+ elif controlDown and key == wx.WXK_SPACE:
1851
+ self.OnCallTipAutoCompleteManually(shiftDown)
1852
+
1853
+ # Ctrl+Shift+H is used to complete Text (from already typed words)
1854
+ elif controlDown and shiftDown and key in [ord('H')]:
1855
+ self.OnShowCompHistory()
1856
+
1857
+ # Search up the history for the text in front of the cursor.
1858
+ elif key == wx.WXK_F8:
1859
+ self.OnHistorySearch()
1860
+
1861
+ # Don't backspace over the latest non-continuation prompt.
1862
+ elif key == wx.WXK_BACK:
1863
+ if self.SliceSelection:
1864
+ self.SliceSelectionDelete()
1865
+ wx.CallAfter(self.RestoreFirstMarker)
1866
+ elif selecting and self.CanEdit():
1867
+ self.ReplaceSelection('')
1868
+ #event.Skip()
1869
+ elif self.CanEdit():
1870
+ doDelete=True
1871
+ cur_line=self.GetCurrentLine()
1872
+ if not cur_line==0 and \
1873
+ self.GetCurrentPos()==self.PositionFromLine(cur_line):
1874
+ if self.MarkerGet(cur_line-1) & OUTPUT_MASK:
1875
+ doDelete=False
1876
+
1877
+ if doDelete:
1878
+ cpos=self.GetCurrentPos()
1879
+ s=chr(self.GetCharAt(cpos-1))
1880
+ self.UpdateUndoHistoryBefore('delete',s,cpos-1,cpos)
1881
+ if self.BackspaceWMarkers():
1882
+ event.Skip()
1883
+
1884
+ wx.CallAfter(self.RestoreFirstMarker)
1885
+
1886
+ elif key == wx.WXK_DELETE:
1887
+ if self.SliceSelection:
1888
+ self.SliceSelectionDelete()
1889
+ wx.CallAfter(self.RestoreFirstMarker)
1890
+ elif selecting and self.CanEdit():
1891
+ self.ReplaceSelection('')
1892
+ #event.Skip()
1893
+ elif self.CanEdit():
1894
+ doDelete=True
1895
+ cur_line=self.GetCurrentLine()
1896
+ if not cur_line==self.GetLineCount()-1 and \
1897
+ self.GetCurrentPos()==self.GetLineEndPosition(cur_line):
1898
+ if self.MarkerGet(cur_line+1) & OUTPUT_MASK:
1899
+ doDelete=False
1900
+
1901
+ if doDelete:
1902
+ cpos=self.GetCurrentPos()
1903
+ s=chr(self.GetCharAt(cpos))
1904
+ self.UpdateUndoHistoryBefore('delete',s,cpos,cpos+1)
1905
+ if self.ForwardDeleteWMarkers():
1906
+ event.Skip()
1907
+
1908
+ wx.CallAfter(self.RestoreFirstMarker)
1909
+
1910
+ # Only allow these keys after the latest prompt.
1911
+ elif key == wx.WXK_TAB and self.CanEdit():
1912
+ # use the same mechanism as with autocmplete...
1913
+ cpos=self.GetCurrentPos()
1914
+ self.UpdateUndoHistoryBefore('insert','dummy',cpos,cpos+5,
1915
+ forceNewAction=True)
1916
+ self.undoHistory[self.undoIndex]['allowsAppend'] = True
1917
+ self.TotalLengthForAutoCompActiveCallback=self.GetTextLength()
1918
+ event.Skip()
1919
+ wx.CallAfter(self.AutoCompActiveCallback)
1920
+
1921
+ # Don't toggle between insert mode and overwrite mode.
1922
+ elif key == wx.WXK_INSERT:
1923
+ pass
1924
+
1925
+ # Don't allow line deletion.
1926
+ #elif controlDown and key in (ord('L'), ord('l')):
1927
+ # TODO : Allow line deletion eventually ??
1928
+ #event.Skip()
1929
+ # pass
1930
+
1931
+ # Don't allow line transposition.
1932
+ # Toggle Shell Mode / Slices Mode
1933
+ elif controlDown and key in (ord('T'), ord('t')):
1934
+ self.ToggleShellMode()
1935
+
1936
+ #Open and Save now work when using CrustSlicesFrames
1937
+ elif controlDown and key in (ord('L'), ord('l')):
1938
+ #print('Load it')
1939
+ file = wx.FileSelector("Load File As New Slice")
1940
+ if file != u'':
1941
+ with open(file,'r') as fid:
1942
+ self.LoadPyFileAsSlice(fid)
1943
+
1944
+ elif controlDown and key in (ord('D'), ord('d')):
1945
+ #Disallow line duplication in favor of divide slices
1946
+ if self.MarkerGet(self.GetCurrentLine()) & INPUT_MASK:
1947
+ #ADD UNDO
1948
+ cpos=self.GetCurrentPos()
1949
+ start,end = map(self.PositionFromLine,
1950
+ self.GetGroupingSlice(self.LineFromPosition(cpos)))
1951
+ self.UpdateUndoHistoryBefore('marker','',start,end,
1952
+ forceNewAction=True)
1953
+ self.SplitSlice()
1954
+ # Turn off selecting
1955
+ self.SetSelection(cpos,cpos)
1956
+ self.ReplaceSelection('')
1957
+ self.UpdateUndoHistoryAfter()
1958
+
1959
+ elif controlDown and key in (ord('M'), ord('m')):
1960
+ #ADD UNDO
1961
+ if self.SliceSelection:
1962
+ cpos=self.GetCurrentPos()
1963
+ ioSel=self.GetIOSelection()
1964
+ if self.SliceSelection:
1965
+ start,end = map(self.PositionFromLine,ioSel)
1966
+ self.UpdateUndoHistoryBefore('marker','',start,end,
1967
+ forceNewAction=True)
1968
+ self.MergeAdjacentSlices()
1969
+ # Turn off selecting
1970
+ self.SetSelection(cpos,cpos)
1971
+ self.ReplaceSelection('')
1972
+ self.UpdateUndoHistoryAfter()
1973
+
1974
+
1975
+ # Change arrow keys to allow margin behaviors...
1976
+ elif self.SliceSelection and \
1977
+ key in [wx.WXK_UP,wx.WXK_DOWN,wx.WXK_RIGHT,wx.WXK_LEFT]:
1978
+ # TODO : This is useful, but not optimal!
1979
+ if key==wx.WXK_UP:
1980
+ for i in range(self.GetLineCount()):
1981
+ if self.MarkerGet(i) & 1<<GROUPING_SELECTING:
1982
+ if i>0: #Grouping
1983
+ self.DoMarginClick(i-1, 2, shiftDown, controlDown)
1984
+ break
1985
+ elif self.MarkerGet(i) & 1<<IO_SELECTING:
1986
+ if i>0: #IO
1987
+ self.DoMarginClick(i-1, 3, shiftDown, controlDown)
1988
+ break
1989
+ elif key==wx.WXK_DOWN:
1990
+ for i in range(self.GetLineCount()-1,-1,-1):
1991
+ if self.MarkerGet(i) & 1<<GROUPING_SELECTING:
1992
+ if i<self.GetLineCount()-1: #Grouping
1993
+ self.DoMarginClick(i+1, 2, shiftDown, controlDown)
1994
+ break
1995
+ elif self.MarkerGet(i) & 1<<IO_SELECTING:
1996
+ if i<self.GetLineCount()-1: #IO
1997
+ self.DoMarginClick(i+1, 3, shiftDown, controlDown)
1998
+ break
1999
+ elif key==wx.WXK_RIGHT:
2000
+ for i in range(self.GetLineCount()):
2001
+ if self.MarkerGet(i) & 1<<GROUPING_SELECTING:
2002
+ self.DoMarginClick(i, 3, shiftDown, controlDown)
2003
+ break
2004
+ elif self.MarkerGet(i) & 1<<IO_SELECTING:
2005
+ self.MarginUnselectAll()
2006
+ # Go to the beginning of the IO Slice
2007
+ self.SetCurrentPos(self.PositionFromLine(i))
2008
+ if not selecting and not shiftDown:
2009
+ self.SetAnchor(self.PositionFromLine(i))
2010
+ self.EnsureCaretVisible()
2011
+ break
2012
+ elif key==wx.WXK_LEFT:
2013
+ for i in range(self.GetLineCount()):
2014
+ if self.MarkerGet(i) & 1<<GROUPING_SELECTING:
2015
+ break
2016
+ elif self.MarkerGet(i) & 1<<IO_SELECTING:
2017
+ self.DoMarginClick(i, 2, shiftDown, controlDown)
2018
+ break
2019
+ # Basic navigation keys should work anywhere.
2020
+ elif key in NAVKEYS:
2021
+ event.Skip()
2022
+ # Protect the readonly portion of the slices shell.
2023
+ elif not self.CanEdit():
2024
+ pass
2025
+ else:
2026
+ # Check to see if we're selecting
2027
+ if self.GetSelectionEnd()>self.GetSelectionStart():
2028
+ # Check to see if a normal input took place
2029
+ if not controlDown and not altDown and key<256:
2030
+ self.ReplaceSelection('') # This seems to work...
2031
+ event.Skip()
2032
+
2033
+ if self.SliceSelection:
2034
+ if key not in [wx.WXK_UP,wx.WXK_DOWN,wx.WXK_RIGHT,wx.WXK_LEFT,
2035
+ wx.WXK_ALT,wx.WXK_COMMAND,wx.WXK_CONTROL,wx.WXK_SHIFT]:
2036
+ self.MarginUnselectAll()
2037
+
2038
+
2039
+ def MarginSelectAll(self):
2040
+ num_lines=self.GetLineCount()
2041
+ for i in range(num_lines):
2042
+ self.MarkerAdd(i,GROUPING_SELECTING)
2043
+ self.MarkerDelete(i,IO_SELECTING)
2044
+
2045
+ def MarginUnselectAll(self):
2046
+ num_lines=self.GetLineCount()
2047
+ for i in range(num_lines):
2048
+ self.MarkerDelete(i,IO_SELECTING)
2049
+ self.MarkerDelete(i,GROUPING_SELECTING)
2050
+ self.SliceSelection=False
2051
+
2052
+ def DoMarginClick(self, lineClicked, margin, shiftDown, controlDown):
2053
+ num_lines=self.GetLineCount()
2054
+
2055
+ if margin==1:
2056
+ pass # these events are not sent right now...
2057
+ if margin==2:
2058
+ self.SliceSelection=True
2059
+ start,end=self.GetGroupingSlice(lineClicked)
2060
+ startPos=self.PositionFromLine(start)
2061
+ self.SetCurrentPos(startPos)
2062
+ self.SetSelection(startPos,startPos)
2063
+ start_marker=self.MarkerGet(start)
2064
+ if self.MarkerGet(lineClicked) & 1<<GROUPING_SELECTING:
2065
+ toggle=self.MarkerDelete
2066
+ if not shiftDown:
2067
+ if start_marker & 1<<GROUPING_START:
2068
+ self.FoldGroupingSlice(lineClicked)
2069
+ elif start_marker & 1<<GROUPING_START_FOLDED:
2070
+ self.UnFoldGroupingSlice(lineClicked)
2071
+ else:
2072
+ toggle=self.MarkerAdd
2073
+
2074
+ if not shiftDown:
2075
+ self.MarginUnselectAll()
2076
+
2077
+ for i in range(start,end+1):
2078
+ toggle(i,GROUPING_SELECTING)
2079
+ elif margin==3:
2080
+ self.SliceSelection=True
2081
+ start,end=self.GetIOSlice(lineClicked)
2082
+ startPos=self.PositionFromLine(start)
2083
+ self.SetCurrentPos(startPos)
2084
+ self.SetSelection(startPos,startPos)
2085
+ start_marker=self.MarkerGet(start)
2086
+ if self.MarkerGet(lineClicked) & 1<<IO_SELECTING:
2087
+ toggle=self.MarkerDelete
2088
+ if not shiftDown:
2089
+ if start_marker & IO_START_MASK:
2090
+ self.FoldIOSlice(lineClicked)
2091
+ elif start_marker & IO_START_FOLDED_MASK:
2092
+ self.UnFoldIOSlice(lineClicked)
2093
+ else:
2094
+ toggle=self.MarkerAdd
2095
+
2096
+ if not shiftDown:
2097
+ self.MarginUnselectAll()
2098
+
2099
+ for i in range(start,end+1):
2100
+ toggle(i,IO_SELECTING)
2101
+
2102
+ #print(start, end)
2103
+
2104
+ elif margin==4:
2105
+ # TODO : Folding ??
2106
+ if 1:#self.MarkerGet(lineClicked) & ( 1<<7 | 1<<8 ):
2107
+ if shiftDown:
2108
+ self.SetFoldExpanded(lineClicked, True)
2109
+ self.Expand(lineClicked, True, True, 1)
2110
+ elif controlDown:
2111
+ if self.GetFoldExpanded(lineClicked):
2112
+ self.SetFoldExpanded(lineClicked, False)
2113
+ self.Expand(lineClicked, False, True, 0)
2114
+ else:
2115
+ self.SetFoldExpanded(lineClicked, True)
2116
+ self.Expand(lineClicked, True, True, 100)
2117
+ else:
2118
+ self.ToggleFold(lineClicked)
2119
+ else:
2120
+ self.MarginUnselectAll()
2121
+ if margin in [2,3]:
2122
+ if toggle==self.MarkerDelete and not shiftDown:
2123
+ self.SliceSelection=False
2124
+ else:
2125
+ self.SliceSelection=True
2126
+
2127
+ def OnMarginClick(self, evt):
2128
+
2129
+ # fold and unfold as neededNAVKEYS
2130
+ lineClicked = self.LineFromPosition(evt.GetPosition())
2131
+ self.DoMarginClick(lineClicked,evt.GetMargin(),evt.GetShift(),evt.GetControl())
2132
+ evt.Skip()
2133
+
2134
+ def OnShowCompHistory(self):
2135
+ """Show possible autocompletion Words from already typed words."""
2136
+
2137
+ #copy from history
2138
+ his = self.history[:]
2139
+
2140
+ #put together in one string
2141
+ joined = " ".join (his)
2142
+ import re
2143
+
2144
+ #sort out only "good" words
2145
+ newlist = re.split("[ \.\[\]=}(\)\,0-9\"]", joined)
2146
+
2147
+ #length > 1 (mix out "trash")
2148
+ thlist = []
2149
+ for i in newlist:
2150
+ if len (i) > 1:
2151
+ thlist.append (i)
2152
+
2153
+ #unique (no duplicate words
2154
+ #oneliner from german python forum => unique list
2155
+ unlist = [thlist[i] for i in xrange(len(thlist)) if thlist[i] not in thlist[:i]]
2156
+
2157
+ #sort lowercase
2158
+ unlist.sort(key=cmp_to_key(lambda a, b: cmp(a.lower(), b.lower())))
2159
+
2160
+ #this is more convenient, isn't it?
2161
+ self.AutoCompSetIgnoreCase(True)
2162
+
2163
+ #join again together in a string
2164
+ stringlist = " ".join(unlist)
2165
+
2166
+ #pos von 0 noch ausrechnen
2167
+
2168
+ #how big is the offset?
2169
+ cpos = self.GetCurrentPos() - 1
2170
+ while chr (self.GetCharAt (cpos)).isalnum():
2171
+ cpos -= 1
2172
+
2173
+ #the most important part
2174
+ self.AutoCompShow(self.GetCurrentPos() - cpos -1, stringlist)
2175
+
2176
+ def ReplaceSelection(self,text,sliceDeletion=False,*args,**kwds):
2177
+ startIO,endIO=self.GetIOSlice()
2178
+ startGrouping,endGrouping=self.GetGroupingSlice()
2179
+ startSel = self.LineFromPosition(self.GetSelectionStart())
2180
+ endSel = self.LineFromPosition(self.GetSelectionEnd())
2181
+
2182
+ #ADD UNDO
2183
+ cpos=self.GetSelectionStart()
2184
+ s=self.GetSelectedText()
2185
+ if s!='':
2186
+ self.UpdateUndoHistoryBefore('delete',s,cpos,cpos+len(s),
2187
+ forceNewAction=True)
2188
+ editwindow.EditWindow.ReplaceSelection(self,'',*args,**kwds)
2189
+ if s!='' and not sliceDeletion:
2190
+ self.UpdateUndoHistoryAfter()
2191
+
2192
+ if endSel-startSel>0 and not sliceDeletion:
2193
+ if endSel==endIO and startIO!=self.GetCurrentLine():
2194
+ self.clearIOMarkers()
2195
+ self.MarkerAdd(self.GetCurrentLine(),INPUT_END)
2196
+
2197
+ if endSel==endGrouping and startGrouping!=self.GetCurrentLine():
2198
+ self.clearGroupingMarkers()
2199
+ self.MarkerAdd(self.GetCurrentLine(),GROUPING_END)
2200
+
2201
+ cpos=self.GetSelectionStart()
2202
+ s=text
2203
+ if s!='':
2204
+ self.UpdateUndoHistoryBefore('insert',s,cpos,cpos+len(s),
2205
+ forceNewAction=True)
2206
+ self.write(text)
2207
+ self.UpdateUndoHistoryAfter()
2208
+
2209
+ self.ensureSingleGroupingMarker()
2210
+ self.ensureSingleIOMarker()
2211
+
2212
+
2213
+ def clearCommand(self):
2214
+ """Delete the current, unexecuted command."""
2215
+ if not self.CanEdit():
2216
+ return
2217
+ start,end=self.GetIOSlice()
2218
+ startpos = self.PositionFromLine(start)
2219
+ endpos = self.GetLineEndPosition(end)
2220
+ self.SetSelection(startpos, endpos)
2221
+ self.ReplaceSelection('')
2222
+ self.more = False
2223
+
2224
+ def OnHistoryReplace(self, step):
2225
+ """Replace with the previous/next command from the history buffer."""
2226
+ if not self.CanEdit():
2227
+ return
2228
+ self.clearCommand()
2229
+ self.replaceFromHistory(step)
2230
+
2231
+ def replaceFromHistory(self, step):
2232
+ """Replace selection with command from the history buffer."""
2233
+ if not self.CanEdit():
2234
+ return
2235
+ self.ReplaceSelection('')
2236
+ newindex = self.historyIndex + step
2237
+ if -1 <= newindex <= len(self.history):
2238
+ self.historyIndex = newindex
2239
+ if 0 <= newindex <= len(self.history)-1:
2240
+ command = self.history[self.historyIndex]
2241
+ command = command.replace('\n', os.linesep)# + ps2)
2242
+ self.ReplaceSelection(command)
2243
+
2244
+ def OnHistoryInsert(self, step):
2245
+ """Insert the previous/next command from the history buffer."""
2246
+ if not self.CanEdit():
2247
+ return
2248
+ startpos = self.GetCurrentPos()
2249
+ self.replaceFromHistory(step)
2250
+ endpos = self.GetCurrentPos()
2251
+ self.SetSelection(endpos, startpos)
2252
+
2253
+ # TODO: Fix Me!
2254
+ def OnHistorySearch(self):
2255
+ """Search up the history buffer for the text in front of the cursor."""
2256
+ if not self.CanEdit():
2257
+ return
2258
+ startpos = self.GetCurrentPos()
2259
+ # The text up to the cursor is what we search for.
2260
+ numCharsAfterCursor = self.GetTextLength() - startpos
2261
+ searchText = self.getCommand(rstrip=False)
2262
+ #print('history search', startpos, numCharsAfterCursor, searchText)
2263
+ if numCharsAfterCursor > 0:
2264
+ searchText = searchText[:-numCharsAfterCursor]
2265
+ if not searchText:
2266
+ return
2267
+ # Search upwards from the current history position and loop
2268
+ # back to the beginning if we don't find anything.
2269
+ if (self.historyIndex <= -1) \
2270
+ or (self.historyIndex >= len(self.history)-2):
2271
+ searchOrder = range(len(self.history))
2272
+ else:
2273
+ searchOrder = range(self.historyIndex+1, len(self.history)) + \
2274
+ range(self.historyIndex)
2275
+ for i in searchOrder:
2276
+ command = self.history[i]
2277
+ if command[:len(searchText)] == searchText:
2278
+ # Replace the current selection with the one we found.
2279
+ self.ReplaceSelection(command[len(searchText):])
2280
+ endpos = self.GetCurrentPos()
2281
+ self.SetSelection(endpos, startpos)
2282
+ # We've now warped into middle of the history.
2283
+ self.historyIndex = i
2284
+ break
2285
+
2286
+ def setStatusText(self, text):
2287
+ """Display status information."""
2288
+
2289
+ # This method will likely be replaced by the enclosing app to
2290
+ # do something more interesting, like write to a status bar.
2291
+ print(text)
2292
+
2293
+ def insertLineBreak(self):
2294
+ """Insert a new line break."""
2295
+ if not self.CanEdit():
2296
+ return
2297
+ elif self.reader.isreading:
2298
+ self.processLine()
2299
+ return
2300
+
2301
+
2302
+ # write with undo wrapper...
2303
+ cpos=self.GetCurrentPos()
2304
+ s=os.linesep
2305
+ self.UpdateUndoHistoryBefore('insert',s,cpos,cpos+1)
2306
+ self.write(s,type='Input')
2307
+ self.UpdateUndoHistoryAfter()
2308
+
2309
+ self.more = True
2310
+ self.prompt()
2311
+
2312
+ def processLine(self):
2313
+ """Process the line of text at which the user hit Enter or Shift+RETURN."""
2314
+ # The user hit ENTER (Shift+RETURN) (Shift+ENTER) and we need to
2315
+ # decide what to do. They could be sitting on any line in the slices shell.
2316
+ thepos = self.GetCurrentPos()
2317
+ cur_line = self.GetCurrentLine()
2318
+ marker=self.MarkerGet(cur_line)
2319
+ if marker & INPUT_MASK:
2320
+ pass
2321
+ elif marker & OUTPUT_MASK:
2322
+ return
2323
+ else:
2324
+ pass #print('BLANK LINE!!')
2325
+
2326
+ startline,endline=self.GetIOSlice(cur_line)
2327
+
2328
+ if startline==0:
2329
+ startpos=0
2330
+ else:
2331
+ startpos=self.PositionFromLine(startline)
2332
+
2333
+ endpos=self.GetLineEndPosition(endline)
2334
+
2335
+ # If they hit ENTER inside the current command, execute the command.
2336
+ if self.CanEdit():
2337
+ self.SetCurrentPos(endpos)
2338
+ self.interp.more = False
2339
+ command = self.GetTextRange(startpos, endpos)
2340
+ lines = command.split(os.linesep)
2341
+ lines = [line.rstrip() for line in lines]
2342
+ command = '\n'.join(lines)
2343
+ if self.reader.isreading:
2344
+ if not command:
2345
+ # Match the behavior of the standard Python shell
2346
+ # when the user hits return without entering a value.
2347
+ command = '\n'
2348
+ self.reader.input = command
2349
+ self.write(os.linesep,'Input')
2350
+ self.MarkerSet(self.GetCurrentLine(),READLINE_BG)
2351
+ self.MarkerSet(self.GetCurrentLine(),INPUT_READLINE)
2352
+ else:
2353
+ self.runningSlice = (startline,endline)
2354
+ self.push(command,useMultiCommand=True)
2355
+ #print('command: %s'%command)
2356
+ wx.CallLater(1, self.EnsureCaretVisible)
2357
+ self.runningSlice=None
2358
+
2359
+ skip=self.BackspaceWMarkers(force=True)
2360
+ if skip:
2361
+ self.DeleteBack()
2362
+
2363
+ if self.GetCurrentLine()==self.GetLineCount()-1:
2364
+ self.write(os.linesep,type='Input')
2365
+ cpos=self.GetCurrentLine()
2366
+ if self.MarkerGet(cpos-1) & OUTPUT_MASK:
2367
+ self.MarkerAdd(cpos-1,OUTPUT_BG)
2368
+ self.SplitSlice()
2369
+ else:
2370
+ cur_line=self.GetCurrentLine()
2371
+ new_pos=self.GetLineEndPosition(cur_line+1)
2372
+ self.SetSelection(new_pos,new_pos)
2373
+ self.SetCurrentPos(new_pos)
2374
+
2375
+ self.EmptyUndoBuffer()
2376
+ self.NeedsCheckForSave=True
2377
+ if self.hasSyntaxError:
2378
+ pos=self.GetLineEndPosition(self.syntaxErrorRealLine)
2379
+ self.SetCurrentPos(pos)
2380
+ self.SetSelection(pos,pos)
2381
+
2382
+ # Not Used!!
2383
+ def getMultilineCommand(self, rstrip=True):
2384
+ """Extract a multi-line command from the editor.
2385
+
2386
+ The command may not necessarily be valid Python syntax."""
2387
+ # DNM
2388
+ # XXX Need to extract real prompts here. Need to keep track of
2389
+ # the prompt every time a command is issued.
2390
+ text = self.GetCurLine()[0]
2391
+ line = self.GetCurrentLine()
2392
+ # Add Marker testing here...
2393
+ while text == '' and line > 0: # Need to add markers handling...
2394
+ line -= 1
2395
+ self.GotoLine(line)
2396
+ text = self.GetCurLine()[0]
2397
+ if text=='':
2398
+ line = self.GetCurrentLine()
2399
+ self.GotoLine(line)
2400
+ startpos = self.GetCurrentPos()
2401
+ line += 1
2402
+ self.GotoLine(line)
2403
+ while self.GetCurLine()[0]=='':
2404
+ line += 1
2405
+ self.GotoLine(line)
2406
+ stoppos = self.GetCurrentPos()
2407
+ command = self.GetTextRange(startpos, stoppos)
2408
+ command = command.replace(os.linesep, '\n')
2409
+ command = command.rstrip()
2410
+ command = command.replace('\n', os.linesep)
2411
+ else:
2412
+ command = ''
2413
+ if rstrip:
2414
+ command = command.rstrip()
2415
+ return command
2416
+
2417
+ def getCommand(self, text=None, rstrip=True):
2418
+ """Extract a command from text which may include a shell prompt.
2419
+
2420
+ The command may not necessarily be valid Python syntax."""
2421
+ if not text:
2422
+ text = self.GetCurLine()[0]
2423
+ # Strip the prompt off the front leaving just the command.
2424
+ command = self.lstripPrompt(text)
2425
+ # Change this -- Nothing has prompts!
2426
+ #if command == text:
2427
+ # command = '' # Real commands have prompts.
2428
+ if rstrip:
2429
+ command = command.rstrip()
2430
+ return command
2431
+
2432
+ def lstripPrompt(self, text):
2433
+ """Return text without a leading prompt."""
2434
+ ps1 = str(sys.ps1)
2435
+ ps1size = len(ps1)
2436
+ ps2 = str(sys.ps2)
2437
+ ps2size = len(ps2)
2438
+ # Strip the prompt off the front of text.
2439
+ if text[:ps1size] == ps1:
2440
+ text = text[ps1size:]
2441
+ elif text[:ps2size] == ps2:
2442
+ text = text[ps2size:]
2443
+ return text
2444
+
2445
+ def push(self, command, silent = False,useMultiCommand=False):
2446
+ """Send command to the interpreter for execution."""
2447
+ if not silent:
2448
+ self.write(os.linesep,type='Output')
2449
+ # TODO : What other magic might we insert here?
2450
+ # TODO : Is there a good reason not to include magic?
2451
+ if USE_MAGIC:
2452
+ command=magic(command)
2453
+
2454
+ # Allows multi-component commands...
2455
+ self.hasSyntaxError=False
2456
+ if useMultiCommand:
2457
+ result = self.BreakTextIntoCommands(command)
2458
+ if result[0] is None:
2459
+ commands=[command]
2460
+ self.hasSyntaxError=True
2461
+ syntaxErrorLine=result[1]+1
2462
+ self.syntaxErrorRealLine = self.GetCurrentLine()+result[1]-len(command.split('\n'))
2463
+ else:
2464
+ commands=result
2465
+ else:
2466
+ commands=[command]
2467
+
2468
+ busy = wx.BusyCursor()
2469
+ self.waiting = True
2470
+ self.lastUpdate=None
2471
+
2472
+ for i in commands:
2473
+ if self.hasSyntaxError:
2474
+ lineno=syntaxErrorLine
2475
+ offset=0 # not sure how to easily recover this information...
2476
+ self.write(' File "<input>", line '+str(lineno)+'\n '+i.split('\n')[lineno-1]+'\n'+' '*offset+' ^\nSyntaxError: invalid syntax\n','Error')
2477
+ else:
2478
+ self.more = self.interp.push(i+'\n')
2479
+ # (the \n stops many things from bouncing at the interpreter)
2480
+ # I could do the following, but I don't really like it!
2481
+ #if useMultiCommand:
2482
+ # self.SplitSlice()
2483
+ self.lastUpdate=None
2484
+
2485
+ if not silent:
2486
+ self.MarkerAdd(self.GetIOSlice()[0],OUTPUT_BG)
2487
+
2488
+ self.waiting = False
2489
+ del busy
2490
+ if not self.more: # could loop-add to history, too, but I don't like it!
2491
+ self.addHistory(command.rstrip())
2492
+
2493
+ if not silent:
2494
+ self.prompt()
2495
+
2496
+ def addHistory(self, command):
2497
+ """Add command to the command history."""
2498
+ # Reset the history position.
2499
+ self.historyIndex = -1
2500
+ # Insert this command into the history, unless it's a blank
2501
+ # line or the same as the last command.
2502
+ if command!='' and ( len(self.history)==0 or command!=self.history[0] ):
2503
+ self.history.insert(0, command)
2504
+ dispatcher.send(signal="SlicesShell.addHistory", command=command)
2505
+
2506
+ def clearGroupingMarkers(self,line_num=None):
2507
+ if line_num==None:
2508
+ line_num=self.GetCurrentLine()
2509
+ self.MarkerDelete(line_num,GROUPING_START)
2510
+ self.MarkerDelete(line_num,GROUPING_START_FOLDED)
2511
+ self.MarkerDelete(line_num,GROUPING_MIDDLE)
2512
+ self.MarkerDelete(line_num,GROUPING_END)
2513
+ def clearIOMarkers(self,line_num=None):
2514
+ if line_num==None:
2515
+ line_num=self.GetCurrentLine()
2516
+ self.MarkerDelete(line_num,INPUT_START)
2517
+ self.MarkerDelete(line_num,INPUT_START_FOLDED)
2518
+ self.MarkerDelete(line_num,INPUT_MIDDLE)
2519
+ self.MarkerDelete(line_num,INPUT_END)
2520
+ self.MarkerDelete(line_num,OUTPUT_START)
2521
+ self.MarkerDelete(line_num,OUTPUT_START_FOLDED)
2522
+ self.MarkerDelete(line_num,OUTPUT_MIDDLE)
2523
+ self.MarkerDelete(line_num,OUTPUT_END)
2524
+ self.MarkerDelete(line_num,OUTPUT_BG)
2525
+ self.MarkerDelete(line_num,READLINE_BG)
2526
+ self.MarkerDelete(line_num,INPUT_READLINE)
2527
+ def ensureSingleGroupingMarker(self,line_num=None):
2528
+ if line_num==None:
2529
+ line_num=self.GetCurrentLine()
2530
+ marker=self.MarkerGet(line_num)
2531
+ if marker & 1<<GROUPING_START:
2532
+ self.MarkerDelete(line_num,GROUPING_START_FOLDED)
2533
+ self.MarkerDelete(line_num,GROUPING_MIDDLE)
2534
+ self.MarkerDelete(line_num,GROUPING_END)
2535
+ elif marker & 1<<GROUPING_START_FOLDED:
2536
+ self.MarkerDelete(line_num,GROUPING_MIDDLE)
2537
+ self.MarkerDelete(line_num,GROUPING_END)
2538
+ elif marker & 1<<GROUPING_MIDDLE:
2539
+ self.MarkerDelete(line_num,GROUPING_END)
2540
+ elif marker & 1<<GROUPING_END:
2541
+ pass
2542
+ else:
2543
+ #print('ERROR! NO GROUPING MARKERS!')
2544
+ return 1 # Blank marker
2545
+
2546
+ return 0
2547
+
2548
+ def ensureSingleIOMarker(self,line_num=None):
2549
+ if line_num==None:
2550
+ line_num=self.GetCurrentLine()
2551
+ marker=self.MarkerGet(line_num)
2552
+ if marker & INPUT_MASK:
2553
+ self.MarkerDelete(line_num,OUTPUT_START)
2554
+ self.MarkerDelete(line_num,OUTPUT_START_FOLDED)
2555
+ self.MarkerDelete(line_num,OUTPUT_MIDDLE)
2556
+ self.MarkerDelete(line_num,OUTPUT_END)
2557
+ self.MarkerDelete(line_num,OUTPUT_BG)
2558
+ [start,start_folded] = [INPUT_START,INPUT_START_FOLDED]
2559
+ [middle,end] = [INPUT_MIDDLE,INPUT_END]
2560
+ elif marker & OUTPUT_MASK:
2561
+ self.MarkerDelete(line_num,INPUT_START)
2562
+ self.MarkerDelete(line_num,INPUT_START_FOLDED)
2563
+ self.MarkerDelete(line_num,INPUT_MIDDLE)
2564
+ self.MarkerDelete(line_num,INPUT_END)
2565
+ [start,start_folded] = [OUTPUT_START,OUTPUT_START_FOLDED]
2566
+ [middle,end] = [OUTPUT_MIDDLE,OUTPUT_END]
2567
+ else:
2568
+ #print('ERROR! NO IO MARKERS!')
2569
+ return 1 # Blank marker
2570
+
2571
+ if marker & 1<<start:
2572
+ self.MarkerDelete(line_num,start_folded)
2573
+ self.MarkerDelete(line_num,middle)
2574
+ self.MarkerDelete(line_num,end)
2575
+ elif marker & 1<<start_folded:
2576
+ self.MarkerDelete(line_num,middle)
2577
+ self.MarkerDelete(line_num,end)
2578
+ elif marker & 1<<middle:
2579
+ self.MarkerDelete(line_num,end)
2580
+ elif marker & 1<<end:
2581
+ pass
2582
+
2583
+ return 0
2584
+
2585
+ def RestoreFirstMarker(self):
2586
+ first_marker=self.MarkerGet(0)
2587
+ self.clearGroupingMarkers(0)
2588
+ self.clearIOMarkers(0)
2589
+
2590
+ if first_marker & 1<<GROUPING_START :
2591
+ self.MarkerAdd(0,GROUPING_START)
2592
+ elif first_marker & 1<<GROUPING_START_FOLDED :
2593
+ self.MarkerAdd(0,GROUPING_START_FOLDED)
2594
+ else:
2595
+ self.MarkerAdd(0,GROUPING_START)
2596
+
2597
+ if first_marker & 1<<INPUT_START :
2598
+ self.MarkerAdd(0,INPUT_START)
2599
+ elif first_marker & 1<<INPUT_START_FOLDED :
2600
+ self.MarkerAdd(0,INPUT_START_FOLDED)
2601
+ elif first_marker & 1<<OUTPUT_START :
2602
+ self.MarkerAdd(0,OUTPUT_START)
2603
+ #self.MarkerAdd(0,OUTPUT_BG) # More harm than good??
2604
+ elif first_marker & 1<<OUTPUT_START_FOLDED :
2605
+ self.MarkerAdd(0,OUTPUT_START_FOLDED)
2606
+ #self.MarkerAdd(0,OUTPUT_BG) # More harm than good??
2607
+ else:
2608
+ self.MarkerAdd(0,INPUT_START)
2609
+
2610
+ if self.doHistUpdate:
2611
+ self.UpdateUndoHistoryAfter()
2612
+
2613
+ def IsAllowedPair(self,m1,m2):
2614
+ """This testing function ensures that two adjacent markers are valid"""
2615
+ i_s = 1<<INPUT_START | 1<<INPUT_START_FOLDED
2616
+ o_s = 1<<OUTPUT_START | 1<<OUTPUT_START_FOLDED
2617
+ g_s = 1<<GROUPING_START | 1<<GROUPING_START_FOLDED
2618
+ i_m,o_m,g_m = 1<<INPUT_MIDDLE, 1<<OUTPUT_MIDDLE, 1<<GROUPING_MIDDLE
2619
+ i_e,o_e,g_e = 1<<INPUT_END, 1<<OUTPUT_END, 1<<GROUPING_END
2620
+
2621
+ if (m1 & i_s) and (m1 & g_s): #1
2622
+ if (m2 & i_s) and (m2 & g_s): return True #1
2623
+ elif (m2 & i_m) and (m2 & g_m): return True #2
2624
+ elif (m2 & i_e) and (m2 & g_m): return True #3
2625
+ elif (m2 & i_e) and (m2 & g_e): return True #4
2626
+ elif (m2 & o_s) and (m2 & g_s): return False #5
2627
+ elif (m2 & o_s) and (m2 & g_m): return True #6
2628
+ elif (m2 & o_s) and (m2 & g_e): return True #7
2629
+ elif (m2 & o_m) and (m2 & g_m): return False #8
2630
+ elif (m2 & o_e) and (m2 & g_e): return False #9
2631
+ else: return False
2632
+ elif (m1 & i_m) and (m1 & g_m): #2
2633
+ if (m2 & i_m) and (m2 & g_m): return True #2
2634
+ elif (m2 & i_e) and (m2 & g_m): return True #3
2635
+ elif (m2 & i_e) and (m2 & g_e): return True #4
2636
+ else: return False
2637
+ elif (m1 & i_e) and (m1 & g_m): #3
2638
+ if (m2 & o_s) and (m2 & g_m): return True #6
2639
+ elif (m2 & o_s) and (m2 & g_e): return True #7
2640
+ else: return False
2641
+ elif (m1 & i_e) and (m1 & g_e): #4
2642
+ if (m2 & i_s) and (m2 & g_s): return True #1
2643
+ elif (m2 & o_s) and (m2 & g_s): return True #5
2644
+ else: return False
2645
+ elif (m1 & o_s) and (m1 & g_s): #5
2646
+ if (m2 & i_s) and (m2 & g_s): return True #1
2647
+ elif (m2 & i_m) and (m2 & g_m): return False #2
2648
+ elif (m2 & i_e) and (m2 & g_m): return False #3
2649
+ elif (m2 & i_e) and (m2 & g_e): return False #4
2650
+ elif (m2 & o_s) and (m2 & g_s): return True #5
2651
+ elif (m2 & o_s) and (m2 & g_m): return False #6
2652
+ elif (m2 & o_s) and (m2 & g_e): return False #7
2653
+ elif (m2 & o_m) and (m2 & g_m): return True #8
2654
+ elif (m2 & o_e) and (m2 & g_e): return True #9
2655
+ else: return False
2656
+ elif (m1 & o_s) and (m1 & g_m): #6
2657
+ if (m2 & o_m) and (m2 & g_m): return True #8
2658
+ elif (m2 & o_e) and (m2 & g_e): return True #9
2659
+ else: return False
2660
+ elif (m1 & o_s) and (m1 & g_e): #7
2661
+ if (m2 & i_s) and (m2 & g_s): return True #1
2662
+ elif (m2 & o_s) and (m2 & g_s): return True #5
2663
+ else: return False
2664
+ elif (m1 & o_m) and (m1 & g_m): #8
2665
+ if (m2 & o_m) and (m2 & g_m): return True #8
2666
+ elif (m2 & o_e) and (m2 & g_e): return True #9
2667
+ else: return False
2668
+ elif (m1 & o_e) and (m1 & g_e): #9
2669
+ if (m2 & i_s) and (m2 & g_s): return True #1
2670
+ elif (m2 & o_s) and (m2 & g_s): return True #5
2671
+ else: return False
2672
+ else:
2673
+ return False
2674
+
2675
+
2676
+ def CleanAllMarkers(self):
2677
+ self.RestoreFirstMarker()
2678
+ first_marker=self.MarkerGet(0)
2679
+ last_line_num=self.GetLineCount()-1
2680
+
2681
+ for i in range(1,last_line_num):
2682
+ self.ensureSingleGroupingMarker(i)
2683
+ self.ensureSingleIOMarker(i)
2684
+
2685
+ previous_marker=self.MarkerGet(i-1)
2686
+ marker=self.MarkerGet(i)
2687
+
2688
+ if not self.IsAllowedPair(previous_marker,marker):
2689
+ pass # FIX MARKER!!
2690
+ # FIX ME
2691
+
2692
+ def write(self, text,type='Input',silent=False):
2693
+ """Display text in the slices shell.
2694
+
2695
+ Replace line endings with OS-specific endings."""
2696
+ text = self.fixLineEndings(text)
2697
+ split=text.split(os.linesep)
2698
+ self.AddText(text)
2699
+
2700
+ # This part handles all the marker stuff that accompanies
2701
+ # adding or removing new lines of text...
2702
+ # Get the total number of lines in the Document == last line number
2703
+ last_line_num=self.GetLineCount()-1
2704
+ # Get the line number we ended on in the write
2705
+ end_line_num=self.GetCurrentLine()
2706
+ # Get the number of returns we are using == number of lines we pasted -1
2707
+ num_new_lines=text.count(os.linesep)
2708
+ # So if num_new_lines==0, start_line_num and end_line_num are the same
2709
+ start_line_num=end_line_num-num_new_lines+1
2710
+
2711
+ # This is a little unnecessary because there will always
2712
+ # be a line before if we just inserted a newline!
2713
+ if start_line_num == 0:
2714
+ previous_line_num=None
2715
+ else:
2716
+ previous_line_num=start_line_num-1
2717
+
2718
+ #However, this is very important...
2719
+ if end_line_num == last_line_num:
2720
+ next_line_num=None
2721
+ else:
2722
+ next_line_num=end_line_num+1
2723
+
2724
+ if type=='Input':
2725
+ start = INPUT_START
2726
+ start_folded = INPUT_START_FOLDED
2727
+ middle = INPUT_MIDDLE
2728
+ end = INPUT_END
2729
+ # preparation for more io types...
2730
+ opposite_start_mask = 1<<OUTPUT_START
2731
+ opposite_start_folded_mask = 1<<OUTPUT_START_FOLDED
2732
+ opposite_middle_mask = 1<<OUTPUT_MIDDLE # To test for bad writes...
2733
+ opposite_end_mask = 1<<OUTPUT_END # To test for bad writes...
2734
+ elif type in ['Output','Error']:
2735
+ #self.MarkerAdd(start_line_num,GROUPING_START_FOLDED)
2736
+ start=OUTPUT_START
2737
+ start_folded=OUTPUT_START_FOLDED
2738
+ middle=OUTPUT_MIDDLE
2739
+ end=OUTPUT_END
2740
+ # preparation for more io types...
2741
+ opposite_start_mask = 1<<INPUT_START
2742
+ opposite_start_folded_mask = 1<<INPUT_START_FOLDED
2743
+ opposite_middle_mask = 1<<INPUT_MIDDLE # To test for bad writes...
2744
+ opposite_end_mask = 1<<INPUT_END # To test for bad writes...
2745
+
2746
+ if num_new_lines>0: #Do nothing if typing within a line...
2747
+ # Update the Grouping Markers
2748
+ # For the previous line and the start_line
2749
+ # Test to make sure we can write ... but not here ...
2750
+ # test this before we call write or before we add text...
2751
+ # So we assume it already obeys the rules
2752
+
2753
+ badMarkers=False
2754
+ fixIOEnd=True
2755
+
2756
+ if previous_line_num==None:
2757
+ # This is an impossible case, here just for completeness...
2758
+ self.clearGroupingMarkers(start_line_num)
2759
+ self.MarkerAdd(start_line_num,GROUPING_START)
2760
+
2761
+ self.clearIOMarkers(start_line_num)
2762
+ self.MarkerAdd(start_line_num,start)
2763
+ if type in ['Output','Error']: self.MarkerAdd(start_line_num,OUTPUT_BG)
2764
+ else:
2765
+ previous_marker=self.MarkerGet(previous_line_num)
2766
+ if previous_marker & opposite_middle_mask:
2767
+ badMarkers=True
2768
+
2769
+ if next_line_num==None:
2770
+ self.MarkerAdd(end_line_num,GROUPING_END)
2771
+ self.MarkerAdd(end_line_num,end)
2772
+ if type in ['Output','Error']: self.MarkerAdd(end_line_num,OUTPUT_BG)
2773
+ fixEndMarkers=False
2774
+ # May be overwritten below if start_line_num==end_line_num...
2775
+ else:
2776
+ next_marker=self.MarkerGet(next_line_num)
2777
+ fixEndMarkers=True
2778
+ if next_marker & ( opposite_middle_mask | opposite_end_mask ):
2779
+ badMarkers=True
2780
+
2781
+ if not badMarkers:
2782
+ # ensure previous_line only has one marker & turn end into middle
2783
+ if previous_line_num!=None:
2784
+ # Adjust previous line appropriately, ensure only one marker
2785
+ # Only print errors if we are on input!
2786
+ blank=False
2787
+ blank=blank or self.ensureSingleGroupingMarker(previous_line_num)
2788
+ blank=blank or self.ensureSingleIOMarker(previous_line_num)
2789
+
2790
+ if blank:
2791
+ #if type=='Input' and not silent: print('BLANK LINE!' # BAD CASE)
2792
+ pass
2793
+
2794
+ if previous_marker & 1<<GROUPING_END :
2795
+ # Make GROUPING slice continue unless we hit
2796
+ # an output end and are starting a new input...
2797
+ if (previous_marker & OUTPUT_MASK) and type=='Input':
2798
+ pass
2799
+ else:
2800
+ self.MarkerDelete(previous_line_num,GROUPING_END)
2801
+ # ONLY CHANGING CASE
2802
+ self.MarkerAdd(previous_line_num,GROUPING_MIDDLE)
2803
+
2804
+ if previous_marker & 1<<end :
2805
+ self.MarkerDelete(previous_line_num,end)
2806
+ self.MarkerAdd(previous_line_num,middle) # ONLY CHANGING CASE
2807
+ if type in ['Output','Error']: self.MarkerAdd(previous_line_num,OUTPUT_BG)
2808
+ elif previous_marker & opposite_middle_mask :
2809
+ # BAD CASE
2810
+ if type=='Input' and not silent:
2811
+ #print('Should have been a bad marker!')
2812
+ pass
2813
+
2814
+ # We can only add input to an input slice
2815
+ # And can only add output to an output slice
2816
+
2817
+ if previous_marker & ( opposite_start_mask |
2818
+ opposite_start_folded_mask |
2819
+ opposite_end_mask ):
2820
+ if type=='Input':
2821
+ self.clearGroupingMarkers(start_line_num)
2822
+ self.MarkerAdd(start_line_num,GROUPING_START)
2823
+ if start_line_num==end_line_num:
2824
+ fixEndMarkers=False
2825
+ else:
2826
+ if start_line_num==end_line_num:
2827
+ fixIOEnd=False
2828
+ self.clearIOMarkers(start_line_num)
2829
+ self.MarkerAdd(start_line_num,start)
2830
+ if type in ['Output','Error']: self.MarkerAdd(start_line_num,OUTPUT_BG)
2831
+ else:
2832
+ if next_line_num!=None:
2833
+ self.clearGroupingMarkers(start_line_num)
2834
+ self.clearIOMarkers(start_line_num)
2835
+ self.MarkerAdd(start_line_num,GROUPING_MIDDLE)
2836
+ self.MarkerAdd(start_line_num,middle)
2837
+ if type in ['Output','Error']: self.MarkerAdd(start_line_num,OUTPUT_BG)
2838
+ # This may be overwritten if start_line_num==end_line_num
2839
+
2840
+ # Take care of all the middle lines...
2841
+ # Does nothing for only one line...
2842
+ for i in range(start_line_num,end_line_num):
2843
+ self.clearGroupingMarkers(i)
2844
+ self.MarkerAdd(i,GROUPING_MIDDLE)
2845
+
2846
+ self.clearIOMarkers(i)
2847
+ self.MarkerAdd(i,middle)
2848
+ if type in ['Output','Error']: self.MarkerAdd(i,OUTPUT_BG)
2849
+
2850
+ if fixEndMarkers:
2851
+ # Take care of the end_line if we haven't already done so...
2852
+ blank=False
2853
+ blank=blank or self.ensureSingleGroupingMarker(next_line_num)
2854
+ blank=blank or self.ensureSingleIOMarker(next_line_num)
2855
+
2856
+ if blank:
2857
+ if type=='Input' and not silent:
2858
+ #print('BLANK LINE!' # BAD CASE)
2859
+ pass
2860
+
2861
+ self.clearGroupingMarkers(end_line_num)
2862
+ if fixIOEnd:
2863
+ self.clearIOMarkers(end_line_num)
2864
+
2865
+ if next_marker & ( 1<<GROUPING_START | 1<<GROUPING_START_FOLDED ) :
2866
+ self.MarkerAdd(end_line_num,GROUPING_END)
2867
+ elif next_marker & ( 1<<GROUPING_MIDDLE | 1<<GROUPING_END ) :
2868
+ self.MarkerAdd(end_line_num,GROUPING_MIDDLE)
2869
+
2870
+ if fixIOEnd:
2871
+ if next_marker & ( 1<<start | 1<<start_folded ) :
2872
+ self.MarkerAdd(end_line_num,end)
2873
+ if type in ['Output','Error']: self.MarkerAdd(end_line_num,OUTPUT_BG)
2874
+ elif next_marker & ( 1<<middle | 1<<end ) :
2875
+ self.MarkerAdd(end_line_num,middle)
2876
+ if type in ['Output','Error']: self.MarkerAdd(end_line_num,OUTPUT_BG)
2877
+ elif next_marker & ( opposite_start_mask |
2878
+ opposite_start_folded_mask ):
2879
+ self.MarkerAdd(end_line_num,end)
2880
+ if type in ['Output','Error']: self.MarkerAdd(end_line_num,OUTPUT_BG)
2881
+ else:
2882
+ self.MarkerAdd(end_line_num,start_folded)
2883
+ if type in ['Output','Error']: self.MarkerAdd(end_line_num,OUTPUT_BG)
2884
+ if type=='Input' and not silent:
2885
+ #print('BAD MARKERS!')
2886
+ pass
2887
+ else:
2888
+ if type=='Input' and not silent:
2889
+ #print('BAD MARKERS!!!')
2890
+ pass
2891
+
2892
+ self.EnsureCaretVisible()
2893
+
2894
+ if self.waiting:
2895
+ if self.lastUpdate==None:
2896
+ self.lastUpdate=time.time()
2897
+ if time.time()-self.lastUpdate > PRINT_UPDATE_MAX_TIME:
2898
+ self.Update()
2899
+ self.lastUpdate=time.time()
2900
+
2901
+ def fixLineEndings(self, text):
2902
+ """Return text with line endings replaced by OS-specific endings."""
2903
+ lines = text.split('\r\n')
2904
+ for l in range(len(lines)):
2905
+ chunks = lines[l].split('\r')
2906
+ for c in range(len(chunks)):
2907
+ chunks[c] = os.linesep.join(chunks[c].split('\n'))
2908
+ lines[l] = os.linesep.join(chunks)
2909
+ text = os.linesep.join(lines)
2910
+ return text
2911
+
2912
+ def prompt(self): # Autoindent added!!!
2913
+ """Display proper prompt for the context: ps1, ps2 or ps3.
2914
+
2915
+ If this is a continuation line, autoindent as necessary."""
2916
+ # TODO : How much of this can I do away with now without prompts??
2917
+
2918
+ isreading = self.reader.isreading
2919
+
2920
+ skip = True
2921
+ if isreading:
2922
+ prompt = str(sys.ps3)
2923
+ elif self.more:
2924
+ prompt = str(sys.ps2)
2925
+ else:
2926
+ prompt = str(sys.ps1)
2927
+ pos = self.GetCurLine()[1]
2928
+ if pos > 0:
2929
+ if isreading:
2930
+ skip = True
2931
+ else:
2932
+ self.write(os.linesep,type='Input')
2933
+ if not self.more:
2934
+ # Not needed anymore! # self.promptPosStart = self.GetCurrentPos()
2935
+ pass
2936
+ if not skip:
2937
+ self.write(prompt,type='Input')
2938
+ if not self.more:
2939
+ # Not needed anymore! # self.promptPosEnd = self.GetCurrentPos()
2940
+ # Clear the undo history after running a command.
2941
+ self.EmptyUndoBuffer()
2942
+
2943
+ #DNM/CP
2944
+ # Autoindent magic
2945
+ # Match the indent of the line above
2946
+ # UNLESS the line above ends in a colon...then add four spaces
2947
+ # (after valid keywords (if, else, etc...) only)
2948
+ if self.more:
2949
+ line_num=self.GetCurrentLine()
2950
+ currentLine=self.GetLine(line_num)
2951
+ previousLine=self.GetLine(line_num-1)
2952
+ pstrip=previousLine.strip()
2953
+ lstrip=previousLine.lstrip()
2954
+
2955
+ if pstrip == '':
2956
+ # because it is all whitespace!
2957
+ indent=previousLine.strip('\n').strip('\r')
2958
+ else:
2959
+ indent=previousLine[:(len(previousLine)-len(lstrip))]
2960
+ if testForContinuations(previousLine,ignoreErrors=True)[1][0]:
2961
+ indent+=' '*4
2962
+
2963
+ #ADD UNDO
2964
+ cpos=self.GetCurrentPos()
2965
+ s=indent
2966
+ self.UpdateUndoHistoryBefore('insert',s,cpos,cpos+len(s))
2967
+ self.write(s,type='Input')
2968
+ self.UpdateUndoHistoryAfter()
2969
+
2970
+
2971
+ self.EnsureCaretVisible()
2972
+ self.ScrollToColumn(0)
2973
+
2974
+ def readline(self):
2975
+ """Replacement for stdin.readline()."""
2976
+ input = ''
2977
+ reader = self.reader
2978
+ reader.isreading = True
2979
+ self.prompt()
2980
+
2981
+ # Ensure that we get a new line and that it's got an input marker...
2982
+ # Also need to temporarily block any other action...
2983
+ cLine = self.GetCurrentLine()
2984
+ self.clearIOMarkers(cLine)
2985
+ self.MarkerAdd(cLine,INPUT_START)
2986
+ self.MarkerAdd(cLine,READLINE_BG)
2987
+ self.MarkerAdd(cLine,INPUT_READLINE)
2988
+
2989
+ try:
2990
+ while not reader.input:
2991
+ wx.GetApp().Yield(onlyIfNeeded=True)
2992
+ input = reader.input
2993
+ finally:
2994
+ start,end = self.GetIOSlice()
2995
+ start = self.runningSlice[1] + 1
2996
+ for i in range(start,end+1):
2997
+ self.clearIOMarkers(i)
2998
+ self.clearGroupingMarkers(i)
2999
+ self.MarkerAdd(i,OUTPUT_BG)
3000
+ if i == start: self.MarkerAdd(i,OUTPUT_START)
3001
+ elif i==end: self.MarkerAdd(i,OUTPUT_END)
3002
+ else: self.MarkerAdd(i,OUTPUT_MIDDLE)
3003
+
3004
+ if i==end: self.MarkerAdd(i,GROUPING_END)
3005
+ else: self.MarkerAdd(i,GROUPING_MIDDLE)
3006
+ reader.input = ''
3007
+ reader.isreading = False
3008
+ input = str(input) # In case of Unicode.
3009
+ return input
3010
+
3011
+ def readlines(self):
3012
+ """Replacement for stdin.readlines()."""
3013
+ lines = []
3014
+ while lines[-1:] != ['\n']:
3015
+ lines.append(self.readline())
3016
+ return lines
3017
+
3018
+ def raw_input(self, prompt=''):
3019
+ """Return string based on user input."""
3020
+ if prompt:
3021
+ self.write(prompt,type='Output')
3022
+ return self.readline()
3023
+
3024
+ def ask(self, prompt='Please enter your response:'):
3025
+ """Get response from the user using a dialog box."""
3026
+ dialog = wx.TextEntryDialog(None, prompt,
3027
+ 'Input Dialog (Raw)', '')
3028
+ try:
3029
+ if dialog.ShowModal() == wx.ID_OK:
3030
+ text = dialog.GetValue()
3031
+ return text
3032
+ finally:
3033
+ dialog.Destroy()
3034
+ return ''
3035
+
3036
+ def pause(self):
3037
+ """Halt execution pending a response from the user."""
3038
+ self.ask('Press enter to continue:')
3039
+
3040
+ def clear(self):
3041
+ """Delete all text from the slices shell."""
3042
+ self.ClearAll()
3043
+ self.MarkerAdd(0,GROUPING_START)
3044
+ self.MarkerAdd(0,INPUT_START)
3045
+
3046
+ def run(self, command, prompt=True, verbose=True):
3047
+ """Execute command as if it was typed in directly.
3048
+ >>> shell.run('print("this")')
3049
+ >>> print("this")
3050
+ this
3051
+ >>>
3052
+ """
3053
+ # Go to the very bottom of the text.
3054
+ endpos = self.GetTextLength()
3055
+ self.SetCurrentPos(endpos)
3056
+ command = command.rstrip()
3057
+ if prompt: self.prompt()
3058
+ if verbose: self.write(command,type='Input')
3059
+ self.push(command)
3060
+
3061
+ # TODO : Will have to fix this to handle other kinds of errors mentioned before...
3062
+ def runfile(self, filename):
3063
+ """Execute all commands in file as if they were typed into the shell."""
3064
+ self.prompt()
3065
+ with open(filename) as file_:
3066
+ for command in file_:
3067
+ if command[:6] == 'shell.':
3068
+ # Run shell methods silently.
3069
+ self.run(command, prompt=False, verbose=False)
3070
+ else:
3071
+ self.run(command, prompt=False, verbose=True)
3072
+
3073
+ def autoCompleteShow(self, command, offset = 0):
3074
+ """Display auto-completion popup list."""
3075
+ self.AutoCompSetAutoHide(self.autoCompleteAutoHide)
3076
+ self.AutoCompSetIgnoreCase(self.autoCompleteCaseInsensitive)
3077
+ list = self.interp.getAutoCompleteList(command,
3078
+ includeMagic=self.autoCompleteIncludeMagic,
3079
+ includeSingle=self.autoCompleteIncludeSingle,
3080
+ includeDouble=self.autoCompleteIncludeDouble)
3081
+ if list:
3082
+ options = ' '.join(list)
3083
+ #offset = 0
3084
+ self.AutoCompShow(offset, options)
3085
+
3086
+ def autoCallTipShow(self, command, insertcalltip = True, forceCallTip = False):
3087
+ """Display argument spec and docstring in a popup window."""
3088
+ if self.CallTipActive():
3089
+ self.CallTipCancel()
3090
+ (name, argspec, tip) = self.interp.getCallTip(command)
3091
+ if tip:
3092
+ dispatcher.send(signal='SlicesShell.calltip', sender=self, calltip=tip)
3093
+ if not self.autoCallTip and not forceCallTip:
3094
+ return
3095
+ startpos = self.GetCurrentPos()
3096
+ if argspec and insertcalltip and self.callTipInsert:
3097
+ # write with undo history...
3098
+ cpos=self.GetCurrentPos()
3099
+ s=argspec + ')'
3100
+ self.UpdateUndoHistoryBefore('insert',s,cpos,cpos+len(s))
3101
+ self.write(s,type='Input')
3102
+ self.UpdateUndoHistoryAfter()
3103
+
3104
+ endpos = self.GetCurrentPos()
3105
+ self.SetSelection(startpos, endpos)
3106
+ if tip:
3107
+ tippos = startpos - (len(name) + 1)
3108
+ fallback = startpos - self.GetColumn(startpos)
3109
+ # In case there isn't enough room, only go back to the fallback.
3110
+ tippos = max(tippos, fallback)
3111
+ self.CallTipShow(tippos, tip)
3112
+
3113
+ def OnCallTipAutoCompleteManually (self, shiftDown):
3114
+ """AutoComplete and Calltips manually."""
3115
+ if self.AutoCompActive():
3116
+ self.AutoCompCancel()
3117
+ currpos = self.GetCurrentPos()
3118
+ stoppos = self.PositionFromLine(self.GetIOSlice()[0])
3119
+
3120
+ cpos = currpos
3121
+ #go back until '.' is found
3122
+ pointavailpos = -1
3123
+ while cpos >= stoppos:
3124
+ if self.GetCharAt(cpos) == ord ('.'):
3125
+ pointavailpos = cpos
3126
+ break
3127
+ cpos -= 1
3128
+
3129
+ #word from non whitespace until '.'
3130
+ if pointavailpos != -1:
3131
+ #look backward for first whitespace char
3132
+ textbehind = self.GetTextRange (pointavailpos + 1, currpos)
3133
+ pointavailpos += 1
3134
+
3135
+ if not shiftDown:
3136
+ #call AutoComplete
3137
+ stoppos = self.PositionFromLine(self.GetIOSlice()[0])
3138
+ textbefore = self.GetTextRange(stoppos, pointavailpos)
3139
+ self.autoCompleteShow(textbefore, len (textbehind))
3140
+ else:
3141
+ #call CallTips
3142
+ cpos = pointavailpos
3143
+ begpos = -1
3144
+ while cpos > stoppos:
3145
+ if chr(self.GetCharAt(cpos)).isspace():
3146
+ begpos = cpos
3147
+ break
3148
+ cpos -= 1
3149
+ if begpos == -1:
3150
+ begpos = cpos
3151
+ ctips = self.GetTextRange (begpos, currpos)
3152
+ ctindex = ctips.find ('(')
3153
+ if ctindex != -1 and not self.CallTipActive():
3154
+ #insert calltip, if current pos is '(', otherwise show it only
3155
+ self.autoCallTipShow( ctips[:ctindex + 1],
3156
+ self.GetCharAt(currpos - 1) == ord('(') and
3157
+ self.GetCurrentPos() == self.GetTextLength(),
3158
+ True )
3159
+
3160
+
3161
+ def writeOut(self, text):
3162
+ """Replacement for stdout."""
3163
+ self.write(text,type='Output')
3164
+ # TODO : FLUSH?? How to make this update real-time...
3165
+
3166
+ def writeErr(self, text):
3167
+ """Replacement for stderr."""
3168
+ self.write(text,type='Error')
3169
+
3170
+ def redirectStdin(self, redirect=True):
3171
+ """If redirect is true then sys.stdin will come from the shell."""
3172
+ if redirect:
3173
+ sys.stdin = self.reader
3174
+ else:
3175
+ sys.stdin = self.stdin
3176
+
3177
+ def redirectStdout(self, redirect=True):
3178
+ """If redirect is true then sys.stdout will go to the shell."""
3179
+ if redirect:
3180
+ sys.stdout = PseudoFileOut(self.writeOut)
3181
+ else:
3182
+ sys.stdout = self.stdout
3183
+
3184
+ def redirectStderr(self, redirect=True):
3185
+ """If redirect is true then sys.stderr will go to the shell."""
3186
+ if redirect:
3187
+ sys.stderr = PseudoFileErr(self.writeErr)
3188
+ else:
3189
+ sys.stderr = self.stderr
3190
+
3191
+ # Take a spashot of the WHOLE grouping slice (or slices)
3192
+ # The argument s is either what got added or deleted
3193
+ def UpdateUndoHistoryBefore(self,actionType,s,posStart,posEnd,
3194
+ forceNewAction=False):
3195
+ uH=self.undoHistory
3196
+ uI=self.undoIndex
3197
+
3198
+ s=s.replace(os.linesep,'\n')
3199
+ startLine=self.LineFromPosition(posStart)
3200
+
3201
+ if actionType=='marker':
3202
+ numLines = self.LineFromPosition(posEnd) - startLine
3203
+ else:
3204
+ numLines=s.count('\n')
3205
+
3206
+ makeNewAction=forceNewAction
3207
+
3208
+ if forceNewAction:
3209
+ makeNewAction=True
3210
+ elif self.undoIndex==-1:
3211
+ makeNewAction=True
3212
+ elif not uH[uI]['allowsAppend']:
3213
+ makeNewAction=True
3214
+ elif actionType!=uH[uI]['actionType']:
3215
+ makeNewAction=True
3216
+ elif actionType=='insert':
3217
+ if posStart!=uH[uI]['posEnd']:
3218
+ makeNewAction=True
3219
+ else: # This is a continuation of the previous insert
3220
+ uH[uI]['charList'] = uH[uI]['charList']+s
3221
+ uH[uI]['posEnd'] = posEnd # posStart cannot move
3222
+ uH[uI]['numLines'] = uH[uI]['numLines']+numLines
3223
+ elif actionType=='delete':
3224
+ # This is a forward continuation of the previous delete
3225
+ if posStart==uH[uI]['posStart']:
3226
+ uH[uI]['charList'] = uH[uI]['charList']+s
3227
+ uH[uI]['posEnd'] = posEnd
3228
+ uH[uI]['numLines'] = uH[uI]['numLines']+numLines
3229
+ # This is a backward continuation of the previous delete
3230
+ elif posEnd==uH[uI]['posStart']:
3231
+ uH[uI]['charList'] = s+uH[uI]['charList']
3232
+ uH[uI]['posStart'] = posStart
3233
+ uH[uI]['startLine'] = startLine
3234
+ uH[uI]['numLines'] = uH[uI]['numLines']+numLines
3235
+ else:
3236
+ makeNewAction=True
3237
+
3238
+ elif actionType=='marker':
3239
+ makeNewAction=True
3240
+ else:
3241
+ pass #print('Unsupported Action Type!!')
3242
+
3243
+ if makeNewAction:
3244
+ del(self.undoHistory[uI+1:]) # remove actions after undoIndex
3245
+
3246
+ uH.append({
3247
+ 'actionType' : actionType, # Action type ('insert','delete','marker')
3248
+ 'allowsAppend': not forceNewAction, # Can action be joined with others?
3249
+ 'charList' : s, # Character list
3250
+ 'posStart' : posStart, # Cursor poition at the start of the action
3251
+ 'posEnd' : posEnd, # Cursor position at the end of the action
3252
+ 'startLine' : startLine, # Start line number,
3253
+ 'numLines' : numLines, # Number of newlines involved
3254
+ 'mBStart' : None, # Starting line for markers BEFORE action
3255
+ 'mAStart' : None, # Starting line for markers AFTER action
3256
+ 'markersBefore' : None, # [markers BEFORE action]
3257
+ 'markersAfter' : None # [markers AFTER action]
3258
+ })
3259
+
3260
+ self.undoIndex+=1
3261
+
3262
+ # Only update the before when starting a new action
3263
+ start = startLine
3264
+ if actionType=='insert':
3265
+ end = start
3266
+ else:
3267
+ end = start + numLines
3268
+
3269
+ # Update Marker Info
3270
+ newStart=self.GetGroupingSlice(start)[0]
3271
+ newEnd=self.GetGroupingSlice(end)[1]
3272
+ self.undoHistory[self.undoIndex]['markersBefore'] = \
3273
+ [self.MarkerGet(i) for i in range(newStart,newEnd+1)]
3274
+ self.undoHistory[self.undoIndex]['mBStart']=newStart
3275
+
3276
+ self.doHistUpdate=True
3277
+
3278
+ def UpdateUndoHistoryAfter(self): # s is either what got added or deleted
3279
+ start = self.undoHistory[self.undoIndex]['startLine']
3280
+ if self.undoHistory[self.undoIndex]['actionType']=='delete':
3281
+ end = start
3282
+ else:
3283
+ end = start + self.undoHistory[self.undoIndex]['numLines']
3284
+
3285
+ newStart=min(self.GetGroupingSlice(start)[0]-1, 0)
3286
+ newEnd=max(self.GetGroupingSlice(end)[1]+1, self.GetLineCount()-1)
3287
+ self.undoHistory[self.undoIndex]['markersAfter'] = \
3288
+ [self.MarkerGet(i) for i in range(newStart,newEnd+1)]
3289
+ self.undoHistory[self.undoIndex]['mAStart']=newStart
3290
+
3291
+ self.doHistUpdate=False
3292
+
3293
+ def Undo(self):
3294
+ #ADD UNDO
3295
+ #Skip undo if there are no actions...
3296
+ if self.undoIndex==-1:
3297
+ return
3298
+
3299
+ uHI=self.undoHistory[self.undoIndex]
3300
+
3301
+ if uHI['actionType'] in ['insert','delete']:
3302
+ # This will perform the opposite of the action given
3303
+ editwindow.EditWindow.Undo(self)
3304
+ elif uHI['actionType']=='marker': # No text changed, don't pass to STC
3305
+ pass
3306
+ else:
3307
+ #print('Unsupported actionType in undoHistory!!')
3308
+ return
3309
+
3310
+ numLines=len(uHI['markersBefore'])
3311
+ for i in range(numLines):
3312
+ self.MarkerSet( uHI['mBStart']+i , uHI['markersBefore'][i] )
3313
+
3314
+ self.undoIndex-=1
3315
+
3316
+ def Redo(self):
3317
+ #ADD UNDO
3318
+ # First check to see if there are any redo operations available
3319
+ # Note that for redo, undoIndex=-1 is a valid input
3320
+ if self.undoIndex >= len(self.undoHistory)-1:
3321
+ return
3322
+ self.undoIndex+=1
3323
+ uHI=self.undoHistory[self.undoIndex]
3324
+
3325
+ if uHI['actionType'] in ['insert','delete']:
3326
+ # This will re-perform the given action
3327
+ editwindow.EditWindow.Redo(self)
3328
+ elif uHI['actionType']=='marker': # No text changed, don't pass to STC
3329
+ pass
3330
+ else:
3331
+ #print('Unsupported actionType in undoHistory!!')
3332
+ return
3333
+
3334
+ numLines=len(uHI['markersAfter'])
3335
+ for i in range(numLines):
3336
+ self.MarkerSet( uHI['mAStart']+i , uHI['markersAfter'][i] )
3337
+
3338
+ def EmptyUndoBuffer(self):
3339
+ editwindow.EditWindow.EmptyUndoBuffer(self)
3340
+ self.undoIndex=-1
3341
+ self.undoHistory=[]
3342
+ self.doHistUpdate=False
3343
+
3344
+ def CanCut(self):
3345
+ return self.CanEdit() and \
3346
+ (self.GetSelectionStart() != self.GetSelectionEnd())
3347
+
3348
+ def CanPaste(self):
3349
+ """Return true if a paste should succeed."""
3350
+ if self.CanEdit() and editwindow.EditWindow.CanPaste(self):
3351
+ return True
3352
+ else:
3353
+ return False
3354
+
3355
+ def CanEdit(self):
3356
+ """Return true if editing should succeed."""
3357
+ marker=self.MarkerGet(self.GetCurrentLine())
3358
+
3359
+ if marker & OUTPUT_MASK:
3360
+ return False
3361
+ elif marker & INPUT_MASK:
3362
+ if self.reader.isreading and not \
3363
+ (self.MarkerGet(self.GetCurrentLine()) & 1<<INPUT_READLINE ):
3364
+ return False
3365
+ start,end=self.GetIOSlice()
3366
+ sliceStartPos=self.PositionFromLine(start)
3367
+ sliceEndPos=self.GetLineEndPosition(end)
3368
+ """Return true if text is selected and can be cut."""
3369
+ if self.GetSelectionStart() == self.GetSelectionEnd():
3370
+ return True
3371
+ elif self.GetSelectionStart() != self.GetSelectionEnd() \
3372
+ and self.GetSelectionStart() >= sliceStartPos \
3373
+ and self.GetSelectionEnd() >= sliceStartPos \
3374
+ and self.GetSelectionStart() <= sliceEndPos \
3375
+ and self.GetSelectionEnd() <= sliceEndPos:
3376
+ return True
3377
+ return False
3378
+
3379
+ def Cut(self):
3380
+ """Remove selection and place it on the clipboard."""
3381
+ if self.CanCut() and self.CanCopy():
3382
+ if self.AutoCompActive():
3383
+ self.AutoCompCancel()
3384
+ if self.CallTipActive():
3385
+ self.CallTipCancel()
3386
+ self.Copy()
3387
+ self.ReplaceSelection('')
3388
+
3389
+ def Copy(self):
3390
+ """Copy selection and place it on the clipboard."""
3391
+ if self.CanCopy():
3392
+ ps1 = str(sys.ps1)
3393
+ ps2 = str(sys.ps2)
3394
+ command = self.GetSelectedText()
3395
+ command = command.replace(os.linesep + ps2, os.linesep)
3396
+ command = command.replace(os.linesep + ps1, os.linesep)
3397
+ command = self.lstripPrompt(text=command)
3398
+ data = wx.TextDataObject(command)
3399
+ self._clip(data)
3400
+
3401
+ def CopyWithPrompts(self):
3402
+ """Copy selection, including prompts, and place it on the clipboard."""
3403
+ if self.CanCopy():
3404
+ command = self.GetSelectedText()
3405
+ data = wx.TextDataObject(command)
3406
+ self._clip(data)
3407
+
3408
+ def CopyWithPromptsPrefixed(self):
3409
+ """Copy selection, including prompts prefixed with four
3410
+ spaces, and place it on the clipboard."""
3411
+ if self.CanCopy():
3412
+ command = self.GetSelectedText()
3413
+ spaces = ' ' * 4
3414
+ command = spaces + command.replace(os.linesep,
3415
+ os.linesep + spaces)
3416
+ data = wx.TextDataObject(command)
3417
+ self._clip(data)
3418
+
3419
+ def _clip(self, data):
3420
+ if wx.TheClipboard.Open():
3421
+ wx.TheClipboard.UsePrimarySelection(False)
3422
+ wx.TheClipboard.SetData(data)
3423
+ wx.TheClipboard.Flush()
3424
+ wx.TheClipboard.Close()
3425
+
3426
+ def Paste(self):
3427
+ """Replace selection with clipboard contents."""
3428
+
3429
+ #ADD UNDO
3430
+ if self.CanPaste() and wx.TheClipboard.Open():
3431
+ ps2 = str(sys.ps2)
3432
+ if wx.TheClipboard.IsSupported(wx.DataFormat(wx.DF_TEXT)):
3433
+ data = wx.TextDataObject()
3434
+ if wx.TheClipboard.GetData(data):
3435
+ self.ReplaceSelection('')
3436
+ command = data.GetText()
3437
+ command = command.rstrip()
3438
+ command = self.fixLineEndings(command)
3439
+ command = self.lstripPrompt(text=command)
3440
+ # TODO : This is still useful... Add it back other places?
3441
+ command = command.replace(os.linesep + ps2, '\n')
3442
+ command = command.replace(os.linesep, '\n')
3443
+ #DNM--Don't use '... '
3444
+ command = command.replace('\n', os.linesep)# + ps2)
3445
+
3446
+ cpos=self.GetCurrentPos()
3447
+ s=command
3448
+ self.UpdateUndoHistoryBefore('insert', s, cpos,
3449
+ cpos+len(s), forceNewAction=True)
3450
+ self.write(s,type='Input')
3451
+ self.UpdateUndoHistoryAfter()
3452
+
3453
+ # Makes paste -> type -> undo consistent with other STC apps
3454
+ self.ReplaceSelection('')
3455
+ wx.TheClipboard.Close()
3456
+
3457
+
3458
+ def PasteAndRun(self):
3459
+ """Replace selection with clipboard contents, run commands."""
3460
+ text = ''
3461
+ if wx.TheClipboard.Open():
3462
+ if wx.TheClipboard.IsSupported(wx.DataFormat(wx.DF_TEXT)):
3463
+ data = wx.TextDataObject()
3464
+ if wx.TheClipboard.GetData(data):
3465
+ text = data.GetText()
3466
+ wx.TheClipboard.Close()
3467
+ if text:
3468
+ self.Execute(text)
3469
+
3470
+
3471
+ def Execute(self, text):
3472
+ """Replace selection with text and run commands."""
3473
+ start,end=self.GetIOSlice()
3474
+ startpos=self.PositionFromLine(start)
3475
+ endpos=self.GetLineEndPosition(end)
3476
+
3477
+ self.SetCurrentPos(endpos)
3478
+ self.SetSelection(startpos, endpos)
3479
+ self.ReplaceSelection('')
3480
+
3481
+ hasSyntaxError=False
3482
+ result = self.BreakTextIntoCommands(command)
3483
+ if result[0] is None:
3484
+ commands=[command]
3485
+ hasSyntaxError=True
3486
+ else:
3487
+ commands=result
3488
+
3489
+ for command in commands:
3490
+ command = command.replace('\n', os.linesep)
3491
+ self.write(command)
3492
+ self.processLine()
3493
+
3494
+ def wrap(self, wrap=True):
3495
+ """Sets whether text is word wrapped."""
3496
+ try:
3497
+ self.SetWrapMode(wrap)
3498
+ except AttributeError:
3499
+ return 'Wrapping is not available in this version.'
3500
+
3501
+ def zoom(self, points=0):
3502
+ """Set the zoom level.
3503
+
3504
+ This number of points is added to the size of all fonts. It
3505
+ may be positive to magnify or negative to reduce."""
3506
+ self.SetZoom(points)
3507
+
3508
+ def LoadSettings(self, config):
3509
+ self.autoComplete = \
3510
+ config.ReadBool('Options/AutoComplete', True)
3511
+ self.autoCompleteIncludeMagic = \
3512
+ config.ReadBool('Options/AutoCompleteIncludeMagic', True)
3513
+ self.autoCompleteIncludeSingle = \
3514
+ config.ReadBool('Options/AutoCompleteIncludeSingle', True)
3515
+ self.autoCompleteIncludeDouble = \
3516
+ config.ReadBool('Options/AutoCompleteIncludeDouble', True)
3517
+ self.autoCallTip = \
3518
+ config.ReadBool('Options/AutoCallTip', True)
3519
+ self.callTipInsert = \
3520
+ config.ReadBool('Options/CallTipInsert', True)
3521
+
3522
+ self.SetWrapMode(config.ReadBool('View/WrapMode', True))
3523
+
3524
+ self.lineNumbers = \
3525
+ config.ReadBool('View/ShowLineNumbers', True)
3526
+ self.setDisplayLineNumbers (self.lineNumbers)
3527
+ zoom = config.ReadInt('View/Zoom/Shell', -99)
3528
+ if zoom != -99:
3529
+ self.SetZoom(zoom)
3530
+
3531
+
3532
+
3533
+ def SaveSettings(self, config):
3534
+ config.WriteBool('Options/AutoComplete', self.autoComplete)
3535
+ config.WriteBool('Options/AutoCompleteIncludeMagic',
3536
+ self.autoCompleteIncludeMagic)
3537
+ config.WriteBool('Options/AutoCompleteIncludeSingle',
3538
+ self.autoCompleteIncludeSingle)
3539
+ config.WriteBool('Options/AutoCompleteIncludeDouble',
3540
+ self.autoCompleteIncludeDouble)
3541
+ config.WriteBool('Options/AutoCallTip', self.autoCallTip)
3542
+ config.WriteBool('Options/CallTipInsert', self.callTipInsert)
3543
+ config.WriteBool('View/WrapMode', self.GetWrapMode())
3544
+ config.WriteBool('View/ShowLineNumbers', self.lineNumbers)
3545
+ config.WriteInt('View/Zoom/Shell', self.GetZoom())
3546
+
3547
+ def GetContextMenu(self):
3548
+ """
3549
+ Create and return a context menu for the slices shell.
3550
+ This is used instead of the scintilla default menu
3551
+ in order to correctly respect our immutable buffer.
3552
+ """
3553
+ menu = wx.Menu()
3554
+ menu.Append(self.ID_UNDO, "Undo")
3555
+ menu.Append(self.ID_REDO, "Redo")
3556
+
3557
+ menu.AppendSeparator()
3558
+
3559
+ menu.Append(self.ID_CUT, "Cut")
3560
+ menu.Append(self.ID_COPY, "Copy")
3561
+ menu.Append(frame.ID_COPY_PLUS, "Copy With Prompts")
3562
+ menu.Append(self.ID_PASTE, "Paste")
3563
+ menu.Append(frame.ID_PASTE_PLUS, "Paste And Run")
3564
+ menu.Append(self.ID_CLEAR, "Clear")
3565
+
3566
+ menu.AppendSeparator()
3567
+
3568
+ menu.Append(self.ID_SELECTALL, "Select All")
3569
+ return menu
3570
+
3571
+ def OnContextMenu(self, evt):
3572
+ menu = self.GetContextMenu()
3573
+ self.PopupMenu(menu)
3574
+
3575
+ def OnUpdateUI(self, evt):
3576
+ id = evt.Id
3577
+ if id in (self.ID_CUT, self.ID_CLEAR):
3578
+ evt.Enable(self.CanCut())
3579
+ elif id in (self.ID_COPY, frame.ID_COPY_PLUS):
3580
+ evt.Enable(self.CanCopy())
3581
+ elif id in (self.ID_PASTE, frame.ID_PASTE_PLUS):
3582
+ evt.Enable(self.CanPaste())
3583
+ elif id == self.ID_UNDO:
3584
+ evt.Enable(self.CanUndo())
3585
+ elif id == self.ID_REDO:
3586
+ evt.Enable(self.CanRedo())
3587
+
3588
+ def LoadPySlicesFile(self,fid):
3589
+ invalidFileString = 'Not a valid input format'
3590
+ lineCount=0
3591
+ groupingStartLines=[0]
3592
+ ioStartLines=[0]
3593
+ ioStartTypes=[]
3594
+ removeComment=False
3595
+
3596
+ # Read the initial three (or four) lines that have version and marker information
3597
+ line=fid.readline()
3598
+ if line == usrBinEnvPythonText:
3599
+ line=fid.readline() # Add the option to place #!/usr/bin/env python at the top
3600
+ if line not in pyslicesFormatHeaderText: print(invalidFileString); return
3601
+ line=fid.readline()
3602
+ if line != groupingStartText: print(invalidFileString); return
3603
+ line=fid.readline()
3604
+ if line == inputStartText: ioStartTypes.append('input');removeComment=False
3605
+ elif line == outputStartText: ioStartTypes.append('output');removeComment=True
3606
+ else: print(invalidFileString); return
3607
+
3608
+ self.ClearAll()
3609
+
3610
+ # Write the file's text to the text area
3611
+ # Capture Marker information to
3612
+ for i in fid:
3613
+ if i==groupingStartText:
3614
+ groupingStartLines.append(lineCount)
3615
+ elif i==inputStartText:
3616
+ ioStartLines.append(lineCount)
3617
+ ioStartTypes.append('input')
3618
+ removeComment=False
3619
+ elif i==outputStartText:
3620
+ ioStartLines.append(lineCount)
3621
+ ioStartTypes.append('output')
3622
+ removeComment=True
3623
+ else:
3624
+ if removeComment: w=i[1:].replace(os.linesep,'\n')
3625
+ else: w=i.replace(os.linesep,'\n')
3626
+ self.write(w,'Input',silent=True)
3627
+ lineCount+=1
3628
+
3629
+ if w[-1]=='\n':
3630
+ lineCount+=1
3631
+
3632
+ for i in range(lineCount+1):
3633
+ self.clearGroupingMarkers(i)
3634
+ self.clearIOMarkers(i)
3635
+
3636
+ doMiddle=False
3637
+ doEnd=False
3638
+ if groupingStartLines!=[]:
3639
+ if i == groupingStartLines[0]:
3640
+ self.MarkerAdd(i,GROUPING_START)
3641
+ del groupingStartLines[0]
3642
+ elif i+1 == groupingStartLines[0]:
3643
+ doEnd=True
3644
+ else:
3645
+ doMiddle=True
3646
+ elif i==lineCount-1:
3647
+ doEnd=True
3648
+ else:
3649
+ doMiddle=True
3650
+
3651
+ if doMiddle:
3652
+ self.MarkerAdd(i,GROUPING_MIDDLE)
3653
+ elif doEnd:
3654
+ self.MarkerAdd(i,GROUPING_END)
3655
+
3656
+ doMiddle=False
3657
+ doEnd=False
3658
+ if ioStartLines!=[]:
3659
+ if i == ioStartLines[0]:
3660
+ # Delete the old ioStartTypes (keep the current copy for later use)
3661
+ if i>0: del ioStartTypes[0]
3662
+
3663
+ if ioStartTypes[0]=='input':
3664
+ self.MarkerAdd(i,INPUT_START)
3665
+ elif ioStartTypes[0]=='output':
3666
+ self.MarkerAdd(i,OUTPUT_START)
3667
+ self.MarkerAdd(i,OUTPUT_BG)
3668
+ else:
3669
+ #print('Invalid Type!')
3670
+ return
3671
+
3672
+ # Only delete markers we are totally finished with...
3673
+ # Keep one more "StartTypes" than "StartLines"
3674
+ del ioStartLines[0]
3675
+ elif i+1 == ioStartLines[0]:
3676
+ doEnd=True
3677
+ else:
3678
+ doMiddle=True
3679
+ elif i==lineCount-1:
3680
+ doEnd=True
3681
+ else:
3682
+ doMiddle=True
3683
+
3684
+ if doMiddle:
3685
+ if ioStartTypes[0]=='input':
3686
+ self.MarkerAdd(i,INPUT_MIDDLE)
3687
+ elif ioStartTypes[0]=='output':
3688
+ self.MarkerAdd(i,OUTPUT_MIDDLE)
3689
+ self.MarkerAdd(i,OUTPUT_BG)
3690
+ else:
3691
+ #print('Invalid Type!')
3692
+ return
3693
+ elif doEnd:
3694
+ if ioStartTypes[0]=='input':
3695
+ self.MarkerAdd(i,INPUT_END)
3696
+ elif ioStartTypes[0]=='output':
3697
+ self.MarkerAdd(i,OUTPUT_END)
3698
+ self.MarkerAdd(i,OUTPUT_BG)
3699
+ else:
3700
+ #print('Invalid Type!')
3701
+ return
3702
+
3703
+ self.EmptyUndoBuffer() # maybe not?
3704
+
3705
+
3706
+ def SavePySlicesFile(self,fid):
3707
+ addComment=False
3708
+
3709
+ def fid_write(s):
3710
+ fid.write(s.replace('\r\n', '\n')
3711
+ .replace('\n', os.linesep)
3712
+ .encode('utf-8'))
3713
+
3714
+ fid_write(usrBinEnvPythonText)
3715
+ fid_write(pyslicesFormatHeaderText[-1])
3716
+ for i in range(self.GetLineCount()):
3717
+ markers=self.MarkerGet(i)
3718
+ if markers & ( 1<<GROUPING_START | 1<<GROUPING_START_FOLDED ):
3719
+ fid_write(groupingStartText)
3720
+ if markers & ( 1<<INPUT_START | 1<<INPUT_START_FOLDED ):
3721
+ fid_write(inputStartText)
3722
+ addComment=False
3723
+ if markers & ( 1<<OUTPUT_START | 1<<OUTPUT_START_FOLDED ):
3724
+ fid_write(outputStartText)
3725
+ addComment=True
3726
+ if addComment:
3727
+ fid_write(u'#')
3728
+
3729
+ fid_write(self.GetLine(i))
3730
+
3731
+ # FIX ME!!
3732
+ def LoadPyFileAsSlice(self,fid):
3733
+ curpos=self.GetCurrentPos()
3734
+ start,end = self.GetGroupingSlice()
3735
+
3736
+ endpos=self.GetLineEndPosition(end)
3737
+ self.SetCurrentPos(endpos)
3738
+ self.SetSelection(endpos, endpos)
3739
+
3740
+ text='\n'+fid.read()
3741
+ self.write(text,'Input')
3742
+ newpos=self.GetCurrentPos()
3743
+
3744
+ self.SetCurrentPos(curpos)
3745
+ self.SetSelection(curpos,curpos)
3746
+ self.SplitSlice()
3747
+ #self.SetCurrentPos(newpos)
3748
+ #self.SetSelection(newpos,newpos)
3749
+
3750
+ def hasChanged(self):
3751
+ """Return True if contents have changed."""
3752
+ return self.GetModify() or self.NeedsCheckForSave
3753
+
3754
+
3755
+
3756
+ ## NOTE: The DnD of file names is disabled until we can figure out how
3757
+ ## best to still allow DnD of text.
3758
+
3759
+ ## #seb : File drag and drop
3760
+ ## class FileDropTarget(wx.FileDropTarget):
3761
+ ## def __init__(self, obj):
3762
+ ## wx.FileDropTarget.__init__(self)
3763
+ ## self.obj = obj
3764
+ ## def OnDropFiles(self, x, y, filenames):
3765
+ ## if len(filenames) == 1:
3766
+ ## txt = 'r\"%s\"' % filenames[0]
3767
+ ## else:
3768
+ ## txt = '( '
3769
+ ## for f in filenames:
3770
+ ## txt += 'r\"%s\" , ' % f
3771
+ ## txt += ')'
3772
+ ## self.obj.AppendText(txt)
3773
+ ## pos = self.obj.GetCurrentPos()
3774
+ ## self.obj.SetCurrentPos( pos )
3775
+ ## self.obj.SetSelection( pos, pos )
3776
+
3777
+
3778
+
3779
+ ## class TextAndFileDropTarget(wx.DropTarget):
3780
+ ## def __init__(self, sliceshell):
3781
+ ## wx.DropTarget.__init__(self)
3782
+ ## self.sliceshell = sliceshell
3783
+ ## self.compdo = wx.DataObjectComposite()
3784
+ ## self.textdo = wx.TextDataObject()
3785
+ ## self.filedo = wx.FileDataObject()
3786
+ ## self.compdo.Add(self.textdo)
3787
+ ## self.compdo.Add(self.filedo, True)
3788
+
3789
+ ## self.SetDataObject(self.compdo)
3790
+
3791
+ ## def OnDrop(self, x, y):
3792
+ ## return True
3793
+
3794
+ ## def OnData(self, x, y, result):
3795
+ ## self.GetData()
3796
+ ## if self.textdo.GetTextLength() > 1:
3797
+ ## text = self.textdo.GetText()
3798
+ ## # *** Do somethign with the dragged text here...
3799
+ ## self.textdo.SetText('')
3800
+ ## else:
3801
+ ## filenames = str(self.filename.GetFilenames())
3802
+ ## if len(filenames) == 1:
3803
+ ## txt = 'r\"%s\"' % filenames[0]
3804
+ ## else:
3805
+ ## txt = '( '
3806
+ ## for f in filenames:
3807
+ ## txt += 'r\"%s\" , ' % f
3808
+ ## txt += ')'
3809
+ ## self.sliceshell.AppendText(txt)
3810
+ ## pos = self.sliceshell.GetCurrentPos()
3811
+ ## self.sliceshell.SetCurrentPos( pos )
3812
+ ## self.sliceshell.SetSelection( pos, pos )
3813
+
3814
+ ## return result