ソースを参照

moved all project assets to project folder

Bachir Soussi Chiadmi 7 年 前
コミット
f73918e5b5

+ 64 - 20
app.py

@@ -22,11 +22,12 @@ from PyQt5.QtWebKitWidgets import QWebPage, QWebView, QWebInspector
 import json
 import git
 
-from classes import server, compiler, design, content
+from classes import server, sasscompiler, design, content
 
 class Core():
    def __init__(self, parent=None):
       # restore previous preferences
+      self.appcwd = os.getcwd()
 
       self.restorePreferences()
       self._mw = False
@@ -34,13 +35,15 @@ class Core():
       # print(self.temp)
 
       self.tempcwd = False
+      # if ther's not current project folder from restorepref
+      # initaite a new temp project
       if(self.cwd == None or not os.path.isdir(self.cwd)):
          self.cwd = os.path.join(self.temp, 'cwd')
          self.tempcwd = True
          self.initnewproject()
 
-      self.server = server.Server(self.temp)
-      self.compiler = compiler.Compiler(self.temp)
+      self.server = server.Server(self)
+      self.sasscompiler = sasscompiler.Compiler(self)
 
    @property
    def mainwindow(self):
@@ -61,6 +64,8 @@ class Core():
       # print(settings.allKeys())
 
       self.cwd = settings.value('core/cwd', None)
+      self.dialog_path = settings.value('core/dialog_path', os.path.expanduser('~'))
+
       self.mw_size = settings.value('mainwindow/size', QtCore.QSize(1024, 768))
       self.mw_pos = settings.value('mainwindow/pos', QtCore.QPoint(0, 0))
       self.mw_curstack = int(settings.value('mainwindow/curstack', 0))
@@ -74,6 +79,8 @@ class Core():
       if not self.tempcwd:
          settings.setValue('core/cwd', self.cwd)
 
+      settings.setValue('core/dialog_path', self.dialog_path)
+
       settings.setValue('mainwindow/size', self._mw.size())
       settings.setValue('mainwindow/pos', self._mw.pos())
       settings.setValue('mainwindow/curstack', self._mw.mainstack.currentIndex())
@@ -82,7 +89,7 @@ class Core():
       if cwd == None :
          cwd = self.cwd
       else :
-         self.cwd = cwd
+         self.changeCWD(cwd)
 
       shutil.copytree('templates/newproject', cwd)
       self.prefs = json.loads(open(os.path.join(cwd,'.config/prefs.json')).read())
@@ -94,11 +101,17 @@ class Core():
       # TODO: embed project styles.scss to app scss frame work
 
    def saveproject(self, cwd = None):
-      if not cwd == None and self.tempcwd:
+      if not cwd == None:
          shutil.copytree(self.cwd, cwd)
-         self.cwd = cwd
          self.tempcwd = False
-         self._mw.setWindowTitle("Cascade – "+self.cwd)
+         self.changeCWD(cwd)
+
+   def changeCWD(self, cwd):
+      self.cwd = cwd
+      self.server.reload()
+      self.sasscompiler.reload()
+      # if not self.tempcwd:
+      self._mw.setWindowTitle("Cascade – "+self.cwd)
 
    def quit(self):
       self.savePreferences()
@@ -113,7 +126,7 @@ class MainWindow(QMainWindow):
       self.core = core
 
       self.setWindowTitle("Cascade")
-      self.setWindowIcon(QIcon('assets/images/icon.png'))
+      self.setWindowIcon(QIcon(os.path.join(self.core.appcwd,'assets/images/icon.png')))
 
       self.resize(self.core.mw_size)
       self.move(self.core.mw_pos)
@@ -140,8 +153,6 @@ class MainWindow(QMainWindow):
       self.save_action = QAction("&Save Project as",self)
       self.save_action.setShortcut("Ctrl+Shift+s")
       file.addAction(self.save_action)
-      # if not self.core.tempcwd:
-      #    self.save_action.setEnabled(False)
 
       quit = QAction("&Quit",self)
       quit.setShortcut("Ctrl+q")
@@ -151,12 +162,19 @@ class MainWindow(QMainWindow):
 
       # edit menu
       edit = bar.addMenu("&Edit")
-      edit.addAction("&copy")
-      edit.addAction("&paste")
+      # edit.addAction("&copy")
+      # edit.addAction("&paste")
       edit.addAction("&build")
-      edit.addAction("&reload")
+
+      self.reload_action = QAction("&Reload",self)
+      self.reload_action.setShortcut("Ctrl+r")
+      edit.addAction(self.reload_action)
+
       edit.addAction("&preferences")
 
+      edit.triggered[QAction].connect(self.oneditmenutrigger)
+
+
       # view menu
       view = bar.addMenu("&View")
 
@@ -194,30 +212,49 @@ class MainWindow(QMainWindow):
       print("open")
 
    def newprojectdialogue(self):
-      projectname = QFileDialog.getSaveFileName(self, 'New Project', '')
+      dialog = QFileDialog()
+      dialog.setFileMode(QFileDialog.Directory)
+      dialog.setAcceptMode(QFileDialog.AcceptOpen)
+      projectname = dialog.getSaveFileName(
+         self,
+         'New Project',
+         self.core.dialog_path
+      )[0]
       # TODO: no file type
       try:
-         if not os.path.isdir(projectname[0]):
-            self.core.initnewproject(projectname[0])
+         head, tail = os.path.split(projectname)
+         self.core.dialog_path = head
+         if not os.path.isdir(projectname):
+            self.core.initnewproject(projectname)
          else:
             print("folder already exists")
             # TODO: check if is cascade folder
       except Exception as e:
+         print('Exception', e)
          pass
 
    def saveprojectdialogue(self, quit=False):
-      projectname = QFileDialog.getSaveFileName(self, 'Save Project', '')
+      dialog = QFileDialog()
+      dialog.setFileMode(QFileDialog.Directory)
+      dialog.setAcceptMode(QFileDialog.AcceptOpen)
+      projectname = dialog.getSaveFileName(
+         self,
+         'Save Project',
+         self.core.dialog_path
+      )[0]
       # TODO: no file type
       try:
-         if not os.path.isdir(projectname[0]):
-            self.core.saveproject(projectname[0])
-            # self.save_action.setEnabled(False)
+         head, tail = os.path.split(projectname)
+         self.core.dialog_path = head
+         if not os.path.isdir(projectname):
+            self.core.saveproject(projectname)
             if quit:
                self.quit()
          else:
             print("folder already exists")
             # TODO: check if is cascade folder
       except Exception as e:
+         print('Exception', e)
          pass
 
    def quit(self):
@@ -231,6 +268,13 @@ class MainWindow(QMainWindow):
       else:
          self.core.quit()
 
+
+   def oneditmenutrigger(self, q):
+      print(q.text()+" is triggered")
+      if q.text() == "&Reload":
+         self.designstack.webkitview.reload()
+
+
    def onviewmenutrigger(self, q):
       print(q.text()+" is triggered")
       if q.text() == "&Design":

+ 0 - 68
assets/js/script.js

@@ -1,68 +0,0 @@
-jQuery(document).ready(function($) {
-
-  console.log("Hello Les notices");
-
-  // $('.story-page').each(function(index, el) {
-  //   $figures = $('figure', this);
-  //   $(this).addClass("figures-"+$figures.length);
-  // });
-
-  $('.story-page-2 h2, .story-page:not(.story-page-0):not(.story-page-1):not(.story-page-2) h1').each(function(index, el) {
-    // console.log("item to typotize",$(this).text());
-    var chars = $(this).text().split("");
-    // console.log("chars", chars);
-    var typotized = "";
-    var k = 0;
-    for (var j = 0; j < chars.length; j++) {
-      // console.log('node '+j+" modulo : "+(j % 6),chars[j]);
-      if(! /\s/.test(chars[j]) ){
-        k++;
-        if ( k % 12 == 0){
-          typotized += '<span class="typo-4">'+chars[j]+'</span>';
-          continue;
-        }
-        if ( k % 9 == 0){
-          typotized += '<span class="typo-3">'+chars[j]+'</span>';
-          continue;
-        }
-        if ( k % 6 == 0){
-          typotized += '<span class="typo-2">'+chars[j]+'</span>';
-          continue;
-        }
-        if ( k % 3 == 0){
-          typotized += '<span class="typo-1">'+chars[j]+'</span>';
-          continue;
-        }
-      }
-      typotized += chars[j];
-    }
-    $(this).html(typotized);
-  });
-
-/*
-  // Detect if a flow element is in odd or even paper
-
-  // var flow = document.webkitGetFlowByName('flow-main');
-  // var flow = NamedFlowMap;//();//getFlowByName("flow-main");
-  // console.log('flow', window);
-  var namedFlow = document.webkitGetNamedFlows()["flow-main"];
-  console.log(namedFlow);
-  // var regions = namedFlow.getRegions();
-  // var content = namedFlow.getContent();
-
-  setTimeout(function(){
-    var region, paper, paperid;
-    $(".story-page>h1,.story-page>figure", "#flow-main").each(function(index, el) {
-      region = namedFlow.getRegionsByContent(this);
-      // paper = $(region).parents('.paper');
-      paperid = $(region).parents('.paper').attr('id').match(/page-(\d+)/)[1];
-      // console.log(paperid);
-      if(paperid % 2 == 0){
-        $(this).addClass('paper-odd')
-      }else{
-        $(this).addClass('paper-even')
-      }
-    });
-  }, 1000);
-*/
-});

+ 0 - 297
assets/scss/styles.scss

@@ -1,297 +0,0 @@
-// your styles here
-
-$bgcolor:white;
-
-.paper, .preview .page {
-  overflow: hidden;
-  background-color: $bgcolor;
-}
-
-
-#stories{
-  font-family: "Vremena Grotesk" sans-serif;
-}
-
-.story-page{
-  @extend .w9;
-  // -webkit-region-break-after:always;
-  //                break-after:always;
-  // -webkit-region-break-inside:auto;
-  // region-break-inside: auto;
-  // -webkit-region-fragment: break;
-
-}
-
-.story-page-0,
-.story-page-1,
-.story-page-2{
-  @extend .h12;
-  // overflow: visible;
-  // position: relative;
-  -webkit-region-break-after:always;
-                break-after:always;
-  -webkit-region-break-inside: avoid;
-                break-inside: avoid;
-}
-
-
-
-figure, img{
-  margin:0; padding:0;
-  max-width: 100%;
-}
-
-//  footer / pagination
-.paper {
-  .body:before, .body:after{
-    // display: block;
-    display:inline-block;
-    width:auto;
-    .debug &{
-      outline: 1px solid green;
-    }
-  }
-  .body:before{
-    top:50%;
-    width:50mm;
-    margin-top: -25mm;
-    text-align: center;
-  }
-  .body:after{
-    bottom:-5mm;
-    width:15mm;
-  }
-}
-// Footer
-/*gauche*/
-.paper:nth-child(odd) .body:before {
-  transform-origin: right;
-  transform: rotateZ(-90deg);
-  right:-7mm;
-}
-/*droite*/
-.paper:nth-child(even) .body:before {
-  transform-origin: left;
-  transform: rotateZ(90deg);
-  left:-7mm;
-}
-
-// Pagination
-// gauche
-.paper:nth-child(odd) .body:after{
-    text-align: right;
-    right:-8mm;
-}
-// droite
-.paper:nth-child(even) .body:after{
-    text-align: left;
-    left:-8mm;
-}
-
-
-#page-1, #page-2{
-  .body:before, .body:after{
-    display: none;
-  }
-  .body{
-    top:0; right:0; bottom:0; left:0;
-  }
-  .bloc{
-    top:0; right:0; bottom:0; left:0;
-  }
-}
-
-
-.story-page-0, .story-page-1{
-  width:100%;
-  height:100%;
-  h1{
-      margin:0 auto;
-      width:mm2pt(150);
-      font-family: 'Vremena Grotesk';
-      font-weight: 500;
-      font-size: 95pt;
-      text-transform: uppercase;
-      text-align: center;
-      line-height: 1.4;
-      letter-spacing: 0.2em;
-      -webkit-region-break-inside:avoid;
-                     break-inside:avoid;
-
-    }
-}
-.story-page-0{
-  h1{
-    transform: translateX(4mm) translateY(-13mm);
-  }
-}
-.story-page-1{
-  h1{
-    transform: translateX(-65mm) translateY(-20mm);
-  }
-}
-
-
-.story-page-2{
-  height:auto;
-  h2{
-    text-align: center;
-    font-family: "Vremena";
-    font-size: 25pt;
-    font-weight: 400;
-    padding-top:mm2pt(55);
-    padding-left: 2.8em;
-    padding-right: 2.8em;
-  }
-}
-
-.typo-1{
-  font-family: "Fantasque";
-  font-weight: bold;
-  font-style: italic;
-}
-.typo-2{
-  font-family: "Vremena";
-}
-.typo-3{
-  font-family: "Vremena Grotesk";
-  font-weight: bold;
-}
-.typo-4{
-  font-family: "Gap Sans"
-}
-
-.story-page{
-  margin-bottom: 10mm;
-}
-
-.story-page:not(.story-page-0):not(.story-page-1):not(.story-page-2){
-  h1{
-    // -webkit-region-break-before: auto;
-    -webkit-region-break-inside: avoid;
-    -webkit-region-break-after: avoid;
-
-    margin: 0 0 5mm 0;
-    margin-right: -$page-margin-inside*0.5;
-
-    font-size: 40pt;
-    font-weight: normal;
-    line-height: 35pt;
-
-    // &.paper-odd{
-    text-align: right;
-    padding-left: 20mm;
-    // }
-    &.paper-even{
-      text-align: left;
-      padding-left: 0;
-      padding-right: 20mm;
-      margin: 0 0 5mm 0;
-      margin-left: -$page-margin-inside*0.5;
-    }
-  }
-
-  figure{
-    // -webkit-region-break-before: avoid;
-    -webkit-region-break-inside: avoid;
-    // -webkit-region-break-after: avoid;
-
-    position: relative;
-
-    $iw:35mm; // image width
-    $bw:4pt;  // border width
-
-    max-width: $iw+$bw*3;
-
-    img{
-      max-width: $iw;
-      border:$bw solid black;
-      border-left: $bw*2 solid black;
-    }
-
-    figcaption{
-      font-size: 8pt;
-      line-height: 9.5pt;
-      max-width: 100%;
-      padding-left: $bw*2;
-    }
-
-    // &.paper-odd{
-    float: left;
-    margin:0 4mm 2mm 0;
-    margin-left: -$page-margin-outside - $bw;
-    // }
-    &.paper-even{
-      float: right;
-      margin:0 0 2mm 4mm;
-      margin-right: -$page-margin-outside - $bw;
-      text-align: right;
-
-      img{
-        border:$bw solid black;
-        border-right: $bw*2 solid black;
-      }
-
-      figcaption{
-        padding-right: $bw*2;
-      }
-    }
-
-  }
-
-  p{
-    font-family: "Averia Serif";
-    font-size: 9pt;
-    line-height: 13pt;
-    margin-top: 0;
-    -webkit-hyphens: auto;
-    // -webkit-region-break-before: always;
-    // -webkit-region-break-inside: auto;
-    // -webkit-region-break-after: always;
-    // &:nth-of-type(1){
-    //   -webkit-region-break-before:avoid;
-    //   -webkit-region-break-inside:auto;
-    // }
-  }
-
-  &:after{
-    content: "";
-    display: block;
-    float: none;
-    clear: both;
-  }
-}
-/*
-@-webkit-region .paper .flow-main {
-  h1{
-    // color: red!important;
-  }
-}
-
-@-webkit-region .paper:nth-child(even) .flow-main {
-  h1{
-    color: purple;
-    text-align: right;
-    padding-left: 3mm;
-  }
-  figure{
-    float: left;
-    margin-left: -$page-margin-outside;
-    margin:0 4mm 2mm 0;
-  }
-}
-
-
-@-webkit-region .paper:nth-child(odd) .flow-main {
-  h1{
-    color: blue;
-    text-align: left;
-    padding-right: 3mm;
-  }
-  figure{
-    float: right;
-    margin-left: -$page-margin-outside;
-    margin:0 0 2mm 4mm;
-  }
-}
-*/

