| 1 |
#!/usr/bin/env python |
|---|
| 2 |
# -*- coding: utf-8 -*- |
|---|
| 3 |
|
|---|
| 4 |
import sys |
|---|
| 5 |
import os |
|---|
| 6 |
import os.path |
|---|
| 7 |
import keyword |
|---|
| 8 |
import code |
|---|
| 9 |
import inspect |
|---|
| 10 |
import operator |
|---|
| 11 |
import dabo |
|---|
| 12 |
import dabo.dEvents as dEvents |
|---|
| 13 |
from dabo.dLocalize import _ |
|---|
| 14 |
_Use_Subprocess = True |
|---|
| 15 |
try: |
|---|
| 16 |
import subprocess |
|---|
| 17 |
except ImportError: |
|---|
| 18 |
_Use_Subprocess = False |
|---|
| 19 |
from dabo.lib.reportUtils import getTempFile |
|---|
| 20 |
if __name__ == "__main__": |
|---|
| 21 |
dabo.ui.loadUI("wx") |
|---|
| 22 |
|
|---|
| 23 |
|
|---|
| 24 |
class EditPageSplitter(dabo.ui.dSplitter): |
|---|
| 25 |
def __init__(self, *args, **kwargs): |
|---|
| 26 |
kwargs["createPanes"] = True |
|---|
| 27 |
super(EditPageSplitter, self).__init__(*args, **kwargs) |
|---|
| 28 |
self.ShowPanelSplitMenu = False |
|---|
| 29 |
|
|---|
| 30 |
def initProperties(self): |
|---|
| 31 |
self.Width = 250 |
|---|
| 32 |
self.Height = 200 |
|---|
| 33 |
self.MinimumPanelSize = 20 |
|---|
| 34 |
|
|---|
| 35 |
def onSashDoubleClick(self, evt): |
|---|
| 36 |
evt.stop() |
|---|
| 37 |
|
|---|
| 38 |
def onContextMenu(self, evt): |
|---|
| 39 |
evt.stop() |
|---|
| 40 |
|
|---|
| 41 |
def onSashPositionChanged(self, evt): |
|---|
| 42 |
self.Parent.updateSashPos() |
|---|
| 43 |
|
|---|
| 44 |
|
|---|
| 45 |
|
|---|
| 46 |
class EditorEditor(dabo.ui.dEditor): |
|---|
| 47 |
def addDroppedText(self, txt): |
|---|
| 48 |
curr = self.Value |
|---|
| 49 |
ss, se = self.SelectionStart, self.SelectionEnd |
|---|
| 50 |
self.Value = "%s%s%s" % (curr[:ss], txt, curr[se:]) |
|---|
| 51 |
self.SelectionStart = ss |
|---|
| 52 |
self.SelectionEnd = ss + len(txt) |
|---|
| 53 |
|
|---|
| 54 |
|
|---|
| 55 |
def _getTextSource(self): |
|---|
| 56 |
return self.Form.getTextSource() |
|---|
| 57 |
|
|---|
| 58 |
|
|---|
| 59 |
|
|---|
| 60 |
class EditorPage(dabo.ui.dPage): |
|---|
| 61 |
def initProperties(self): |
|---|
| 62 |
self.p = None |
|---|
| 63 |
self.outputText = "" |
|---|
| 64 |
self._outputSashExtra = self.Application.getUserSetting("editorform.outputSashExtra", 100) |
|---|
| 65 |
|
|---|
| 66 |
|
|---|
| 67 |
def afterInit(self): |
|---|
| 68 |
self.splitter = EditPageSplitter(self, Orientation="h") |
|---|
| 69 |
self.splitter.SashPosition = self.Height - self._outputSashExtra |
|---|
| 70 |
|
|---|
| 71 |
self.splitter.Panel1.Sizer = dabo.ui.dSizer() |
|---|
| 72 |
self.splitter.Panel2.Sizer = dabo.ui.dSizer() |
|---|
| 73 |
|
|---|
| 74 |
self.editor = EditorEditor(self.splitter.Panel1) |
|---|
| 75 |
self.editor.UseBookmarks = True |
|---|
| 76 |
self.editor.page = self |
|---|
| 77 |
self.output = dabo.ui.dEditBox(self.splitter.Panel2) |
|---|
| 78 |
self.output.ReadOnly = True |
|---|
| 79 |
|
|---|
| 80 |
self.splitter.Panel1.Sizer.append1x(self.editor) |
|---|
| 81 |
self.splitter.Panel2.Sizer.append1x(self.output) |
|---|
| 82 |
|
|---|
| 83 |
self.Sizer = dabo.ui.dSizer() |
|---|
| 84 |
self.Sizer.append1x(self.splitter) |
|---|
| 85 |
|
|---|
| 86 |
self.updateTimer = dabo.ui.callEvery(1000, self.outputUpdate) |
|---|
| 87 |
|
|---|
| 88 |
self.layout() |
|---|
| 89 |
|
|---|
| 90 |
self.editor.setFocus() |
|---|
| 91 |
self.editor.bindEvent(dEvents.TitleChanged, self.onTitleChanged) |
|---|
| 92 |
self.editor.bindEvent(dEvents.MouseRightClick, self.Form.onEditorRightClick) |
|---|
| 93 |
# Set up the file drop target |
|---|
| 94 |
self.editor.DroppedFileHandler = self.Form |
|---|
| 95 |
# Set up the text drop target |
|---|
| 96 |
### NOTE: currently we can only have text or file drops, not both |
|---|
| 97 |
#self.editor.DroppedTextHandler = self.Form |
|---|
| 98 |
# Update Hide/Show of output. Default to hidden |
|---|
| 99 |
self.showOutput(self.Application.getUserSetting("visibleOutput", False)) |
|---|
| 100 |
# Set the initial title |
|---|
| 101 |
dabo.ui.callAfter(self.onTitleChanged, None) |
|---|
| 102 |
dabo.ui.callAfter(self.splitter._setOrientation, "h") #Its weird without this, self.splitter._constructed is not true |
|---|
| 103 |
dabo.ui.callAfter(self.updateSashPos) |
|---|
| 104 |
|
|---|
| 105 |
|
|---|
| 106 |
def onResize(self, evt): |
|---|
| 107 |
self.splitter.SashPosition = self.Height - self._outputSashExtra |
|---|
| 108 |
|
|---|
| 109 |
|
|---|
| 110 |
def updateSashPos(self): |
|---|
| 111 |
if self.splitter.SashPosition > 0: |
|---|
| 112 |
self._outputSashExtra = self.Height - self.splitter.SashPosition |
|---|
| 113 |
self.Application.setUserSetting("editorform.outputSashExtra", self._outputSashExtra) |
|---|
| 114 |
|
|---|
| 115 |
|
|---|
| 116 |
def outputUpdate(self): |
|---|
| 117 |
if self and self.p: |
|---|
| 118 |
#need a nonblocking way of getting stdout and stderr |
|---|
| 119 |
self.outputText = self.outputText + self.p.stdout.read() + self.p.stderr.read() |
|---|
| 120 |
if not self.p.poll() is None: |
|---|
| 121 |
self.p = None |
|---|
| 122 |
self.output.Value = self.outputText |
|---|
| 123 |
|
|---|
| 124 |
|
|---|
| 125 |
def showOutput(self, show): |
|---|
| 126 |
self.splitter.Split = show |
|---|
| 127 |
|
|---|
| 128 |
|
|---|
| 129 |
def onTitleChanged(self, evt): |
|---|
| 130 |
title = self.editor._title |
|---|
| 131 |
self.Caption = title |
|---|
| 132 |
self.Form.onTitleChanged(evt) |
|---|
| 133 |
|
|---|
| 134 |
|
|---|
| 135 |
def onPageEnter(self, evt): |
|---|
| 136 |
self.editor.setFocus() |
|---|
| 137 |
|
|---|
| 138 |
|
|---|
| 139 |
def onPageLeave(self, evt): |
|---|
| 140 |
self.editor.setInactive() |
|---|
| 141 |
|
|---|
| 142 |
|
|---|
| 143 |
def onDestroy(self, evt): |
|---|
| 144 |
dabo.ui.callAfter(self.Form.onTitleChanged, evt) |
|---|
| 145 |
|
|---|
| 146 |
|
|---|
| 147 |
def _getPathInfo(self): |
|---|
| 148 |
try: |
|---|
| 149 |
ret = self.editor._fileName |
|---|
| 150 |
except: |
|---|
| 151 |
ret = "" |
|---|
| 152 |
return ret |
|---|
| 153 |
|
|---|
| 154 |
|
|---|
| 155 |
PathInfo = property(_getPathInfo, None, None, |
|---|
| 156 |
_("Path to the file being edited (str)") ) |
|---|
| 157 |
|
|---|
| 158 |
|
|---|
| 159 |
|
|---|
| 160 |
class EditorPageFrame(dabo.ui.dPageFrame): |
|---|
| 161 |
def beforeInit(self): |
|---|
| 162 |
self.PageClass = EditorPage |
|---|
| 163 |
|
|---|
| 164 |
|
|---|
| 165 |
def getTextSource(self): |
|---|
| 166 |
txt = [] |
|---|
| 167 |
for pg in self.Pages: |
|---|
| 168 |
txt.append(pg.editor.Value) |
|---|
| 169 |
return " ".join(txt) |
|---|
| 170 |
|
|---|
| 171 |
|
|---|
| 172 |
def checkChanges(self, closing=False): |
|---|
| 173 |
"""Cycle through the pages, and if any contain unsaved changes, |
|---|
| 174 |
ask the user if they should be saved. If they cancel, immediately |
|---|
| 175 |
stop and return False. If they say yes, save the contents. Unless |
|---|
| 176 |
they cancel, close each page. |
|---|
| 177 |
""" |
|---|
| 178 |
ret = True |
|---|
| 179 |
for pg in self.Pages[::-1]: |
|---|
| 180 |
ed = pg.editor |
|---|
| 181 |
ret = ed.checkChangesAndContinue() |
|---|
| 182 |
if not ret: |
|---|
| 183 |
break |
|---|
| 184 |
elif closing: |
|---|
| 185 |
self.PageCount -= 1 |
|---|
| 186 |
return ret |
|---|
| 187 |
|
|---|
| 188 |
|
|---|
| 189 |
def findEditor(self, pth, selectIt=False): |
|---|
| 190 |
"""Returns the editor that is editing the specified file. If there |
|---|
| 191 |
is no matching editor, returns None. If selectIt is True, makes that |
|---|
| 192 |
editor the active editor. |
|---|
| 193 |
""" |
|---|
| 194 |
ret = None |
|---|
| 195 |
for pg in self.Pages: |
|---|
| 196 |
if pg.editor._fileName == pth: |
|---|
| 197 |
ret = pg.editor |
|---|
| 198 |
if selectIt: |
|---|
| 199 |
self.SelectedPage = pg |
|---|
| 200 |
return ret |
|---|
| 201 |
|
|---|
| 202 |
|
|---|
| 203 |
def editFile(self, pth, selectIt=False): |
|---|
| 204 |
ret = self.findEditor(pth, selectIt) |
|---|
| 205 |
if ret is None: |
|---|
| 206 |
# Create a new page |
|---|
| 207 |
pg = self.getBlankPage(True) |
|---|
| 208 |
try: |
|---|
| 209 |
fileTarget = pg.editor.openFile(pth) |
|---|
| 210 |
if fileTarget: |
|---|
| 211 |
self.SelectedPage = pg |
|---|
| 212 |
ret = pg |
|---|
| 213 |
except: |
|---|
| 214 |
dabo.ui.callAfter(self.removePage, pg) |
|---|
| 215 |
ret = None |
|---|
| 216 |
return ret |
|---|
| 217 |
|
|---|
| 218 |
|
|---|
| 219 |
def getBlankPage(self, create=False): |
|---|
| 220 |
"""Returns the first page that is not associated with a file, |
|---|
| 221 |
and which has not been modified. If no such page exists, and |
|---|
| 222 |
the 'create' parameter is True, a new blank page is created |
|---|
| 223 |
and returned. Otherwise, returns None. |
|---|
| 224 |
""" |
|---|
| 225 |
ret = None |
|---|
| 226 |
for pg in self.Pages: |
|---|
| 227 |
ed = pg.editor |
|---|
| 228 |
if ed._title.strip() == ed._newFileName.strip(): |
|---|
| 229 |
ret = pg |
|---|
| 230 |
break |
|---|
| 231 |
if ret is None and create: |
|---|
| 232 |
self.PageCount += 1 |
|---|
| 233 |
ret = self.Pages[-1] |
|---|
| 234 |
return ret |
|---|
| 235 |
|
|---|
| 236 |
|
|---|
| 237 |
def closeEditor(self, ed=None, checkChanges=True): |
|---|
| 238 |
if ed is None: |
|---|
| 239 |
ed = self.SelectedPage.editor |
|---|
| 240 |
if checkChanges: |
|---|
| 241 |
ret = ed.checkChangesAndContinue() |
|---|
| 242 |
else: |
|---|
| 243 |
ret = True |
|---|
| 244 |
if ret is not False: |
|---|
| 245 |
self.removePage(ed.page) |
|---|
| 246 |
return ret |
|---|
| 247 |
|
|---|
| 248 |
|
|---|
| 249 |
def newEditor(self): |
|---|
| 250 |
ret = self.getBlankPage(True) |
|---|
| 251 |
self.SelectedPage = ret |
|---|
| 252 |
return ret |
|---|
| 253 |
|
|---|
| 254 |
|
|---|
| 255 |
def selectByCaption(self, cap): |
|---|
| 256 |
pgs = [pg for pg in self.Pages |
|---|
| 257 |
if pg.Caption == cap] |
|---|
| 258 |
if pgs: |
|---|
| 259 |
pg = pgs[0] |
|---|
| 260 |
else: |
|---|
| 261 |
dabo.errorLog.write(_("No matching page for %s") % cap) |
|---|
| 262 |
return |
|---|
| 263 |
self.SelectedPage = pg |
|---|
| 264 |
pg.editor.setFocus() |
|---|
| 265 |
|
|---|
| 266 |
|
|---|
| 267 |
def edFocus(self): |
|---|
| 268 |
self.SelectedPage.editor.setFocus() |
|---|
| 269 |
|
|---|
| 270 |
|
|---|
| 271 |
def _getCurrentEditor(self): |
|---|
| 272 |
try: |
|---|
| 273 |
return self.SelectedPage.editor |
|---|
| 274 |
except: |
|---|
| 275 |
return None |
|---|
| 276 |
|
|---|
| 277 |
|
|---|
| 278 |
def _getTitle(self): |
|---|
| 279 |
sp = self.SelectedPage |
|---|
| 280 |
try: |
|---|
| 281 |
ret = sp.PathInfo |
|---|
| 282 |
if sp.editor.Modified: |
|---|
| 283 |
ret += " *" |
|---|
| 284 |
except: |
|---|
| 285 |
ret = "" |
|---|
| 286 |
return ret |
|---|
| 287 |
|
|---|
| 288 |
|
|---|
| 289 |
CurrentEditor = property(_getCurrentEditor, None, None, |
|---|
| 290 |
_("References the currently active editor (dEditor)")) |
|---|
| 291 |
|
|---|
| 292 |
Title = property(_getTitle, None, None, |
|---|
| 293 |
_("Title of the active page (str)") ) |
|---|
| 294 |
|
|---|
| 295 |
|
|---|
| 296 |
|
|---|
| 297 |
class EditorForm(dabo.ui.dForm): |
|---|
| 298 |
def __init__(self, *args, **kwargs): |
|---|
| 299 |
super(EditorForm, self).__init__(*args, **kwargs) |
|---|
| 300 |
|
|---|
| 301 |
|
|---|
| 302 |
def afterInit(self): |
|---|
| 303 |
# Set up the file drop target |
|---|
| 304 |
self.DroppedFileHandler = self |
|---|
| 305 |
pnl = dabo.ui.dPanel(self) |
|---|
| 306 |
self.Sizer.append1x(pnl) |
|---|
| 307 |
pnl.Sizer = dabo.ui.dSizer("v") |
|---|
| 308 |
self._lastPath = self.Application.getUserSetting("lastPath", os.getcwd()) |
|---|
| 309 |
super(EditorForm, self).afterInit() |
|---|
| 310 |
self.Caption = _("Dabo Editor") |
|---|
| 311 |
self.funcButton = dabo.ui.dImage(pnl, ScaleMode="Clip", Size=(22,22)) |
|---|
| 312 |
self.funcButton.Picture = dabo.ui.imageFromData(funcButtonData()) |
|---|
| 313 |
self.funcButton.bindEvent(dEvents.MouseLeftDown, self.onFuncButton) |
|---|
| 314 |
self.bmkButton = dabo.ui.dImage(pnl, ScaleMode="Clip", Size=(22,22)) |
|---|
| 315 |
self.bmkButton.Picture = dabo.ui.imageFromData(bmkButtonData()) |
|---|
| 316 |
self.bmkButton.bindEvent(dEvents.MouseLeftDown, self.onBmkButton) |
|---|
| 317 |
|
|---|
| 318 |
self.prntButton = dabo.ui.dBitmapButton(pnl, Size=(22,22)) |
|---|
| 319 |
self.prntButton.Picture = "print" |
|---|
| 320 |
self.prntButton.bindEvent(dEvents.Hit, self.onPrint) |
|---|
| 321 |
|
|---|
| 322 |
self.lexSelector = dabo.ui.dDropdownList(pnl, ValueMode="String") |
|---|
| 323 |
self.lexSelector.bindEvent(dEvents.Hit, self.onLexSelect) |
|---|
| 324 |
|
|---|
| 325 |
btnSizer = dabo.ui.dSizer("H", DefaultSpacing=4) |
|---|
| 326 |
btnSizer.append(self.funcButton) |
|---|
| 327 |
btnSizer.append(self.bmkButton) |
|---|
| 328 |
btnSizer.append(self.prntButton) |
|---|
| 329 |
btnSizer.appendSpacer(10, proportion=1) |
|---|
| 330 |
lbl = dabo.ui.dLabel(pnl, Caption=_("Language:")) |
|---|
| 331 |
if not self.Application.Platform.lower() == "win": |
|---|
| 332 |
lbl.FontSize -= 2 |
|---|
| 333 |
self.lexSelector.FontSize -= 2 |
|---|
| 334 |
btnSizer.append(lbl, valign="middle") |
|---|
| 335 |
btnSizer.append(self.lexSelector, valign="middle") |
|---|
| 336 |
|
|---|
| 337 |
pnl.Sizer.append(btnSizer, "x", border=4) |
|---|
| 338 |
|
|---|
| 339 |
self.pgfEditor = EditorPageFrame(pnl, TabPosition="Top") |
|---|
| 340 |
self.pgfEditor.bindEvent(dEvents.PageChanged, self.onEditorPageChanged) |
|---|
| 341 |
pnl.Sizer.append1x(self.pgfEditor) |
|---|
| 342 |
self.layout() |
|---|
| 343 |
self.fillMenu() |
|---|
| 344 |
dabo.ui.callAfter(self.showPage, 0) |
|---|
| 345 |
|
|---|
| 346 |
|
|---|
| 347 |
def showPage(self, pg): |
|---|
| 348 |
"""Shows the specified page, if it exists.""" |
|---|
| 349 |
try: |
|---|
| 350 |
self.pgfEditor.SelectedPage = pg |
|---|
| 351 |
self.pgfEditor.edFocus() |
|---|
| 352 |
except: |
|---|
| 353 |
pass |
|---|
| 354 |
|
|---|
| 355 |
|
|---|
| 356 |
def onPrint(self, evt): |
|---|
| 357 |
self.CurrentEditor.onPrint() |
|---|
| 358 |
|
|---|
| 359 |
|
|---|
| 360 |
def onActivate(self, evt): |
|---|
| 361 |
"""Check the files to see if any have been updated on disk.""" |
|---|
| 362 |
self.checkForUpdatedFiles() |
|---|
| 363 |
|
|---|
| 364 |
|
|---|
| 365 |
def checkForUpdatedFiles(self): |
|---|
| 366 |
"""If any file being edited has not been modified, and there is a more recent version |
|---|
| 367 |
on disk, update the file with the version on disk. |
|---|
| 368 |
""" |
|---|
| 369 |
for pg in self.pgfEditor.Pages: |
|---|
| 370 |
ed = pg.editor |
|---|
| 371 |
if not ed.isChanged() and ed.checkForDiskUpdate(): |
|---|
| 372 |
selpos = ed.SelectionPosition |
|---|
| 373 |
ed.openFile(ed._fileName) |
|---|
| 374 |
ed.SelectionPosition = selpos |
|---|
| 375 |
|
|---|
| 376 |
|
|---|
| 377 |
def onLexSelect(self, evt): |
|---|
| 378 |
self.CurrentEditor.Language = self.lexSelector.Value |
|---|
| 379 |
|
|---|
| 380 |
|
|---|
| 381 |
def onFuncButton(self, evt): |
|---|
| 382 |
evt.stop() |
|---|
| 383 |
flist = self.CurrentEditor.getFunctionList() |
|---|
| 384 |
pop = dabo.ui.dMenu() |
|---|
| 385 |
for nm, pos, iscls in flist: |
|---|
| 386 |
prompt = nm |
|---|
| 387 |
if not iscls: |
|---|
| 388 |
prompt = " - %s" % nm |
|---|
| 389 |
itm = pop.append(prompt, OnHit=self.onFunctionPop) |
|---|
| 390 |
itm.textPosition = pos |
|---|
| 391 |
self.showContextMenu(pop) |
|---|
| 392 |
del pop |
|---|
| 393 |
|
|---|
| 394 |
|
|---|
| 395 |
def onFunctionPop(self, evt): |
|---|
| 396 |
ed = self.CurrentEditor |
|---|
| 397 |
pos = evt.menuItem.textPosition |
|---|
| 398 |
currLine = ed.LineNumber |
|---|
| 399 |
newLine = ed.getLineFromPosition(pos) |
|---|
| 400 |
if newLine > currLine: |
|---|
| 401 |
ed.moveToEnd() |
|---|
| 402 |
ed.ensureLineVisible(newLine) |
|---|
| 403 |
ed.LineNumber = newLine |
|---|
| 404 |
nextLinePos = ed.getPositionFromLine(newLine+1) |
|---|
| 405 |
ed.SelectionPosition = (pos, nextLinePos-1) |
|---|
| 406 |
|
|---|
| 407 |
|
|---|
| 408 |
def onIdle(self, evt): |
|---|
| 409 |
ed = self.CurrentEditor |
|---|
| 410 |
if ed: |
|---|
| 411 |
self.StatusText = "Line: %s, Col: %s" % (ed.LineNumber, ed.Column) |
|---|
| 412 |
|
|---|
| 413 |
|
|---|
| 414 |
def getTextSource(self): |
|---|
| 415 |
return self.pgfEditor.getTextSource() |
|---|
| 416 |
|
|---|
| 417 |
|
|---|
| 418 |
def onEditorRightClick(self, evt): |
|---|
| 419 |
ed = self.CurrentEditor |
|---|
| 420 |
pos = evt.mousePosition |
|---|
| 421 |
pp = ed.getPositionFromXY(pos) |
|---|
| 422 |
if pp < 0: |
|---|
| 423 |
# They clicked outside of the text area of the line. Find |
|---|
| 424 |
# a position just to the right of the margin |
|---|
| 425 |
lpos = ed.getMarginWidth() |
|---|
| 426 |
pp = ed.getPositionFromXY(lpos, pos[1]) |
|---|
| 427 |
if pp < 0: |
|---|
| 428 |
# This is a totally blank line. Nothing can be done |
|---|
| 429 |
return |
|---|
| 430 |
ln = ed.getLineFromPosition(pp) |
|---|
| 431 |
ed.LineNumber = ln |
|---|
| 432 |
self.onBmkButton(evt) |
|---|
| 433 |
|
|---|
| 434 |
|
|---|
| 435 |
def onBmkButton(self, evt): |
|---|
| 436 |
evt.stop() |
|---|
| 437 |
ed = self.CurrentEditor |
|---|
| 438 |
bmkList = ed.getBookmarkList() |
|---|
| 439 |
pop = dabo.ui.dMenu() |
|---|
| 440 |
currBmk = ed.getCurrentLineBookmark() |
|---|
| 441 |
if not currBmk: |
|---|
| 442 |
pop.append(_("Set Bookmark..."), OnHit=self.onSetBmk) |
|---|
| 443 |
else: |
|---|
| 444 |
pop.append(_("Clear Bookmark..."), OnHit=self.onClearBmk) |
|---|
| 445 |
if bmkList: |
|---|
| 446 |
pop.append(_("Clear All Bookmarks"), OnHit=self.onClearAllBmk) |
|---|
| 447 |
pop.appendSeparator() |
|---|
| 448 |
for nm in bmkList: |
|---|
| 449 |
itm = pop.append(nm, OnHit=self.onBookmarkPop) |
|---|
| 450 |
self.showContextMenu(pop) |
|---|
| 451 |
del pop |
|---|
| 452 |
|
|---|
| 453 |
|
|---|
| 454 |
def onBookmarkPop(self, evt): |
|---|
| 455 |
"""Navigate to the chosen bookmark.""" |
|---|
| 456 |
self.CurrentEditor.findBookmark(evt.prompt) |
|---|
| 457 |
|
|---|
| 458 |
|
|---|
| 459 |
def onSetBmk(self, evt): |
|---|
| 460 |
"""Need to ask the user for a name for this bookmark.""" |
|---|
| 461 |
nm = dabo.ui.getString(message=_("Name for this bookmark:"), |
|---|
| 462 |
caption=_("New Bookmark")) |
|---|
| 463 |
if not nm: |
|---|
| 464 |
# User canceled |
|---|
| 465 |
return |
|---|
| 466 |
ed = self.CurrentEditor |
|---|
| 467 |
if nm in ed.getBookmarkList(): |
|---|
| 468 |
msg = _("There is already a bookmark named '%s'. Creating a new bookmark " |
|---|
| 469 |
"with the same name will delete the old one. Are you sure you want " |
|---|
| 470 |
"to do this?") % nm |
|---|
| 471 |
if not dabo.ui.areYouSure(message=msg, title=_("Duplicate Name"), |
|---|
| 472 |
defaultNo=True, cancelButton=False): |
|---|
| 473 |
return |
|---|
| 474 |
self.CurrentEditor.setBookmark(nm) |
|---|
| 475 |
|
|---|
| 476 |
|
|---|
| 477 |
def onClearBmk(self, evt): |
|---|
| 478 |
"""Clear the current bookmark.""" |
|---|
| 479 |
ed = self.CurrentEditor |
|---|
| 480 |
bmk = ed.getCurrentLineBookmark() |
|---|
| 481 |
if bmk: |
|---|
| 482 |
ed.clearBookmark(bmk) |
|---|
| 483 |
|
|---|
| 484 |
|
|---|
| 485 |
def onClearAllBmk(self, evt): |
|---|
| 486 |
"""Remove all the bookmarks.""" |
|---|
| 487 |
self.CurrentEditor.clearAllBookmarks() |
|---|
| 488 |
|
|---|
| 489 |
|
|---|
| 490 |
def onEditorPageChanged(self, evt): |
|---|
| 491 |
self.checkForUpdatedFiles() |
|---|
| 492 |
self.onTitleChanged(evt) |
|---|
| 493 |
self.setCheckedMenus() |
|---|
| 494 |
self.updateLex() |
|---|
| 495 |
|
|---|
| 496 |
|
|---|
| 497 |
def updateLex(self): |
|---|
| 498 |
if self.CurrentEditor: |
|---|
| 499 |
if not self.lexSelector.Choices: |
|---|
| 500 |
self.lexSelector.Choices = self.CurrentEditor.getAvailableLanguages() |
|---|
| 501 |
self.lexSelector.Value = self.CurrentEditor.Language |
|---|
| 502 |
|
|---|
| 503 |
|
|---|
| 504 |
def setCheckedMenus(self): |
|---|
| 505 |
ed = self.CurrentEditor |
|---|
| 506 |
if ed is None: |
|---|
| 507 |
self._autoAutoItem.Checked = self._wrapItem.Checked = self._synColorItem.Checked = False |
|---|
| 508 |
else: |
|---|
| 509 |
self._autoAutoItem.Checked = ed.AutoAutoComplete |
|---|
| 510 |
self._wrapItem.Checked = ed.WordWrap |
|---|
| 511 |
self._synColorItem.Checked = ed.SyntaxColoring |
|---|
| 512 |
self._showOutItem.Checked = self.Application.getUserSetting("visibleOutput", False) |
|---|
| 513 |
|
|---|
| 514 |
|
|---|
| 515 |
def beforeClose(self, evt): |
|---|
| 516 |
ret= self.pgfEditor.checkChanges(closing=True) |
|---|
| 517 |
return ret |
|---|
| 518 |
|
|---|
| 519 |
|
|---|
| 520 |
def processDroppedFiles(self, filelist): |
|---|
| 521 |
"""Try to open each file up in an editor tab.""" |
|---|
| 522 |
self.openRecursively(filelist) |
|---|
| 523 |
|
|---|
| 524 |
|
|---|
| 525 |
def processDroppedText(self, txt): |
|---|
| 526 |
"""Add the text to the current editor.""" |
|---|
| 527 |
self.CurrentEditor.addDroppedText(txt) |
|---|
| 528 |
|
|---|
| 529 |
|
|---|
| 530 |
def openRecursively(self, filelist): |
|---|
| 531 |
if isinstance(filelist, basestring): |
|---|
| 532 |
# Individual file passed |
|---|
| 533 |
filelist = [filelist] |
|---|
| 534 |
for ff in filelist: |
|---|
| 535 |
if os.path.isdir(ff): |
|---|
| 536 |
for fname in os.listdir(ff): |
|---|
| 537 |
self.openRecursively(os.path.join(ff, fname)) |
|---|
| 538 |
else: |
|---|
| 539 |
if os.path.isfile(ff): |
|---|
| 540 |
self.openFile(ff, justReportErrors=True) |
|---|
| 541 |
|
|---|
| 542 |
|
|---|
| 543 |
def onDocumentationHint(self, evt): |
|---|
| 544 |
# Eventually, a separate IDE window can optionally display help contents |
|---|
| 545 |
# for the object. For now, just print the longdoc to the infolog. |
|---|
| 546 |
dabo.infoLog.write(_("Documentation Hint received:\n\n%s") % evt.EventData["longDoc"]) |
|---|
| 547 |
|
|---|
| 548 |
|
|---|
| 549 |
def onTitleChanged(self, evt): |
|---|
| 550 |
if self and self.pgfEditor: |
|---|
| 551 |
self.Caption = _("Dabo Editor: %s") % self.pgfEditor.Title |
|---|
|
|---|