design.py 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. import os, re
  4. # sys,
  5. from PyQt5 import QtCore
  6. from PyQt5.QtCore import QUrl, QSettings
  7. from PyQt5.QtGui import QKeySequence, QFont
  8. from PyQt5.QtWidgets import QWidget, QTabWidget, QVBoxLayout, QHBoxLayout, QSplitter, QPlainTextEdit, QShortcut, QPushButton, QCheckBox
  9. from PyQt5.QtWebKit import QWebSettings
  10. from PyQt5.QtWebKitWidgets import QWebView, QWebInspector
  11. class WebkitView(QWebView):
  12. def __init__(self, parent, port):
  13. self.port = port
  14. self.view = QWebView.__init__(self, parent)
  15. self.load(QUrl('http://localhost:'+str(self.port)))
  16. self.settings().setAttribute(QWebSettings.DeveloperExtrasEnabled, True)
  17. # self.settings().setAttribute(QWebSettings.PluginsEnabled, True)
  18. class WebkitInspector(QWebInspector):
  19. def __init__(self, parent, webkitview):
  20. super(WebkitInspector, self).__init__(parent)
  21. self.webkitview = webkitview
  22. self.setPage(self.webkitview.page())
  23. self.showMaximized()
  24. # TODO: webkitinspector is disappearing when chaging tabs
  25. class WebViewOptions(QWidget):
  26. def __init__(self, parent):
  27. super(WebViewOptions, self).__init__(parent)
  28. self.parent = parent
  29. self.hbox = QHBoxLayout()
  30. self.hbox.setContentsMargins(0,0,0,0)
  31. self.preview = QCheckBox('&Preview', self)
  32. # self.preview.setShortcut('Ctrl+Shift+p')
  33. self.preview.clicked.connect(self.onPreview)
  34. self.hbox.addWidget(self.preview)
  35. self.debug = QCheckBox('Deb&ug', self)
  36. # self.debug.setShortcut('Ctrl+Shift+u')
  37. self.debug.clicked.connect(self.onDebug)
  38. self.hbox.addWidget(self.debug)
  39. self.grid = QCheckBox('&Grid', self)
  40. # self.grid.setShortcut('Ctrl+Shift+g')
  41. self.grid.clicked.connect(self.onGrid)
  42. self.hbox.addWidget(self.grid)
  43. # spread
  44. self.spread = QCheckBox('&Spread', self)
  45. # self.spread.setShortcut('Ctrl+Shift+g')
  46. self.spread.clicked.connect(self.onSpread)
  47. self.hbox.addWidget(self.spread)
  48. self.hbox.addStretch()
  49. # zoom
  50. # page
  51. self.hbox.addStretch()
  52. self.reload = QPushButton("&Reload", self)
  53. # self.reload.setShortcut('Ctrl+Shift+r')
  54. # TODO: how to define same shortcut in different places
  55. # self.reload.setIcon(Icon(ico)))
  56. self.reload.clicked.connect(self.onReload)
  57. self.hbox.addWidget(self.reload)
  58. self.setLayout(self.hbox)
  59. def onReload(self):
  60. print("onReload")
  61. # self.parent.webkitview.
  62. def onPreview(self):
  63. print('onPreview')
  64. def onDebug(self):
  65. print('onDebug')
  66. def onGrid(self):
  67. print('onGrid')
  68. def onSpread(self):
  69. print('onSpread')
  70. class CodeEditor(QPlainTextEdit):
  71. def __init__(self, core, tabs, file=None):
  72. super(CodeEditor, self).__init__()
  73. self.core = core
  74. self.tabs = tabs
  75. self.file = file
  76. self.setText()
  77. self.shortcut = QShortcut(QKeySequence("Ctrl+s"), self)
  78. self.shortcut.activated.connect(self.save)
  79. def setText(self):
  80. try:
  81. self.textChanged.disconnect(self.onTextChanged)
  82. except Exception as e:
  83. print(e)
  84. self.filepath = os.path.join(self.core.cwd,self.file)
  85. self.clear()
  86. self.insertPlainText(open(self.filepath, 'r').read())
  87. self.changed = False
  88. self.textChanged.connect(self.onTextChanged)
  89. def onTextChanged(self):
  90. # print('textChanged')
  91. # print(self.toPlainText())
  92. # open(self.filepath, 'w').write(self.toPlainText())
  93. if not self.changed:
  94. self.changed = True
  95. i = self.tabs.currentIndex()
  96. self.tabs.setTabText(i, "* "+self.tabs.tabText(i))
  97. def save(self):
  98. if self.changed:
  99. open(self.filepath, 'w').write(self.toPlainText())
  100. i = self.tabs.currentIndex()
  101. self.tabs.setTabText(i, re.sub(r'^\*\s', '', self.tabs.tabText(i)))
  102. self.changed = False
  103. # TODO: how to combine file save and project save
  104. class Editor(QWidget):
  105. def __init__(self, parent, core):
  106. super(Editor, self).__init__()
  107. self.core = core
  108. self.layout = QVBoxLayout(self)
  109. self.layout.setContentsMargins(0,0,0,0)
  110. # Initialize tab screen
  111. self.tabs = QTabWidget()
  112. self.scsstab = CodeEditor(core, self.tabs, 'assets/css/styles.scss')
  113. self.jstab = CodeEditor(core, self.tabs, 'assets/js/script.js')
  114. # Add tabs
  115. self.tabs.addTab(self.scsstab,"scss")
  116. self.tabs.addTab(self.jstab,"js")
  117. # Add tabs to widget
  118. self.layout.addWidget(self.tabs)
  119. self.setLayout(self.layout)
  120. # font = QFont()
  121. # font.setFamily('Courier')
  122. # font.setFixedPitch(True)
  123. # font.setPointSize(10)
  124. # self.setFont(font)
  125. # self.highlighter = Highlighter(self.document())
  126. # https://pypi.python.org/pypi/QScintilla/2.9.2
  127. def refresh(self):
  128. self.scsstab.setText()
  129. self.jstab.setText()
  130. class DesignStack(QWidget):
  131. def __init__(self, core):
  132. super(DesignStack, self).__init__()
  133. # self.grid = QGridLayout()
  134. self.hbox = QHBoxLayout()
  135. self.hbox.setContentsMargins(0,0,0,0)
  136. self.setLayout(self.hbox)
  137. self.webview = QWidget()
  138. self.webview.vbox = QVBoxLayout()
  139. self.webview.setLayout(self.webview.vbox)
  140. self.webview.vbox.setContentsMargins(0,0,0,0)
  141. self.webkitview = WebkitView(self, core.server.port)
  142. self.webkitinspector = WebkitInspector(self, self.webkitview)
  143. shortcut = QShortcut(self)
  144. shortcut.setKey("F12")
  145. shortcut.activated.connect(self.toggleInspector)
  146. self.webkitinspector.setVisible(False)
  147. self.webviewoptions = WebViewOptions(self)
  148. self.webview.vbox.addWidget(self.webviewoptions)
  149. self.vsplitter = QSplitter(QtCore.Qt.Vertical)
  150. self.vsplitter.addWidget(self.webkitview)
  151. self.vsplitter.addWidget(self.webkitinspector)
  152. self.vsplitter.splitterMoved.connect(self.movedSplitter)
  153. self.webview.vbox.addWidget(self.vsplitter)
  154. self.hsplitter = QSplitter(QtCore.Qt.Horizontal)
  155. self.hsplitter.addWidget(self.webview)
  156. self.editor = Editor(self, core)
  157. self.hsplitter.addWidget(self.editor)
  158. self.hsplitter.splitterMoved.connect(self.movedSplitter)
  159. self.hbox.addWidget(self.hsplitter)
  160. self.restorePrefs()
  161. def toggleInspector(self):
  162. self.webkitinspector.setVisible(not self.webkitinspector.isVisible())
  163. def restorePrefs(self):
  164. settings = QSettings('FiguresLibres', 'Cascade')
  165. print(settings.value('design/vsplitter/sizes', self.vsplitter.sizes()))
  166. vals = settings.value('design/vsplitter/sizes', None)
  167. if vals:
  168. sizes = []
  169. for size in vals: sizes.append(int(size))
  170. self.vsplitter.setSizes(sizes)
  171. vals = settings.value('design/hsplitter/sizes', None)
  172. if vals:
  173. sizes = []
  174. for size in vals: sizes.append(int(size))
  175. self.hsplitter.setSizes(sizes)
  176. def movedSplitter(self):
  177. settings = QSettings('FiguresLibres', 'Cascade')
  178. # print(self.vsplitter.sizes())
  179. settings.setValue('design/vsplitter/sizes', self.vsplitter.sizes())
  180. settings.setValue('design/hsplitter/sizes', self.hsplitter.sizes())
  181. def refresh(self):
  182. self.editor.refresh()
  183. self.webkitview.reload()