design.py 10 KB

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