mainwindow.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. # @Author: Bachir Soussi Chiadmi <bach>
  4. # @Date: 23-05-2017
  5. # @Email: bachir@figureslibres.io
  6. # @Last modified by: bach
  7. # @Last modified time: 03-06-2017
  8. # @License: GPL-V3
  9. from __future__ import absolute_import, print_function, division, unicode_literals
  10. import os, asyncio
  11. from PyQt5.QtCore import Qt
  12. from PyQt5.QtGui import QIcon, QKeySequence
  13. from PyQt5.QtWidgets import (QMainWindow, QAction, QWidget,
  14. QLabel, QStackedWidget,
  15. QFileDialog, QMessageBox,
  16. QShortcut)
  17. from . import design, content, docsetdialog
  18. class MainWindow(QMainWindow):
  19. def __init__(self, core):
  20. super(MainWindow, self).__init__()
  21. # load core class
  22. self.core = core
  23. self.setWindowTitle("Libriis")
  24. self.setWindowIcon(QIcon(os.path.join(self.core.appcwd,'assets/images/icon.png')))
  25. self.resize(self.core.mw_size)
  26. self.move(self.core.mw_pos)
  27. self.initMenuBar()
  28. self.initMainStack()
  29. self.show()
  30. # __ ___ ____
  31. # / |/ /__ ____ __ __/ __ )____ ______
  32. # / /|_/ / _ \/ __ \/ / / / __ / __ `/ ___/
  33. # / / / / __/ / / / /_/ / /_/ / /_/ / /
  34. # /_/ /_/\___/_/ /_/\__,_/_____/\__,_/_/
  35. def initMenuBar(self):
  36. # menu bar
  37. bar = self.menuBar()
  38. # bar.setNativeMenuBar(False)
  39. file = bar.addMenu("&File")
  40. new = QAction("&New Project",self)
  41. new.setShortcut("Ctrl+n")
  42. file.addAction(new)
  43. open = QAction("&Open",self)
  44. open.setShortcut("Ctrl+o")
  45. file.addAction(open)
  46. self.save_action = QAction("&Save Project as",self)
  47. self.save_action.setShortcut("Ctrl+Shift+s")
  48. file.addAction(self.save_action)
  49. self.docset_action = QAction("&Document Settings",self)
  50. self.docset_action.setShortcut("Ctrl+d")
  51. file.addAction(self.docset_action)
  52. self.pdf_action = QAction("&PDF",self)
  53. self.pdf_action.setShortcut("Ctrl+p")
  54. file.addAction(self.pdf_action)
  55. self.quit_action = QAction("&Quit",self)
  56. self.quit_action.setShortcut("Ctrl+q")
  57. file.addAction(self.quit_action)
  58. file.triggered[QAction].connect(self.onfilemenutrigger)
  59. # edit menu
  60. edit = bar.addMenu("&Edit")
  61. # edit.addAction("&copy")
  62. # edit.addAction("&paste")
  63. edit.addAction("&build")
  64. self.reload_action = QAction("&Reload",self)
  65. self.reload_action.setShortcut("Ctrl+r")
  66. edit.addAction(self.reload_action)
  67. edit.addAction("&preferences")
  68. edit.triggered[QAction].connect(self.oneditmenutrigger)
  69. # view menu
  70. view = bar.addMenu("&View")
  71. contentview = QAction("&Content",self)
  72. contentview.setShortcut("F1")
  73. view.addAction(contentview)
  74. designview = QAction("&Design",self)
  75. designview.setShortcut("F2")
  76. view.addAction(designview)
  77. versionview = QAction("&Version")
  78. versionview.setShortcut("F3")
  79. view.addAction(versionview)
  80. self.menuview = QAction("&Show Menu", self)
  81. self.menuview.setCheckable(True)
  82. self.menuview.setShortcutContext(Qt.ApplicationShortcut)
  83. self.menuview.setShortcut('F4')
  84. view.addAction(self.menuview)
  85. # self.menuview_shortcut = QShortcut(QKeySequence("F4"), self)
  86. # self.menuview_shortcut.activated.connect(self.toggleMenu)
  87. view.triggered[QAction].connect(self.onviewmenutrigger)
  88. # about menu
  89. about = bar.addMenu("About")
  90. about.addAction("&Website")
  91. self.menuisvisible = True
  92. # TODO: get menu visibility from settings
  93. def onfilemenutrigger(self, q):
  94. print(q.text()+" is triggered")
  95. if q.text() == "&New Project":
  96. self.newprojectdialogue()
  97. elif q.text() == "&Open":
  98. self.openprojectdialogue()
  99. elif q.text() == "&Save Project as":
  100. self.saveprojectdialogue()
  101. elif q.text() == "&Document Settings":
  102. self.onDocSettings()
  103. elif q.text() == "&PDF":
  104. self.genPDF()
  105. elif q.text() == "&Quit":
  106. self.quit()
  107. def openprojectdialogue(self):
  108. print("open")
  109. dialog = QFileDialog()
  110. dialog.setFileMode(QFileDialog.Directory)
  111. dialog.setAcceptMode(QFileDialog.AcceptOpen)
  112. options = QFileDialog.DontResolveSymlinks | QFileDialog.ShowDirsOnly
  113. folder = dialog.getExistingDirectory(
  114. self,
  115. 'Open Project',
  116. self.core.dialog_path,
  117. options
  118. )
  119. try:
  120. head, tail = os.path.split(folder)
  121. self.core.dialog_path = head
  122. # TODO: check if is libriis folder
  123. print(folder)
  124. if os.path.isdir(folder):
  125. self.core.openproject(folder)
  126. else:
  127. print("folder doesn't exists")
  128. except Exception as e:
  129. print('Exception', e)
  130. pass
  131. def newprojectdialogue(self):
  132. dialog = QFileDialog()
  133. dialog.setFileMode(QFileDialog.Directory)
  134. dialog.setAcceptMode(QFileDialog.AcceptOpen)
  135. projectname = dialog.getSaveFileName(
  136. self,
  137. 'New Project',
  138. self.core.dialog_path
  139. )[0]
  140. # TODO: no file type
  141. try:
  142. head, tail = os.path.split(projectname)
  143. self.core.dialog_path = head
  144. if not os.path.isdir(projectname):
  145. self.core.initnewproject(projectname)
  146. else:
  147. print("folder already exists")
  148. # TODO: check if is libriis folder
  149. except Exception as e:
  150. print('Exception', e)
  151. pass
  152. def saveprojectdialogue(self, quit=False):
  153. dialog = QFileDialog()
  154. dialog.setFileMode(QFileDialog.Directory)
  155. dialog.setAcceptMode(QFileDialog.AcceptOpen)
  156. projectname = dialog.getSaveFileName(
  157. self,
  158. 'Save Project',
  159. self.core.dialog_path
  160. # TODO: if tempproject open in home
  161. )[0]
  162. # TODO: no file type
  163. try:
  164. head, tail = os.path.split(projectname)
  165. self.core.dialog_path = head
  166. if not os.path.isdir(projectname):
  167. self.core.saveproject(projectname)
  168. if quit:
  169. self.quit()
  170. else:
  171. print("folder already exists")
  172. # TODO: check if is libriis folder
  173. except Exception as e:
  174. print('Exception', e)
  175. pass
  176. def onDocSettings(self):
  177. d = docsetdialog.DocsetDialog(self)
  178. d.exec_()
  179. self.core.recordDocSettings({
  180. "ho":d.headerOdd.text(),
  181. "he":d.headerEven.text(),
  182. "np":d.np.text(),
  183. "pw":d.pw.text(),
  184. "ph":d.ph.text(),
  185. "mt":d.mt.text(),
  186. "mb":d.mb.text(),
  187. "me":d.me.text(),
  188. "mi":d.mi.text(),
  189. "cs":d.cs.text(),
  190. "bs":d.bs.text(),
  191. "cn":d.cn.text(),
  192. "cg":d.cg.text(),
  193. "rn":d.rn.text(),
  194. "rg":d.rg.text(),
  195. "lh":d.lh.text()
  196. })
  197. def genPDF(self):
  198. print('PDF')
  199. self.designstack.webkitview.ongenPDF()
  200. def quit(self):
  201. print("Quit")
  202. if self.core.tempcwd:
  203. buttonReply = QMessageBox.question(self, 'Project Not Saved', "Do you want to save your current project before quiting?", QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel, QMessageBox.Cancel)
  204. if buttonReply == QMessageBox.Yes:
  205. self.saveprojectdialogue(quit=True)
  206. if buttonReply == QMessageBox.No:
  207. self.core.quit()
  208. else:
  209. self.core.quit()
  210. def oneditmenutrigger(self, q):
  211. print(q.text()+" is triggered")
  212. if q.text() == "&Reload":
  213. self.designstack.webkitview.reload()
  214. def onviewmenutrigger(self, q):
  215. print(q.text()+" is triggered")
  216. if q.text() == "&Content":
  217. self.mainstack.setCurrentIndex(0)
  218. elif q.text() == "&Design":
  219. self.mainstack.setCurrentIndex(1)
  220. elif q.text() == "&Version":
  221. self.mainstack.setCurrentIndex(2)
  222. elif q.text() == "&Show Menu":
  223. self.toggleMenu()
  224. def toggleMenu(self):
  225. self.menuisvisible = not self.menuisvisible
  226. if self.menuisvisible:
  227. print('show menu')
  228. # self.menuBar().adjustSize()
  229. # self.menuBar().show()
  230. # .height(1)
  231. #setVisible(True)
  232. # .setStyleSheet("margin-top:0;")
  233. self.menuview.setChecked(True)
  234. else:
  235. print('hide menu')
  236. # self.menuBar()
  237. # self.menuBar().hide()
  238. # .height(25)
  239. #setVisible(False)
  240. # .setStyleSheet("margin-top:-10px;")
  241. self.menuview.setChecked(False)
  242. # __ ____ ______ __
  243. # / /_____ __ __/ __ \________ __________/ ____/ _____ ____ / /_
  244. # / //_/ _ \/ / / / /_/ / ___/ _ \/ ___/ ___/ __/ | | / / _ \/ __ \/ __/
  245. # / ,< / __/ /_/ / ____/ / / __(__ |__ ) /___ | |/ / __/ / / / /_
  246. # /_/|_|\___/\__, /_/ /_/ \___/____/____/_____/ |___/\___/_/ /_/\__/
  247. # /____/
  248. # def keyPressEvent(self, e):
  249. # print('keyPressEvent', e.key())
  250. # # print('Qt.Key_Alt', Qt.Key_Alt)
  251. # super(MainWindow, self).keyPressEvent(e)
  252. # self.checkToggleMenu('pressed', e.key() == Qt.Key_Alt)
  253. #
  254. # def keyReleaseEvent(self, e):
  255. # print('keyReleaseEvent', e.key())
  256. # # print('Qt.Key_Alt', Qt.Key_Alt)
  257. # super(MainWindow, self).keyReleaseEvent(e)
  258. # self.checkToggleMenu('released', e.key() == Qt.Key_Alt)
  259. # def checkToggleMenu(self, act='released', alt=True):
  260. # print("-- -- checkToggleMenu : "+act+" | alt :"+str(alt))
  261. # # if alt is pressed, other key pressevent is not fired, only release :(
  262. # # keyPressEvent is waiting for toggleMenu o_O which is supposed to be asynchro ...
  263. # if not alt:
  264. # self.key_pressed_after_alt = True
  265. # if alt and act=="pressed":
  266. # self.key_pressed_after_alt = False
  267. # if act == 'released' and alt:
  268. # loop = asyncio.get_event_loop()
  269. # loop.run_until_complete(self.toggleMenu())
  270. # # loop.close()
  271. # async def toggleMenu(self):
  272. # print('toggleMenu')
  273. # await asyncio.sleep(2)
  274. # if not self.key_pressed_after_alt:
  275. # print('!! !! TOGGLE !! !!')
  276. # # self.menuBar().setVisible(not self.menuBar().isVisible())
  277. # __ ___ _ _____ __ __
  278. # / |/ /___ _(_)___ / ___// /_____ ______/ /__
  279. # / /|_/ / __ `/ / __ \\__ \/ __/ __ `/ ___/ //_/
  280. # / / / / /_/ / / / / /__/ / /_/ /_/ / /__/ ,<
  281. # /_/ /_/\__,_/_/_/ /_/____/\__/\__,_/\___/_/|_|
  282. def initMainStack(self):
  283. self.mainstack = QStackedWidget()
  284. self.contentstack = content.ContentStack(self.core)
  285. self.designstack = design.DesignStack(self.core)
  286. self.versionstack = QLabel("Version (git).")
  287. self.mainstack.addWidget(self.contentstack)
  288. self.mainstack.addWidget(self.designstack)
  289. self.mainstack.addWidget(self.versionstack)
  290. self.mainstack.setCurrentIndex(self.core.mw_curstack)
  291. # TODO: add an app console window (show sass compilation errors for example)
  292. self.setCentralWidget(self.mainstack)