design.py 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  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, QSizeF
  7. from PyQt5.QtGui import QKeySequence, QFont
  8. from PyQt5.QtWidgets import QWidget, QTabWidget, QVBoxLayout, QHBoxLayout, QSplitter, QPlainTextEdit, QShortcut, QPushButton, QCheckBox, QSpinBox, QLabel
  9. from PyQt5.QtWebKit import QWebSettings
  10. from PyQt5.QtWebKitWidgets import QWebView, QWebInspector
  11. from PyQt5.QtPrintSupport import QPrintPreviewDialog, QPrinter
  12. class WebkitView(QWebView):
  13. def __init__(self, parent, core):
  14. self.parent = parent
  15. self.core = core
  16. self.port = core.server.port
  17. self.view = QWebView.__init__(self, parent)
  18. self.setZoomFactor(1)
  19. self.load(QUrl('http://localhost:'+str(self.port)))
  20. self.settings().setAttribute(QWebSettings.DeveloperExtrasEnabled, True)
  21. # self.settings().setAttribute(QWebSettings.PluginsEnabled, True)
  22. self.initPDF()
  23. # self.mainframe = self.page.mainFrame()
  24. # print(self.mainframe)
  25. def initPDF(self):
  26. self.printer = QPrinter(QPrinter.HighResolution)
  27. self.printer.setFullPage(True)
  28. # self.printer.setPageMargins(0,0,0,0,QPrinter.Millimeter)
  29. self.printer.setFontEmbeddingEnabled(True)
  30. self.printer.setColorMode(QPrinter.Color)
  31. # TODO: set the page size and orientation from doc settings
  32. # (need to do doc settings before that)
  33. # self.printer.setPageSize(QPrinter.A4)
  34. self.printer.setPaperSize(QSizeF(210, 300), QPrinter.Millimeter)
  35. # self.printer.setOrientation(QPrinter.Portrait)
  36. self.printer.setOutputFormat(QPrinter.PdfFormat)
  37. self.printer.setCreator('Cascade')
  38. self.printer.setDocName(self.core.projectname)
  39. self.printer.setOutputFileName(self.core.projectname+".pdf")
  40. # self.setFixedWidth(1000)
  41. def ongenPDF(self):
  42. # QPrinter::Custom
  43. # dialog = QPrintPreviewDialog(self.printer)
  44. # dialog.setWindowState(Qt.WindowMaximized)
  45. # dialog.paintRequested.connect(self.print_)
  46. # dialog.setWindowFlags(Qt.CustomizeWindowHint | Qt.WindowTitleHint | Qt.WindowMinMaxButtonsHint | Qt.WindowCloseButtonHint | Qt.WindowContextHelpButtonHint)
  47. # dialog.exec()
  48. # TODO: open a dialogue to ask where to save the pdf
  49. # TODO: reload webview and wait for it before printing
  50. # TODO: addd a progress bar
  51. # self.webview.
  52. self.print_(self.printer)
  53. def refresh(self):
  54. self.initPDF()
  55. self.reload()
  56. class WebkitInspector(QWebInspector):
  57. def __init__(self, parent, webkitview):
  58. super(WebkitInspector, self).__init__(parent)
  59. self.webkitview = webkitview
  60. self.setPage(self.webkitview.page())
  61. self.showMaximized()
  62. # TODO: webkitinspector is disappearing when chaging tabs
  63. class WebViewToolBar(QWidget):
  64. def __init__(self, parent):
  65. super(WebViewToolBar, self).__init__(parent)
  66. self.parent = parent
  67. font = QFont()
  68. # font.setFamily("Droid Sans Mono")
  69. # font.setFixedPitch(True)
  70. font.setPointSize(8)
  71. self.setFont(font)
  72. self.hbox = QHBoxLayout()
  73. self.hbox.setContentsMargins(0,0,0,0)
  74. self.preview = QCheckBox('&Preview', self)
  75. # self.preview.setShortcut('Ctrl+Shift+p')
  76. self.preview.clicked.connect(self.onPreview)
  77. self.hbox.addWidget(self.preview)
  78. self.debug = QCheckBox('Deb&ug', self)
  79. # self.debug.setShortcut('Ctrl+Shift+u')
  80. self.debug.clicked.connect(self.onDebug)
  81. self.hbox.addWidget(self.debug)
  82. self.grid = QCheckBox('&Grid', self)
  83. # self.grid.setShortcut('Ctrl+Shift+g')
  84. self.grid.clicked.connect(self.onGrid)
  85. self.hbox.addWidget(self.grid)
  86. # spread
  87. self.spread = QCheckBox('&Spread', self)
  88. # self.spread.setShortcut('Ctrl+Shift+g')
  89. self.spread.clicked.connect(self.onSpread)
  90. self.hbox.addWidget(self.spread)
  91. self.hbox.addStretch()
  92. # zoom
  93. self.hbox.addWidget(QLabel("Zoom:"))
  94. self.zoom = QSpinBox(self)
  95. # TODO: action
  96. self.hbox.addWidget(self.zoom)
  97. # page
  98. self.hbox.addWidget(QLabel("Page:"))
  99. self.page = QSpinBox(self)
  100. # TODO: action
  101. self.hbox.addWidget(self.page)
  102. self.addpage = QPushButton("&Add Page", self)
  103. # self.addpage.setShortcut('Ctrl+Shift+r')
  104. # TODO: how to define same shortcut in different places
  105. # self.addpage.setIcon(Icon(ico)))
  106. # self.addpage.clicked.connect(self.onAddPage)
  107. self.hbox.addWidget(self.addpage)
  108. self.hbox.addStretch()
  109. self.reload = QPushButton("&Reload", self)
  110. # self.reload.setShortcut('Ctrl+Shift+r')
  111. # TODO: how to define same shortcut in different places
  112. # self.reload.setIcon(Icon(ico)))
  113. self.reload.clicked.connect(self.onReload)
  114. self.hbox.addWidget(self.reload)
  115. self.genpdf = QPushButton("&PDF", self)
  116. # self.genpdf.setShortcut('Ctrl+Shift+r')
  117. # TODO: how to define same shortcut in different places
  118. # self.genpdf.setIcon(Icon(ico)))
  119. self.genpdf.clicked.connect(self.onGenPDF)
  120. self.hbox.addWidget(self.genpdf)
  121. self.setLayout(self.hbox)
  122. def onPreview(self):
  123. print('onPreview')
  124. def onDebug(self):
  125. print('onDebug')
  126. def onGrid(self):
  127. print('onGrid')
  128. def onSpread(self):
  129. print('onSpread')
  130. def onReload(self):
  131. print("onReload")
  132. # self.parent.webkitview.
  133. def onGenPDF(self):
  134. print("onGenPDF")
  135. self.parent.webkitview.ongenPDF()
  136. class CodeEditor(QPlainTextEdit):
  137. def __init__(self, core, tabs, file=None):
  138. super(CodeEditor, self).__init__()
  139. self.core = core
  140. self.tabs = tabs
  141. self.file = file
  142. self.setText()
  143. self.shortcut = QShortcut(QKeySequence("Ctrl+s"), self)
  144. self.shortcut.activated.connect(self.save)
  145. def setText(self):
  146. try:
  147. self.textChanged.disconnect(self.onTextChanged)
  148. except Exception as e:
  149. print(e)
  150. self.filepath = os.path.join(self.core.cwd,self.file)
  151. self.clear()
  152. self.insertPlainText(open(self.filepath, 'r').read())
  153. self.changed = False
  154. self.textChanged.connect(self.onTextChanged)
  155. font = QFont()
  156. font.setFamily("Droid Sans Mono")
  157. font.setFixedPitch(True)
  158. font.setPointSize(12)
  159. self.setFont(font)
  160. # self.highlighter = Highlighter(self.document())
  161. # https://pypi.python.org/pypi/QScintilla/2.9.2
  162. def onTextChanged(self):
  163. # print('textChanged')
  164. # print(self.toPlainText())
  165. # open(self.filepath, 'w').write(self.toPlainText())
  166. if not self.changed:
  167. self.changed = True
  168. i = self.tabs.currentIndex()
  169. self.tabs.setTabText(i, "* "+self.tabs.tabText(i))
  170. # TODO: indicate that webview needs to be reloaded
  171. def save(self):
  172. if self.changed:
  173. open(self.filepath, 'w').write(self.toPlainText())
  174. i = self.tabs.currentIndex()
  175. self.tabs.setTabText(i, re.sub(r'^\*\s', '', self.tabs.tabText(i)))
  176. self.changed = False
  177. # TODO: how to combine file save and project save
  178. class Editor(QWidget):
  179. def __init__(self, parent, core):
  180. super(Editor, self).__init__()
  181. self.core = core
  182. self.layout = QVBoxLayout(self)
  183. self.layout.setContentsMargins(0,0,0,0)
  184. # Initialize tab screen
  185. self.tabs = QTabWidget()
  186. self.scsstab = CodeEditor(core, self.tabs, 'assets/css/styles.scss')
  187. self.jstab = CodeEditor(core, self.tabs, 'assets/js/script.js')
  188. # Add tabs
  189. self.tabs.addTab(self.scsstab,"scss")
  190. self.tabs.addTab(self.jstab,"js")
  191. # Add tabs to widget
  192. self.layout.addWidget(self.tabs)
  193. self.setLayout(self.layout)
  194. def refresh(self):
  195. self.scsstab.setText()
  196. self.jstab.setText()
  197. class DesignStack(QWidget):
  198. def __init__(self, core):
  199. super(DesignStack, self).__init__()
  200. # self.grid = QGridLayout()
  201. self.hbox = QHBoxLayout()
  202. self.hbox.setContentsMargins(0,0,0,0)
  203. self.setLayout(self.hbox)
  204. self.webview = QWidget()
  205. self.webview.vbox = QVBoxLayout()
  206. self.webview.setLayout(self.webview.vbox)
  207. self.webview.vbox.setContentsMargins(0,0,0,0)
  208. self.webkitview = WebkitView(self, core)
  209. self.webkitinspector = WebkitInspector(self, self.webkitview)
  210. shortcut = QShortcut(self)
  211. shortcut.setKey("F12")
  212. shortcut.activated.connect(self.toggleInspector)
  213. self.webkitinspector.setVisible(False)
  214. self.webviewtoolbar = WebViewToolBar(self)
  215. self.webview.vbox.addWidget(self.webviewtoolbar)
  216. self.vsplitter = QSplitter(QtCore.Qt.Vertical)
  217. self.vsplitter.addWidget(self.webkitview)
  218. self.vsplitter.addWidget(self.webkitinspector)
  219. self.vsplitter.splitterMoved.connect(self.movedSplitter)
  220. self.webview.vbox.addWidget(self.vsplitter)
  221. self.hsplitter = QSplitter(QtCore.Qt.Horizontal)
  222. self.hsplitter.addWidget(self.webview)
  223. self.editor = Editor(self, core)
  224. self.hsplitter.addWidget(self.editor)
  225. self.hsplitter.splitterMoved.connect(self.movedSplitter)
  226. self.hbox.addWidget(self.hsplitter)
  227. self.restorePrefs()
  228. def toggleInspector(self):
  229. self.webkitinspector.setVisible(not self.webkitinspector.isVisible())
  230. def restorePrefs(self):
  231. settings = QSettings('FiguresLibres', 'Cascade')
  232. print(settings.value('design/vsplitter/sizes', self.vsplitter.sizes()))
  233. vals = settings.value('design/vsplitter/sizes', None)
  234. if vals:
  235. sizes = []
  236. for size in vals: sizes.append(int(size))
  237. self.vsplitter.setSizes(sizes)
  238. vals = settings.value('design/hsplitter/sizes', None)
  239. if vals:
  240. sizes = []
  241. for size in vals: sizes.append(int(size))
  242. self.hsplitter.setSizes(sizes)
  243. def movedSplitter(self):
  244. settings = QSettings('FiguresLibres', 'Cascade')
  245. # print(self.vsplitter.sizes())
  246. settings.setValue('design/vsplitter/sizes', self.vsplitter.sizes())
  247. settings.setValue('design/hsplitter/sizes', self.hsplitter.sizes())
  248. def refresh(self):
  249. self.editor.refresh()
  250. self.webkitview.refresh()