filelist.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. "idlelib.filelist"
  2. import os
  3. from tkinter import messagebox
  4. class FileList:
  5. # N.B. this import overridden in PyShellFileList.
  6. from idlelib.editor import EditorWindow
  7. def __init__(self, root):
  8. self.root = root
  9. self.dict = {}
  10. self.inversedict = {}
  11. self.vars = {} # For EditorWindow.getrawvar (shared Tcl variables)
  12. def open(self, filename, action=None):
  13. assert filename
  14. filename = self.canonize(filename)
  15. if os.path.isdir(filename):
  16. # This can happen when bad filename is passed on command line:
  17. messagebox.showerror(
  18. "File Error",
  19. f"{filename!r} is a directory.",
  20. master=self.root)
  21. return None
  22. key = os.path.normcase(filename)
  23. if key in self.dict:
  24. edit = self.dict[key]
  25. edit.top.wakeup()
  26. return edit
  27. if action:
  28. # Don't create window, perform 'action', e.g. open in same window
  29. return action(filename)
  30. else:
  31. edit = self.EditorWindow(self, filename, key)
  32. if edit.good_load:
  33. return edit
  34. else:
  35. edit._close()
  36. return None
  37. def gotofileline(self, filename, lineno=None):
  38. edit = self.open(filename)
  39. if edit is not None and lineno is not None:
  40. edit.gotoline(lineno)
  41. def new(self, filename=None):
  42. return self.EditorWindow(self, filename)
  43. def close_all_callback(self, *args, **kwds):
  44. for edit in list(self.inversedict):
  45. reply = edit.close()
  46. if reply == "cancel":
  47. break
  48. return "break"
  49. def unregister_maybe_terminate(self, edit):
  50. try:
  51. key = self.inversedict[edit]
  52. except KeyError:
  53. print("Don't know this EditorWindow object. (close)")
  54. return
  55. if key:
  56. del self.dict[key]
  57. del self.inversedict[edit]
  58. if not self.inversedict:
  59. self.root.quit()
  60. def filename_changed_edit(self, edit):
  61. edit.saved_change_hook()
  62. try:
  63. key = self.inversedict[edit]
  64. except KeyError:
  65. print("Don't know this EditorWindow object. (rename)")
  66. return
  67. filename = edit.io.filename
  68. if not filename:
  69. if key:
  70. del self.dict[key]
  71. self.inversedict[edit] = None
  72. return
  73. filename = self.canonize(filename)
  74. newkey = os.path.normcase(filename)
  75. if newkey == key:
  76. return
  77. if newkey in self.dict:
  78. conflict = self.dict[newkey]
  79. self.inversedict[conflict] = None
  80. messagebox.showerror(
  81. "Name Conflict",
  82. f"You now have multiple edit windows open for {filename!r}",
  83. master=self.root)
  84. self.dict[newkey] = edit
  85. self.inversedict[edit] = newkey
  86. if key:
  87. try:
  88. del self.dict[key]
  89. except KeyError:
  90. pass
  91. def canonize(self, filename):
  92. if not os.path.isabs(filename):
  93. try:
  94. pwd = os.getcwd()
  95. except OSError:
  96. pass
  97. else:
  98. filename = os.path.join(pwd, filename)
  99. return os.path.normpath(filename)
  100. def _test(): # TODO check and convert to htest
  101. from tkinter import Tk
  102. from idlelib.editor import fixwordbreaks
  103. from idlelib.run import fix_scaling
  104. root = Tk()
  105. fix_scaling(root)
  106. fixwordbreaks(root)
  107. root.withdraw()
  108. flist = FileList(root)
  109. flist.new()
  110. if flist.inversedict:
  111. root.mainloop()
  112. if __name__ == '__main__':
  113. from unittest import main
  114. main('idlelib.idle_test.test_filelist', verbosity=2)
  115. # _test()