Advertisement
Guest User

Untitled

a guest
Jan 28th, 2015
234
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.97 KB | None | 0 0
  1. # -*- coding: utf-8 -*-
  2. #! /usr/bin/env python
  3.  
  4. '''
  5. Python Manager
  6. ==============
  7. GUI tool for managing modules and packages based on reimport: Full featured reload for Python.
  8. '''
  9.  
  10. import os
  11. import reimport
  12. import sys
  13. import time
  14. import shiboken
  15. from itertools import groupby
  16. from PySide import QtGui, QtCore
  17.  
  18.  
  19. PARENT_APPLICATION = None
  20.  
  21. if 'Maya' in sys.executable:
  22.  
  23. from maya.OpenMayaUI.MQtUtil import mainWindow
  24. maya_window = shiboken.wrapInstance(long(mainWindow()), QtGui.QWidget)
  25.  
  26. PARENT_APPLICATION = maya_window
  27.  
  28. elif 'Nuke' in sys.executable:
  29.  
  30. PARENT_APPLICATION = 'Nuke' # Replace with proper nuke qwidget
  31.  
  32.  
  33. STYLE = '''
  34. QLabel#Header{
  35. background: rgb(235, 235, 235);
  36. padding: 15px;
  37. font: 12pt;
  38. }
  39. QListWidget{
  40. background: rgb(215, 215, 215);
  41. outline: none;
  42. }
  43. QListWidget::item{
  44. background: rgb(215, 215, 215);
  45. border-top: 1px solid rgb(230, 230, 230);
  46. border-bottom: 1px solid rgb(200, 200, 200);
  47. outline: none;
  48. }
  49. QListWidget::item:selected{
  50. color: rgb(235, 235, 235);
  51. background: rgb(100, 100, 215);
  52. border-top: 1px solid rgb(115, 115, 230);
  53. border-bottom: 1px solid rgb(85, 85, 200)
  54. }
  55. QPushButton{
  56. border: 0;
  57. color: rgb(235, 235, 235);
  58. background: rgb(200, 20, 20);
  59. font-weight: 400;
  60. border-radius: 8px;
  61. }
  62. QPushButton:pressed{
  63. border: 0;
  64. padding: 0;
  65. margin: 0;
  66. }
  67. QScrollBar:vertical{
  68. border: 1px solid rgb(115, 115, 115);
  69. background: rgb(255, 255, 255, 0);
  70. width: 8px;
  71. margin: 0;
  72. }
  73. QScrollBar::handle:vertical{
  74. background: rgb(165, 165, 165);
  75. min-height: 20px;
  76. height: 40px;
  77. width: 8px;
  78. }
  79. QScrollBar::handle:vertical:hover{
  80. background: rgb(185, 185, 185);
  81. min-height: 20px;
  82. height: 40px;
  83. width: 8px;
  84. }
  85. QScrollBar::add-line:vertical{
  86. background: rgb(0,0,0,0);
  87. subcontrol-origin: paddding;
  88. subcontrol-position: top;
  89. }
  90. QScrollBar::sub-line:vertical{
  91. background: rgb(0,0,0,0);
  92. subcontrol-origin: padding;
  93. subcontrol-position: bottom;
  94. }
  95. QScrollBar::top-arrow:vertical, QScrollBar::bottom-arrow:vertical{
  96. background: rgb(255,255,255,0);
  97. }
  98. QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical{
  99. background: rgb(255,255,255,0);
  100. }
  101. '''
  102.  
  103.  
  104. class ModuleWidget(QtGui.QWidget):
  105. '''QListWidgetItem Widget that wraps up a module or package, displaying
  106. modified time and module path. Tooltips display module filepaths.
  107. '''
  108.  
  109. def __init__(self, module, subpackages=None, parent=None):
  110. super(ModuleWidget, self).__init__(parent)
  111. self.module = module
  112. self.subpackages = subpackages
  113. self.grid = QtGui.QGridLayout()
  114. self.grid.setContentsMargins(20, 10, 20, 10)
  115. self.grid.setColumnStretch(2, 1)
  116.  
  117. modname = self.module.__name__
  118. modpath = self.module.__file__
  119. modmodf = time.localtime(os.path.getmtime(modpath))
  120.  
  121. font = QtGui.QFont('SansSerif', 12)
  122. subfont = QtGui.QFont('SansSerif', 10)
  123.  
  124. self.modf = QtGui.QLabel(time.strftime('%H:%M', modmodf))
  125. self.modf.setFont(font)
  126. self.name = QtGui.QLabel(modname)
  127. self.name.setFont(font)
  128. self.name.setToolTip(modpath)
  129.  
  130. self.grid.addWidget(self.modf, 0, 0)
  131. self.grid.addWidget(self.name, 0, 1, 1, 2)
  132.  
  133. if self.subpackages:
  134. for i, subpackage in enumerate(self.subpackages):
  135. subname = subpackage.__name__
  136. subpath = subpackage.__file__
  137. submodf = time.localtime(os.path.getmtime(modpath))
  138.  
  139. modf = QtGui.QLabel(time.strftime('%H:%M', modmodf))
  140. modf.setFont(subfont)
  141. name = QtGui.QLabel(subname)
  142. name.setFont(subfont)
  143. name.setToolTip(subpath)
  144.  
  145. self.grid.addWidget(modf, i + 1, 1)
  146. self.grid.addWidget(name, i + 1, 2)
  147.  
  148. self.setLayout(self.grid)
  149. self.setAttribute(QtCore.Qt.WA_StyledBackground)
  150. self.setObjectName('ModuleWidget')
  151. self.deactivate()
  152.  
  153. def activate(self):
  154. self.setStyleSheet('QLabel{color:rgb(235,235,235)}')
  155.  
  156. def deactivate(self):
  157. self.setStyleSheet('QLabel{color:rgb(15,15,15)}')
  158.  
  159.  
  160. class ModuleList(QtGui.QListWidget):
  161. '''QListWidget extended to act more like a python list and handle module
  162. objects.'''
  163.  
  164. def __init__(self, *args, **kwargs):
  165. super(ModuleList, self).__init__(*args, **kwargs)
  166. self.itemSelectionChanged.connect(self.selection_changed)
  167. self.setSelectionMode(QtGui.QListWidget.ExtendedSelection)
  168. self.setFocusPolicy(QtCore.Qt.NoFocus)
  169.  
  170. def selection_changed(self, *args):
  171. '''Change text color of ModuleWidgets based on selection.'''
  172.  
  173. for i in range(self.count()):
  174. item = self.item(i)
  175. w = self.itemWidget(item)
  176. if w:
  177. if item.isSelected():
  178. w.activate()
  179. else:
  180. w.deactivate()
  181.  
  182. def refresh(self):
  183. '''Get a new list of modified modules to display.'''
  184.  
  185. self.clear()
  186. self.extend(reimport.modified())
  187.  
  188. def extend(self, modules):
  189. '''Takes an iterable of module paths and groups them by package, then
  190. adds them to the QListWidget. Delegates QListWidgetItem to
  191. ModuleWidget.'''
  192.  
  193. modified = sorted(modules)
  194.  
  195. def top_level(item):
  196. '''Sort by top level module.'''
  197. return item.split('.')[0]
  198.  
  199. grouped = {}
  200. for k, v in groupby(modified, key=top_level):
  201. grouped[k] = [item for item in v if not item == k]
  202.  
  203. for module, subpackages in grouped.iteritems():
  204. m = sys.modules.get(module)
  205. sp = [sys.modules.get(p) for p in subpackages]
  206. self.append(m, sp)
  207.  
  208. def append(self, module, subpackages=None):
  209. '''Append module or a package to the list.'''
  210.  
  211. item = QtGui.QListWidgetItem(self)
  212. w = ModuleWidget(module, subpackages)
  213. item.setSizeHint(w.sizeHint())
  214. self.setItemWidget(item, w)
  215. super(ModuleList, self).addItem(item)
  216.  
  217. def selected(self):
  218. '''Iterate over selected items.'''
  219.  
  220. for item in self.selectedItems():
  221. yield(item)
  222.  
  223. def pop(self, item):
  224. '''Pop a list item and return a ModuleWidget'''
  225.  
  226. w = self.itemWidget(item)
  227. self.takeItem(self.row(item))
  228. return w
  229.  
  230.  
  231. class Button(QtGui.QPushButton):
  232. '''Sexy button with a drop shadow.'''
  233.  
  234.  
  235. shadow_state = {
  236. 'default': (12, (0, 4)),
  237. 'press': (12, (0, 2)),
  238. 'enter': (13, (0, 5)),
  239. }
  240.  
  241. def __init__(self, *args, **kwargs):
  242. super(Button, self).__init__(*args, **kwargs)
  243.  
  244. self.drop_shadow = QtGui.QGraphicsDropShadowEffect(self)
  245. self.drop_shadow.setBlurRadius(self.shadow_state['default'][0])
  246. self.drop_shadow.setOffset(*self.shadow_state['default'][1])
  247. self.drop_shadow.setColor(QtGui.QColor(0, 0, 0, 75))
  248. self.setFocusPolicy(QtCore.Qt.NoFocus)
  249. self.setGraphicsEffect(self.drop_shadow)
  250.  
  251. def mousePressEvent(self, event):
  252. self.drop_shadow.setBlurRadius(self.shadow_state['press'][0])
  253. self.drop_shadow.setOffset(*self.shadow_state['press'][1])
  254. super(Button, self).mousePressEvent(event)
  255.  
  256. def enterEvent(self, event):
  257. self.drop_shadow.setBlurRadius(self.shadow_state['enter'][0])
  258. self.drop_shadow.setOffset(*self.shadow_state['enter'][1])
  259. super(Button, self).enterEvent(event)
  260.  
  261. def leaveEvent(self, event):
  262. self.drop_shadow.setBlurRadius(self.shadow_state['default'][0])
  263. self.drop_shadow.setOffset(*self.shadow_state['default'][1])
  264. super(Button, self).leaveEvent(event)
  265.  
  266. def mouseReleaseEvent(self, event):
  267. self.drop_shadow.setBlurRadius(self.shadow_state['default'][0])
  268. self.drop_shadow.setOffset(*self.shadow_state['default'][1])
  269. super(Button, self).mouseReleaseEvent(event)
  270.  
  271. class PythonManager(QtGui.QDialog):
  272. '''GUI Managing modified Python modules and packages.'''
  273.  
  274. def __init__(self, parent=PARENT_APPLICATION):
  275. super(PythonManager, self).__init__(parent)
  276.  
  277. drop_shadow = QtGui.QGraphicsDropShadowEffect(self)
  278. drop_shadow.setBlurRadius(10)
  279. drop_shadow.setOffset(0, 3)
  280. drop_shadow.setColor(QtGui.QColor(0, 0, 0, 50))
  281.  
  282. self.module_list = ModuleList()
  283.  
  284. self.layout = QtGui.QGridLayout(self)
  285. self.layout.setContentsMargins(0, 0, 0, 0)
  286. self.layout.setSpacing(0)
  287. self.layout.setRowMinimumHeight(0, 39)
  288. self.layout.addWidget(self.module_list, 1, 0)
  289. self.setLayout(self.layout)
  290.  
  291. self.refresh_button = Button('Refresh', self)
  292. self.refresh_button.clicked.connect(self.module_list.refresh)
  293. self.reimport_button = Button('Reimport', self)
  294. self.reimport_button.clicked.connect(self.reimport_button_clicked)
  295.  
  296. self.header = QtGui.QLabel('Modified Modules and Packages', self)
  297. self.header.setObjectName('Header')
  298. self.header.setGraphicsEffect(drop_shadow)
  299. self.header.setFixedHeight(40)
  300.  
  301. self.setWindowTitle('Python Manager')
  302. self.setStyleSheet(STYLE)
  303.  
  304. def resizeEvent(self, event):
  305. '''Resize PythonManager UI, reposition buttons and header.'''
  306.  
  307. super(PythonManager, self).resizeEvent(event)
  308.  
  309. w = self.width()
  310. h = self.height()
  311. riw = self.reimport_button.width()
  312. rih = self.reimport_button.height()
  313. rfw = self.refresh_button.width()
  314.  
  315. self.setMinimumWidth(riw + rfw + 50)
  316. self.header.setFixedWidth(w)
  317. self.header.move(0, 0)
  318. self.reimport_button.move(w - riw - 20, h -rih - 20)
  319. self.refresh_button.move(w - riw - rfw - 30, h - rih - 20)
  320.  
  321. def reimport_button_clicked(self):
  322. '''Reimport selected items from the ModuleList.'''
  323.  
  324. for item in self.module_list.selected():
  325. w = self.module_list.pop(item)
  326. reimport.reimport(w.module)
  327.  
  328. def main():
  329.  
  330. app = QtGui.QApplication(sys.argv)
  331. pyman = PythonManager()
  332. pyman.show()
  333. sys.exit(app.exec_())
  334.  
  335.  
  336. if __name__ == '__main__':
  337. main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement