configure.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. import logging
  2. from PyQt5.QtWidgets import *
  3. from PyQt5.QtGui import *
  4. from PyQt5.QtCore import *
  5. from protolib.gui_utils.pyqt5_messageboxes import show_question_messagebox
  6. from windows.to_protolib.text_input import ask_text
  7. logger = logging.getLogger(__name__)
  8. class ConfigureWindow(QDialog):
  9. updating = False
  10. def __init__(self, file_browser):
  11. super().__init__()
  12. # Initialize tab screen
  13. self.tabs = QTabWidget()
  14. self.typing_tabs = QTabWidget()
  15. self.typing_types_tab = QWidget()
  16. self.typing_mimetypes_tab = QWidget()
  17. self.file_browser = file_browser
  18. #region typing types tab
  19. types_tab_layout = QVBoxLayout()
  20. self.file_type_select = QComboBox()
  21. sorted_file_types = self.typing_types_refresh_select()
  22. self.file_type_select.activated.connect(self.file_type_select_updated)
  23. types_tab_layout.addWidget(self.file_type_select)
  24. types_tab_type_controls_layout = QHBoxLayout()
  25. self.mimetypes_type_remove = QPushButton('Remove File Type')
  26. self.mimetypes_type_remove.clicked.connect(self.typing_types_remove_type)
  27. types_tab_type_controls_layout.addWidget(self.mimetypes_type_remove)
  28. self.mimetypes_type_add = QPushButton('Add File Type')
  29. self.mimetypes_type_add.clicked.connect(self.typing_types_add_type)
  30. types_tab_type_controls_layout.addWidget(self.mimetypes_type_add)
  31. types_tab_layout.addLayout(types_tab_type_controls_layout)
  32. types_tab_viewer_layout = QHBoxLayout()
  33. self.file_type_viewer_label = QLabel('Viewer')
  34. types_tab_viewer_layout.addWidget(self.file_type_viewer_label)
  35. self.file_type_viewer = QLineEdit(self.file_browser.config['typing']['types'][sorted_file_types[0]]['viewer'] if sorted_file_types else '')
  36. self.file_type_viewer.editingFinished.connect(self.file_type_viewer_changed)
  37. self.file_type_viewer.setPlaceholderText('Enter type viewer command here')
  38. types_tab_viewer_layout.addWidget(self.file_type_viewer)
  39. types_tab_layout.addLayout(types_tab_viewer_layout)
  40. types_tab_mimetype_layout = QHBoxLayout()
  41. self.mimetypes_mimetype_label = QLabel('Mime Types')
  42. types_tab_mimetype_layout.addWidget(self.mimetypes_mimetype_label)
  43. self.mimetypes_edit = QComboBox()
  44. self.mimetypes_edit.editTextChanged.connect(self.mimetype_assoc_edited)
  45. types_tab_mimetype_layout.addWidget(self.mimetypes_edit)
  46. types_tab_layout.addLayout(types_tab_mimetype_layout)
  47. types_tab_mimetype_controls_layout = QHBoxLayout()
  48. self.typing_types_mimetype_remove = QPushButton('Remove Mime Type')
  49. self.typing_types_mimetype_remove.clicked.connect(self.typing_types_remove_mimetype)
  50. types_tab_mimetype_controls_layout.addWidget(self.typing_types_mimetype_remove)
  51. self.typing_types_mimetype_add = QPushButton('Add Mime Type')
  52. self.typing_types_mimetype_add.clicked.connect(self.typing_types_add_mimetype)
  53. types_tab_mimetype_controls_layout.addWidget(self.typing_types_mimetype_add)
  54. types_tab_layout.addLayout(types_tab_mimetype_controls_layout)
  55. self.typing_types_tab.setLayout(types_tab_layout)
  56. self.file_type_select_updated()
  57. #endregion
  58. #region typing mimetypes tab
  59. mimetypes_tab_layout = QVBoxLayout()
  60. self.mimetype_select = QComboBox()
  61. sorted_mimetypes = self.typing_mimetypes_refresh_select()
  62. self.mimetype_select.activated.connect(self.mimetype_select_updated)
  63. mimetypes_tab_layout.addWidget(self.mimetype_select)
  64. mimetypes_tab_type_controls_layout = QHBoxLayout()
  65. self.mimetypes_type_remove = QPushButton('Remove Mime Type')
  66. self.mimetypes_type_remove.clicked.connect(self.typing_mimetypes_remove_type)
  67. mimetypes_tab_type_controls_layout.addWidget(self.mimetypes_type_remove)
  68. self.mimetypes_type_add = QPushButton('Add Mime Type')
  69. self.mimetypes_type_add.clicked.connect(self.typing_mimetypes_add_type)
  70. mimetypes_tab_type_controls_layout.addWidget(self.mimetypes_type_add)
  71. mimetypes_tab_layout.addLayout(mimetypes_tab_type_controls_layout)
  72. mimetypes_tab_name_layout = QHBoxLayout()
  73. self.mimetype_name_label = QLabel('Name')
  74. mimetypes_tab_name_layout.addWidget(self.mimetype_name_label)
  75. self.mimetype_name = QLineEdit(self.file_browser.config['typing']['mimetypes'][sorted_mimetypes[0]]['name'] if sorted_mimetypes else '')
  76. self.mimetype_name.editingFinished.connect(self.mimetype_name_changed)
  77. self.mimetype_name.setPlaceholderText('Enter mime type name here')
  78. mimetypes_tab_name_layout.addWidget(self.mimetype_name)
  79. mimetypes_tab_layout.addLayout(mimetypes_tab_name_layout)
  80. mimetypes_tab_mimetype_layout = QHBoxLayout()
  81. self.mimetypes_mimetype_label = QLabel('Patterns')
  82. mimetypes_tab_mimetype_layout.addWidget(self.mimetypes_mimetype_label)
  83. self.mimetypes_select = QComboBox()
  84. self.mimetypes_select.editTextChanged.connect(self.mimetype_pattern_edited)
  85. mimes = self.file_browser.config['typing']['mimetypes'][sorted_mimetypes[0]]['patterns']
  86. self.mimetypes_select.addItems(sorted(mimes))
  87. mimetypes_tab_mimetype_layout.addWidget(self.mimetypes_select)
  88. mimetypes_tab_layout.addLayout(mimetypes_tab_mimetype_layout)
  89. mimetypes_tab_mimetype_controls_layout = QHBoxLayout()
  90. self.typing_mimetypes_mimetype_remove = QPushButton('Remove Pattern')
  91. self.typing_mimetypes_mimetype_remove.clicked.connect(self.typing_mimetypes_remove_mimetype)
  92. mimetypes_tab_mimetype_controls_layout.addWidget(self.typing_mimetypes_mimetype_remove)
  93. self.typing_mimetypes_mimetype_add = QPushButton('Add Pattern')
  94. self.typing_mimetypes_mimetype_add.clicked.connect(self.typing_mimetypes_add_mimetype)
  95. mimetypes_tab_mimetype_controls_layout.addWidget(self.typing_mimetypes_mimetype_add)
  96. mimetypes_tab_layout.addLayout(mimetypes_tab_mimetype_controls_layout)
  97. self.typing_mimetypes_tab.setLayout(mimetypes_tab_layout)
  98. self.mimetype_select_updated()
  99. #endregion
  100. # Add tabs
  101. self.tabs.addTab(self.typing_tabs,"File Typing")
  102. self.typing_tabs.addTab(self.typing_types_tab,"Types")
  103. self.typing_tabs.addTab(self.typing_mimetypes_tab,"Mime Types")
  104. # Add tabs to widget
  105. layout = QVBoxLayout()
  106. self.setLayout(layout)
  107. self.layout().addWidget(self.tabs)
  108. def file_type_select_updated(self):
  109. self.updating = True
  110. index = self.file_type_select.currentIndex()
  111. key = self.file_type_select.itemText(index)
  112. viewer = self.file_browser.config['typing']['types'][key]['viewer']
  113. self.file_type_viewer.setText(viewer if viewer else '')
  114. mimes = self.file_browser.config['typing']['types'][key]['mimetypes']
  115. self.mimetypes_edit.clear()
  116. if len(mimes) > 0:
  117. self.mimetypes_edit.addItems(sorted(mimes))
  118. self.mimetypes_edit.setEditable(True)
  119. else:
  120. self.mimetypes_edit.setEditable(False)
  121. self.updating = False
  122. def file_type_viewer_changed(self):
  123. if self.updating:
  124. return
  125. index = self.file_type_select.currentIndex()
  126. key = self.file_type_select.itemText(index)
  127. viewer = self.file_type_viewer.text()
  128. self.file_browser.config['typing']['types'][key]['viewer'] = viewer if viewer else None
  129. def mimetype_assoc_edited(self, text):
  130. key_index = self.file_type_select.currentIndex()
  131. key = self.file_type_select.itemText(key_index)
  132. index = self.mimetypes_edit.currentIndex()
  133. if not text:
  134. return
  135. self.file_browser.config['typing']['types'][key]['mimetypes'][index] = text
  136. def typing_types_remove_mimetype(self):
  137. response = show_question_messagebox('Are you sure?', 'You are about to permanently delete a mime type association. This can\'t be undone')
  138. if not response:
  139. return
  140. index = self.mimetypes_edit.currentIndex()
  141. self.mimetypes_edit.removeItem(index)
  142. self.mimetype_assoc_edited(None)
  143. def typing_types_add_mimetype(self):
  144. text = ask_text('Enter mime type', 'Use the following field to enter the mime type you would like to add', 'Enter mime type here')
  145. if not text:
  146. return
  147. self.mimetypes_edit.addItem(text)
  148. self.mimetype_assoc_edited(text)
  149. self.file_type_select_updated()
  150. def typing_types_remove_type(self):
  151. response = show_question_messagebox('Are you sure?', 'You are about to permanently delete a file type record. This can\'t be undone')
  152. if not response:
  153. return
  154. def typing_types_add_type(self):
  155. text = ask_text('Enter file type name', 'Use the following field to enter the name of the file type you would like to add', 'Enter file type name here')
  156. if not text:
  157. return
  158. record = {
  159. 'mimetypes': [],
  160. 'viewer': None
  161. }
  162. self.file_browser.config['typing']['types'][text] = record
  163. self.typing_types_refresh_select()
  164. self.file_type_select_updated()
  165. def typing_types_refresh_select(self):
  166. self.file_type_select.clear()
  167. sorted_file_types = sorted(self.file_browser.config['typing']['types'].keys())
  168. self.file_type_select.addItems(sorted_file_types)
  169. return sorted_file_types
  170. def mimetype_select_updated(self):
  171. self.updating = True
  172. index = self.mimetype_select.currentIndex()
  173. key = self.mimetype_select.itemText(index)
  174. name = self.file_browser.config['typing']['mimetypes'][key]['name']
  175. self.mimetype_name.setText(name if name else '')
  176. mimes = self.file_browser.config['typing']['mimetypes'][key]['patterns']
  177. self.mimetypes_select.clear()
  178. if len(mimes) > 0:
  179. self.mimetypes_select.addItems(sorted(mimes))
  180. self.mimetypes_select.setEditable(True)
  181. else:
  182. self.mimetypes_select.setEditable(False)
  183. self.updating = False
  184. def mimetype_name_changed(self):
  185. if self.updating:
  186. return
  187. index = self.mimetype_select.currentIndex()
  188. key = self.mimetype_select.itemText(index)
  189. viewer = self.mimetype_viewer.text()
  190. self.file_browser.config['typing']['mimetypes'][key]['viewer'] = viewer if viewer else None
  191. def mimetype_name_edited(self, text):
  192. key_index = self.mimetype_select.currentIndex()
  193. key = self.mimetype_select.itemText(key_index)
  194. index = self.mimetypes_select.currentIndex()
  195. if not text:
  196. return
  197. self.file_browser.config['typing']['mimetypes'][key]['mimetypes'][index] = text
  198. def typing_mimetypes_remove_mimetype(self):
  199. response = show_question_messagebox('Are you sure?', 'You are about to permanently delete a mime type association. This can\'t be undone')
  200. if not response:
  201. return
  202. index = self.mimetypes_select.currentIndex()
  203. self.mimetypes_select.removeItem(index)
  204. self.mimetype_pattern_edited(None)
  205. def typing_mimetypes_add_mimetype(self):
  206. text = ask_text('Enter mime type', 'Use the following field to enter the mime type you would like to add', 'Enter mime type here')
  207. if not text:
  208. return
  209. self.mimetypes_select.addItem(text)
  210. self.mimetype_pattern_edited(text)
  211. self.mimetype_select_updated()
  212. def typing_mimetypes_remove_type(self):
  213. response = show_question_messagebox('Are you sure?', 'You are about to permanently delete a file type record. This can\'t be undone')
  214. if not response:
  215. return
  216. def typing_mimetypes_add_type(self):
  217. text = ask_text('Enter file type name', 'Use the following field to enter the name of the file type you would like to add', 'Enter file type name here')
  218. if not text:
  219. return
  220. record = {
  221. 'mimetypes': [],
  222. 'viewer': None
  223. }
  224. self.file_browser.config['typing']['mimetypes'][text] = record
  225. self.typing_mimetypes_refresh_select()
  226. self.mimetype_select_updated()
  227. def typing_mimetypes_refresh_select(self):
  228. self.mimetype_select.clear()
  229. sorted_mimetypes = sorted(self.file_browser.config['typing']['mimetypes'].keys())
  230. self.mimetype_select.addItems(sorted_mimetypes)
  231. return sorted_mimetypes
  232. def mimetype_pattern_edited(self, text):
  233. key_index = self.file_type_select.currentIndex()
  234. key = self.file_type_select.itemText(key_index)
  235. index = self.mimetypes_select.currentIndex()
  236. if not text:
  237. return
  238. self.file_browser.config['typing']['mimetypes'][key]['patterns'][index] = text
  239. # To ProtoLib
  240. # https://stackoverflow.com/questions/7479915/getting-all-items-of-qcombobox-pyqt4-python
  241. def combo_box_all_items(widget: QComboBox):
  242. return [widget.itemText(i) for i in range(widget.count())]