+ 0 - 26
classes/compiler.py

@@ -1,26 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-from PyQt5.QtCore import QFileSystemWatcher
-import sass
-
-class Compiler():
-   def __init__(self,parent=None):
-      paths = [
-         'assets',
-         'assets/scss',
-         'assets/scss/styles.scss'
-      ]
-      self.fs_watcher = QFileSystemWatcher(paths)
-      # self.fs_watcher.directoryChanged.connect(self.directory_changed)
-      self.fs_watcher.fileChanged.connect(self.compile_scss)
-      self.compile_scss()
-
-   # def directory_changed(path):
-   #    print("Directory changed : %s" % path)
-
-   def compile_scss(path = ""):
-      print("compiling sass : %s" % path)
-      scss = sass.compile_file(b'assets/scss/main.scss')
-      with open('assets/scss/main.css', 'w') as fp:
-         fp.write(scss.decode('utf8'))

+ 8 - 6
classes/content.py

@@ -24,8 +24,8 @@ class Summary(QWidget):
       super(Summary, self).__init__(parent)
       self.parent = parent
 
-      self.jsonfilepath = os.path.join(self.parent.core.cwd,'.config/summary.json')
-      sum_json = open(self.jsonfilepath).read()
+      jsonfilepath = os.path.join(self.parent.core.cwd,'.config/summary.json')
+      sum_json = open(jsonfilepath).read()
       self.sum = json.loads(sum_json)
 
       vbox = QVBoxLayout()
