app.py 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  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: 21-04-2017
  8. # @License: GPL-V3
  9. import sys, os, shutil, tempfile
  10. from PyQt5 import QtCore
  11. from PyQt5.QtCore import QCoreApplication, QUrl, pyqtSlot, QSettings
  12. from PyQt5.QtGui import QIcon, QKeySequence, QFont, QSyntaxHighlighter
  13. from PyQt5.QtWidgets import QMainWindow, QAction, QWidget, QApplication, QShortcut, QGridLayout, QLabel, QTabWidget, QStackedWidget, QHBoxLayout, QVBoxLayout, QSplitter, QSplitterHandle, QPlainTextEdit, QInputDialog, QLineEdit, QFileDialog, QMessageBox, QPushButton
  14. # from PyQt5.QtNetwork import QNetworkProxyFactory, QNetworkRequest
  15. from PyQt5.QtWebKit import QWebSettings
  16. from PyQt5.QtWebKitWidgets import QWebPage, QWebView, QWebInspector
  17. import json
  18. import git
  19. from classes import server, compiler, view, content
  20. class Core():
  21. def __init__(self, parent=None):
  22. # restore previous preferences
  23. self.restorePreferences()
  24. self._mw = False
  25. self.temp = tempfile.mkdtemp()
  26. # print(self.temp)
  27. self.tempcwd = False
  28. if(self.cwd == None or not os.path.isdir(self.cwd)):
  29. self.cwd = os.path.join(self.temp, 'cwd')
  30. self.tempcwd = True
  31. self.initnewproject()
  32. self.server = server.Server(self.temp)
  33. self.compiler = compiler.Compiler(self.temp)
  34. @property
  35. def mainwindow(self):
  36. return self.mainwindow
  37. @mainwindow.setter
  38. def mainwindow(self, mw):
  39. if not self._mw:
  40. self._mw = mw
  41. if not self.tempcwd:
  42. self._mw.setWindowTitle("Cascade – "+self.cwd)
  43. def restorePreferences(self):
  44. # print("restorePreferences")
  45. settings = QSettings('FiguresLibres', 'Cascade')
  46. # settings.clear()
  47. # print(settings.allKeys())
  48. self.cwd = settings.value('core/cwd', None)
  49. self.mw_size = settings.value('mainwindow/size', QtCore.QSize(1024, 768))
  50. self.mw_pos = settings.value('mainwindow/pos', QtCore.QPoint(0, 0))
  51. def savePreferences(self):
  52. # print("savePreferences")
  53. settings = QSettings('FiguresLibres', 'Cascade')
  54. # print(settings.allKeys())
  55. if not self.tempcwd:
  56. settings.setValue('core/cwd', self.cwd)
  57. settings.setValue('mainwindow/size', self.mainwindow.size())
  58. settings.setValue('mainwindow/pos', self.mainwindow.pos())
  59. # TODO: save splitters pos
  60. def initnewproject(self, cwd = None):
  61. if cwd == None :
  62. cwd = self.cwd
  63. else :
  64. self.cwd = cwd
  65. shutil.copytree('templates/newproject', cwd)
  66. self.prefs = json.loads(open(os.path.join(cwd,'.config/prefs.json')).read())
  67. self.summary = json.loads(open(os.path.join(cwd,'.config/summary.json')).read())
  68. self.repository = git.Repo.init(cwd)
  69. self.repository.index.add(['assets','contents','.config'])
  70. self.repository.index.commit("initial commit")
  71. # TODO: set mdtohtml compiler from project md to app index.html
  72. # TODO: embed project styles.scss to app scss frame work
  73. def saveproject(self, cwd = None):
  74. if not cwd == None and self.tempcwd:
  75. shutil.copytree(self.cwd, cwd)
  76. self.cwd = cwd
  77. self.tempcwd = False
  78. self._mw.setWindowTitle("Cascade – "+self.cwd)
  79. def quit(self):
  80. self.savePreferences()
  81. shutil.rmtree(self.temp, ignore_errors=True)
  82. QCoreApplication.instance().quit()
  83. class MainWindow(QMainWindow):
  84. def __init__(self, core):
  85. super(MainWindow, self).__init__()
  86. # load core class
  87. self.core = core
  88. self.setWindowTitle("Cascade")
  89. self.setWindowIcon(QIcon('assets/images/icon.png'))
  90. self.resize(self.core.mw_size)
  91. self.move(self.core.mw_pos)
  92. self.initMenuBar()
  93. self.initMainStack()
  94. self.show()
  95. def initMenuBar(self):
  96. # menu bar
  97. bar = self.menuBar()
  98. file = bar.addMenu("&File")
  99. new = QAction("&New Project",self)
  100. new.setShortcut("Ctrl+n")
  101. file.addAction(new)
  102. open = QAction("&Open",self)
  103. open.setShortcut("Ctrl+o")
  104. file.addAction(open)
  105. self.save_action = QAction("&Save Project as",self)
  106. self.save_action.setShortcut("Ctrl+Shift+s")
  107. file.addAction(self.save_action)
  108. # if not self.core.tempcwd:
  109. # self.save_action.setEnabled(False)
  110. quit = QAction("&Quit",self)
  111. quit.setShortcut("Ctrl+q")
  112. file.addAction(quit)
  113. file.triggered[QAction].connect(self.onfilemenutrigger)
  114. # edit menu
  115. edit = bar.addMenu("Edit")
  116. edit.addAction("copy")
  117. edit.addAction("paste")
  118. edit.addAction("preferences")
  119. # view menu
  120. view = bar.addMenu("&View")
  121. designview = QAction("&Design",self)
  122. designview.setShortcut("F1")
  123. view.addAction(designview)
  124. contentview = QAction("&Content",self)
  125. contentview.setShortcut("F2")
  126. view.addAction(contentview)
  127. versionview = QAction("&Version",self)
  128. versionview.setShortcut("F3")
  129. view.addAction(versionview)
  130. view.triggered[QAction].connect(self.onviewmenutrigger)
  131. def onfilemenutrigger(self, q):
  132. print(q.text()+" is triggered")
  133. if q.text() == "&New Project":
  134. self.newprojectdialogue()
  135. elif q.text() == "&Open":
  136. self.openprojectdialogue()
  137. elif q.text() == "&Save Project as":
  138. self.saveprojectdialogue()
  139. elif q.text() == "&Quit":
  140. self.quit()
  141. def openprojectdialogue(self):
  142. print("open")
  143. def newprojectdialogue(self):
  144. projectname = QFileDialog.getSaveFileName(self, 'New Project', '')
  145. # TODO: no file type
  146. try:
  147. if not os.path.isdir(projectname[0]):
  148. self.core.initnewproject(projectname[0])
  149. else:
  150. print("folder already exists")
  151. # TODO: check if is cascade folder
  152. except Exception as e:
  153. pass
  154. def saveprojectdialogue(self, quit=False):
  155. projectname = QFileDialog.getSaveFileName(self, 'Save Project', '')
  156. # TODO: no file type
  157. try:
  158. if not os.path.isdir(projectname[0]):
  159. self.core.saveproject(projectname[0])
  160. # self.save_action.setEnabled(False)
  161. if quit:
  162. self.quit()
  163. else:
  164. print("folder already exists")
  165. # TODO: check if is cascade folder
  166. except Exception as e:
  167. pass
  168. def quit(self):
  169. print("Quit")
  170. if self.core.tempcwd:
  171. 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)
  172. if buttonReply == QMessageBox.Yes:
  173. self.saveprojectdialogue(quit=True)
  174. if buttonReply == QMessageBox.No:
  175. self.core.quit()
  176. else:
  177. self.core.quit()
  178. def onviewmenutrigger(self, q):
  179. print(q.text()+" is triggered")
  180. if q.text() == "&Design":
  181. self.mainstack.setCurrentIndex(0)
  182. elif q.text() == "&Content":
  183. self.mainstack.setCurrentIndex(1)
  184. elif q.text() == "&Version":
  185. self.mainstack.setCurrentIndex(2)
  186. def initMainStack(self):
  187. self.mainstack = QStackedWidget()
  188. # self.tabwidget.setContentsMargins(0,0,0,0)
  189. # self.tabwidget.setStyleSheet("""
  190. # QTabWidget::pane {
  191. # border:0px solid inherted;
  192. # margin:0px;
  193. # padding:0px;
  194. # }
  195. # QTabBar::tab {
  196. # padding: 4px;
  197. # font-size:12px;
  198. # }
  199. # QTabBar::tab:selected {
  200. # font-weight:bold;
  201. # }
  202. # """)
  203. self.viewstack = view.ViewStack(self.core)
  204. self.contentstack = content.ContentStack(self.core)
  205. self.versionstack = QLabel("Version (git).")
  206. self.mainstack.addWidget(self.viewstack)
  207. self.mainstack.addWidget(self.contentstack)
  208. self.mainstack.addWidget(self.versionstack)
  209. self.setCentralWidget(self.mainstack)
  210. def main():
  211. app = QApplication(sys.argv)
  212. core = Core()
  213. mainappwindow = MainWindow(core)
  214. core.mainwindow = mainappwindow
  215. sys.exit(app.exec_())
  216. if __name__ == "__main__":
  217. main()