@@ -43,13 +43,14 @@ class Summary(QWidget):
       # file
       filename = re.sub(r'\W', "_", text)+".md"
       # TODO: check if file does not already exists
-      filepath = os.path.join(self.core.cwd,'contents',filename)
+      filepath = os.path.join(self.parent.core.cwd,'contents',filename)
       with open(filepath, 'w') as fp:
          fp.write('#'+text)
       # json
       item = {"title":text,"file":filename}
       self.sum.append(item)
-      with open(self.jsonfilepath, "w") as fp:
+      jsonfilepath = os.path.join(self.parent.core.cwd,'.config/summary.json')
+      with open(jsonfilepath, "w") as fp:
          json.dump(self.sum, fp, ensure_ascii=False, indent="\t")
       # refresh list
       self.list.addNewItem(item)
@@ -59,11 +60,12 @@ class Summary(QWidget):
       newdata = []
       for i in range(0,self.list.count()):
          # print(self.item(i).item['title'])
-         newdata.append(self.list.item(i).item)
+         newdata.append(self.list.item(i).data)
 
       # print(newdata)
       self.sum = newdata
-      with open(self.jsonfilepath, "w") as fp:
+      jsonfilepath = os.path.join(self.parent.core.cwd,'.config/summary.json')
+      with open(jsonfilepath, "w") as fp:
          json.dump(newdata, fp, ensure_ascii=False, indent="\t")
 
 

+ 3 - 2
classes/design.py

@@ -25,6 +25,7 @@ class WebkitInspector(QWebInspector):
       super(WebkitInspector, self).__init__(parent)
       self.webkitview = webkitview
       self.setPage(self.webkitview.page())
+      self.showMaximized()
       # TODO: webkitinspector is disappearing when chaging tabs
 
 
@@ -73,7 +74,7 @@ class Editor(QWidget):
       # Initialize tab screen
       self.tabs = QTabWidget()
 
-      self.scsstab = CodeEditor(core, self.tabs, 'assets/scss/styles.scss')
+      self.scsstab = CodeEditor(core, self.tabs, 'assets/css/styles.scss')
       self.jstab = CodeEditor(core, self.tabs, 'assets/js/script.js')
 
       # Add tabs
@@ -153,6 +154,6 @@ class DesignStack(QWidget):
 
    def movedSplitter(self):
       settings = QSettings('FiguresLibres', 'Cascade')
-      print(self.vsplitter.sizes())
+      # print(self.vsplitter.sizes())
       settings.setValue('design/vsplitter/sizes', self.vsplitter.sizes())
       settings.setValue('design/hsplitter/sizes', self.hsplitter.sizes())

+ 43 - 0
classes/sasscompiler.py

@@ -0,0 +1,43 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+import os
+from PyQt5.QtCore import QFileSystemWatcher
+import sass
+
+class Compiler():
+   def __init__(self,parent):
+      self.parent = parent
+      self.initWatching()
+      self.compile_scss()
+   # def directory_changed(path):
+   #    print("Directory changed : %s" % path)
+
+   def initWatching(self):
+      self.refreshPaths()
+      self.fs_watcher = QFileSystemWatcher(self.paths)
+      # self.fs_watcher.directoryChanged.connect(self.directory_changed)
+      self.fs_watcher.fileChanged.connect(self.compile_scss)
+
+   def compile_scss(self):
+      print("compiling sass")
+      try:
+         scss = sass.compile_file(str.encode(os.path.join(self.parent.cwd,'assets/css/main.scss')))
+         with open(os.path.join(self.parent.cwd,'assets/css/main.css'), 'w') as fp:
+            fp.write(scss.decode('utf8'))
+      except Exception as e:
+         print("Error compiling Sass", e)
+         pass
+
+
+   def refreshPaths(self):
+      self.paths = [
+         os.path.join(self.parent.cwd,'assets'),
+         os.path.join(self.parent.cwd,'assets/css'),
+         os.path.join(self.parent.cwd,'assets/css/styles.scss')
+      ]
+
+   def reload(self):
+      self.fs_watcher.removePaths(self.paths)
+      self.refreshPaths()
+      self.fs_watcher.addPaths(self.paths)

+ 16 - 4
classes/server.py

@@ -13,8 +13,9 @@ import threading
 
 class Server():
 
-   def __init__(self, parent=None):
+   def __init__(self, parent):
 
+      self.parent = parent
       # find free port
       sock = socket()
       sock.bind(('', 0))
@@ -22,13 +23,24 @@ class Server():
       self._port = sock.getsockname()[1]
       sock.close()
 
-      self.httpd = http.server.HTTPServer(('', self.port), http.server.SimpleHTTPRequestHandler)
-      self.thread = threading.Thread(target=self.httpd.serve_forever)
+      # self.initial_cwd = os.getcwd()
+      self.thread = threading.Thread(target=self.webserver)
       self.thread.daemon = True
       self.thread.start()
-      print("serving at port", self._port)
+      # os.chdir(self.initial_cwd)
 
+   def webserver(self):
+      os.chdir(self.parent.cwd)
+      self.httpd = http.server.HTTPServer(('', self.port), http.server.SimpleHTTPRequestHandler)
+      self.httpd.serve_forever()
+      print("serving at port", self._port)
 
    @property
    def port(self):
         return self._port
+
+   def reload(self):
+      # self.thread.shutdown()
+      os.chdir(self.parent.cwd)
+      # self.thread.start()
+      # os.chdir(self.initial_cwd)

+ 0 - 0
assets/scss/debug.scss → templates/newproject/assets/css/debug.scss


+ 0 - 0
assets/scss/grid.scss → templates/newproject/assets/css/grid.scss


+ 0 - 0
assets/scss/html2print.scss → templates/newproject/assets/css/html2print.scss


+ 0 - 0
assets/scss/layout.scss → templates/newproject/assets/css/layout.scss


+ 0 - 0
assets/scss/main.scss → templates/newproject/assets/css/main.scss


+ 0 - 0
assets/scss/mixins.scss → templates/newproject/assets/css/mixins.scss


+ 0 - 0
templates/newproject/assets/scss/styles.scss → templates/newproject/assets/css/styles.scss


+ 0 - 0
assets/js/html2print.js → templates/newproject/assets/js/html2print.js


+ 0 - 0
assets/js/setup.js → templates/newproject/assets/js/setup.js


+ 0 - 0
assets/lib/css-regions-polyfill.min.js → templates/newproject/assets/lib/css-regions-polyfill.min.js


+ 0 - 0
assets/lib/jquery.min.js → templates/newproject/assets/lib/jquery.min.js


+ 1 - 1
index.html → templates/newproject/index.html

@@ -3,7 +3,7 @@
   <head>
     <meta charset="utf-8">
     <title>Cascade</title>
-    <link rel="stylesheet" href="assets/scss/main.css">
+    <link rel="stylesheet" href="assets/css/main.css">
   </head>
   <body>
     <h1>Cascade</h1>