Esempio n. 1
0
    def __init__(self):
        QWidget.__init__(self)

        from widgets.content import ContentType
        from widgets.flatbutton import FlatButton
        from widgets.hyperlink import HyperLink
        from widgets.section import Section

        self.editButton = FlatButton(":/images/edit_normal.png",
                                     ":/images/edit_hover.png")
        self.copyButton = FlatButton(":/images/copy_normal.png",
                                     ":/images/copy_hover.png")
        self.deleteButton = FlatButton(":/images/trash_normal.png",
                                       ":/images/trash_hover.png")
        self.addColumns = HyperLink(
            QCoreApplication.translate("RowEditor", "(+) Add Columns"))
        self.editButton.setToolTip(
            QCoreApplication.translate("RowEditor", "Edit Row"))
        self.deleteButton.setToolTip(
            QCoreApplication.translate("RowEditor", "Delete Row"))
        self.copyButton.setToolTip(
            QCoreApplication.translate("RowEditor", "Copy Row"))
        self.editButton.setMaximumWidth(24)
        self.copyButton.setMaximumWidth(24)
        self.deleteButton.setMaximumWidth(24)
        vbox = QVBoxLayout()
        vbox.setAlignment(Qt.AlignTop)
        vbox.setSpacing(5)
        vbox.addWidget(self.editButton)
        vbox.addWidget(self.copyButton)
        vbox.addWidget(self.deleteButton, 0, Qt.AlignBottom)
        layout = QHBoxLayout()

        pal = self.palette()
        pal.setColor(QPalette.Background,
                     QColor(self.palette().alternateBase().color()))
        self.setPalette(pal)
        self.setAutoFillBackground(True)

        self.highlightedRect = QRect()
        self.layout = QGridLayout()
        self.layout.addWidget(self.addColumns, 0, 0, 1, 1, Qt.AlignCenter)
        self.layout.setColumnStretch(0, 1)

        layout.addItem(vbox)
        layout.addLayout(self.layout)
        self.setLayout(layout)

        self.deleteButton.clicked.connect(self.delete)
        self.copyButton.clicked.connect(self.copy)
        self.editButton.clicked.connect(self.edit)
        self.addColumns.clicked.connect(self.insertColumns)
Esempio n. 2
0
    def __init__(self):
        QWidget.__init__(self)
        self.content = None
        self.type = ""
        self.setAutoFillBackground(True)
        self.setMinimumWidth(120)
        self.setMinimumHeight(50)
        self.setMaximumHeight(50)
        self.zoom = False

        self.mode = Mode.EMPTY
        self.normalColor = QColor(
            self.palette().base().color().name()).lighter().name()
        self.enabledColor = self.palette().base().color().name()
        self.dropColor = QColor(
            self.palette().base().color().name()).lighter().lighter().name()
        self.setColor(self.normalColor)
        self.link = HyperLink(
            QCoreApplication.translate("ElementEditor", "(+) Insert Module"))

        self.editButton = FlatButton(":/images/edit_normal.png",
                                     ":/images/edit_hover.png")
        self.copyButton = FlatButton(":/images/copy_normal.png",
                                     ":/images/copy_hover.png")
        self.deleteButton = FlatButton(":/images/trash_normal.png",
                                       ":/images/trash_hover.png")
        self.editButton.setVisible(False)
        self.copyButton.setVisible(False)
        self.deleteButton.setVisible(False)
        self.editButton.setToolTip(
            QCoreApplication.translate("ElementEditor", "Edit Element"))
        self.deleteButton.setToolTip(
            QCoreApplication.translate("ElementEditor", "Delete Element"))
        self.copyButton.setToolTip(
            QCoreApplication.translate("ElementEditor", "Copy Element"))
        self.text = QLabel(QCoreApplication.translate("ElementEditor", "Text"))
        self.text.setVisible(False)
        layout = QHBoxLayout()
        layout.addWidget(self.link, 0, Qt.AlignCenter)
        layout.addWidget(self.editButton)
        layout.addWidget(self.copyButton)
        layout.addWidget(self.text, 1, Qt.AlignCenter)
        layout.addWidget(self.deleteButton)
        self.setLayout(layout)

        self.editButton.clicked.connect(self.edit)
        self.deleteButton.clicked.connect(self.delete)
        self.copyButton.clicked.connect(self.copy)
        self.link.clicked.connect(self.enable)
Esempio n. 3
0
 def __init__(self):
     QWidget.__init__(self)
     self.placeholder = QWidget()
     hbox = QHBoxLayout()
     hbox.setAlignment(Qt.AlignLeft)
     hbox.setSpacing(10)
     addSection = HyperLink("(+) Add Section")
     addFullSection = HyperLink("(+) Add Full Width Section")
     l = QVBoxLayout()
     self.layout = QVBoxLayout()
     l.addLayout(self.layout)
     l.addWidget(self.placeholder)
     hbox.addWidget(addSection)
     hbox.addWidget(addFullSection)
     self.layout.addLayout(hbox)
     self.layout.addStretch()
     self.setLayout(l)
     self.setAcceptDrops(True)
     addSection.clicked.connect(self.addNormalSection)
     addFullSection.clicked.connect(self.addFullSection)
Esempio n. 4
0
class ElementEditor(QWidget):
    elementCopied = pyqtSignal(object)
    elementEnabled = pyqtSignal()
    elementDragged = pyqtSignal()

    def __init__(self):
        QWidget.__init__(self)
        self.content = None
        self.type = ""
        self.setAutoFillBackground(True)
        self.setMinimumWidth(120)
        self.setMinimumHeight(50)
        self.setMaximumHeight(50)
        self.zoom = False

        self.mode = Mode.EMPTY
        self.normalColor = QColor(
            self.palette().base().color().name()).lighter().name()
        self.enabledColor = self.palette().base().color().name()
        self.dropColor = QColor(
            self.palette().base().color().name()).lighter().lighter().name()
        self.setColor(self.normalColor)
        self.link = HyperLink(
            QCoreApplication.translate("ElementEditor", "(+) Insert Module"))

        self.editButton = FlatButton(":/images/edit_normal.png",
                                     ":/images/edit_hover.png")
        self.copyButton = FlatButton(":/images/copy_normal.png",
                                     ":/images/copy_hover.png")
        self.deleteButton = FlatButton(":/images/trash_normal.png",
                                       ":/images/trash_hover.png")
        self.editButton.setVisible(False)
        self.copyButton.setVisible(False)
        self.deleteButton.setVisible(False)
        self.editButton.setToolTip(
            QCoreApplication.translate("ElementEditor", "Edit Element"))
        self.deleteButton.setToolTip(
            QCoreApplication.translate("ElementEditor", "Delete Element"))
        self.copyButton.setToolTip(
            QCoreApplication.translate("ElementEditor", "Copy Element"))
        self.text = QLabel(QCoreApplication.translate("ElementEditor", "Text"))
        self.text.setVisible(False)
        layout = QHBoxLayout()
        layout.addWidget(self.link, 0, Qt.AlignCenter)
        layout.addWidget(self.editButton)
        layout.addWidget(self.copyButton)
        layout.addWidget(self.text, 1, Qt.AlignCenter)
        layout.addWidget(self.deleteButton)
        self.setLayout(layout)

        self.editButton.clicked.connect(self.edit)
        self.deleteButton.clicked.connect(self.delete)
        self.copyButton.clicked.connect(self.copy)
        self.link.clicked.connect(self.enable)

    def enable(self):
        from widgets.columneditor import ColumnEditor
        from widgets.sectioneditor import SectionEditor
        dlg = ModulDialog()
        dlg.exec()

        if not dlg.result:
            return
        editor = Plugins.element_plugins[dlg.result]
        self.content = editor.getDefaultContent()
        if isinstance(self.parentWidget(), ColumnEditor):
            self.parentWidget().column._items.append(self.content)
        elif isinstance(self.parentWidget(), SectionEditor):
            self.parentWidget().section._items.append(self.content)
        self.type = editor.tag_name
        self.text.setText(editor.display_name)

        self.setMode(Mode.ENABLED)
        self.elementEnabled.emit()
        self.edit()

    def copy(self):
        self.elementCopied.emit(self)

    def delete(self):
        self.parentWidget().removeElement(self.content)
        self.parentWidget().layout.removeWidget(self)
        self.hide()
        ce = self.getContentEditor()
        if ce:
            ce.editChanged("Delete Element")

    def edit(self):
        ce = self.getContentEditor()
        if ce:
            ce.elementEdit(self)

    def setColor(self, name):
        pal = self.palette()
        pal.setColor(QPalette.Background, QColor(name))
        self.setPalette(pal)

    def setMode(self, mode):
        self.mode = mode
        if mode == Mode.EMPTY:
            self.link.setVisible(True)
            self.editButton.setVisible(False)
            self.copyButton.setVisible(False)
            self.deleteButton.setVisible(False)
            self.text.setVisible(False)
            self.setColor(self.normalColor)
        elif mode == Mode.ENABLED:
            self.link.setVisible(False)
            self.editButton.setVisible(True)
            self.copyButton.setVisible(True)
            self.deleteButton.setVisible(True)
            self.text.setVisible(True)
            self.setColor(self.enabledColor)
        elif mode == Mode.DROPZONE:
            self.link.setVisible(False)
            self.editButton.setVisible(False)
            self.copyButton.setVisible(False)
            self.deleteButton.setVisible(False)
            self.text.setVisible(True)
            self.text.setText(
                QCoreApplication.translate("ElementEditor", "Drop Here"))
            self.setColor(self.dropColor)

    def getContentEditor(self):
        se = self.getSectionEditor()
        if se:
            pe = se.parentWidget()
            if pe:
                sa = pe.parentWidget()
                if sa:
                    vp = sa.parentWidget()
                    if vp:
                        cee = vp.parentWidget()
                        if cee:
                            return cee
        return None

    def getSectionEditor(self):
        from widgets.sectioneditor import SectionEditor
        from widgets.columneditor import ColumnEditor
        se = self.parentWidget()
        if isinstance(se, SectionEditor):
            return se
        elif isinstance(se, ColumnEditor):
            re = se.parentWidget()
            if re:
                se = re.parentWidget()
                if se:
                    return se
        return None

    def getContent(self):
        return self.content

    def setContent(self, content):
        self.content = content
        self.type = content.tag_name
        if content.adminlabel:
            self.text.setText(content.adminlabel)
        else:
            if content.display_name:
                self.text.setText(content.display_name)
            else:
                self.text.setText(content.tag_name)

    def mousePressEvent(self, event):
        from widgets.columneditor import ColumnEditor
        from widgets.sectioneditor import SectionEditor
        if self.mode != Mode.ENABLED or event.button() != Qt.LeftButton:
            return

        if self.parentWidget().layout.count() == 1:
            self.elementDragged.emit()

        mimeData = WidgetMimeData()
        mimeData.setData(self)
        parent = self.parentWidget()
        if isinstance(parent, ColumnEditor):
            mimeData.source_list = parent.column._items
        elif isinstance(parent, SectionEditor):
            mimeData.source_list = parent.section._items

        pixmap = QPixmap(self.size())
        self.render(pixmap)

        drag = QDrag(self)
        drag.setMimeData(mimeData)
        drag.setHotSpot(event.pos())
        drag.setPixmap(pixmap)
        self.hide()

        if drag.exec(Qt.MoveAction) == Qt.IgnoreAction:
            self.show()

    def dropped(self):
        #seems to be a bug that after dropping the item the bgcolor changes
        self.setColor(self.enabledColor)
Esempio n. 5
0
    def __init__(self, fullwidth):
        QWidget.__init__(self)
        from widgets.hyperlink import HyperLink
        from widgets.flatbutton import FlatButton
        from widgets.section import Section
        from widgets.content import ContentType
        from widgets.elementeditor import ElementEditor, Mode

        self.fullwidth = fullwidth
        self.section = None
        self.id = None
        self.cssclass = None
        self.style = None
        self.attributes = None
        self.setAutoFillBackground(True)
        self.setAcceptDrops(True)
        self.setBGColor()
        vbox = QVBoxLayout()
        vbox.setAlignment(Qt.AlignTop)
        vbox.setSpacing(5)
        self.edit_button = FlatButton(":/images/edit_normal.png",
                                      ":/images/edit_hover.png")
        self.copy_button = FlatButton(":/images/copy_normal.png",
                                      ":/images/copy_hover.png")
        self.delete_button = FlatButton(":/images/trash_normal.png",
                                        ":/images/trash_hover.png")
        self.edit_button.setToolTip("Edit Section")
        self.delete_button.setToolTip("Delete Section")
        self.copy_button.setToolTip("Copy Section")
        self.edit_button.setMaximumWidth(24)
        self.copy_button.setMaximumWidth(24)
        self.delete_button.setMaximumWidth(24)
        vbox.addWidget(self.edit_button)
        vbox.addWidget(self.copy_button)
        vbox.addWidget(self.delete_button)

        vboxRight = QVBoxLayout()
        vboxRight.setAlignment(Qt.AlignLeft)
        layout = QHBoxLayout()
        self.layout = QVBoxLayout()
        layout.addLayout(vbox)
        addRow = HyperLink("(+) Add Row")
        vboxRight.addLayout(self.layout)

        if self.fullwidth:
            ee = ElementEditor()
            ee.elementEnabled.connect(self.addElement)
            ee.elementDragged.connect(self.addElement)

            # connect(ee, SIGNAL(elementCopied(ElementEditor*)), self, SLOT(copyElement(ElementEditor*)))

            self.layout.addWidget(ee, 0, Qt.AlignTop)
        else:
            vboxRight.addWidget(addRow)
        layout.addLayout(vboxRight)
        self.setLayout(layout)

        self.delete_button.clicked.connect(self.delete)
        self.copy_button.clicked.connect(self.copy)
        addRow.clicked.connect(self.addRow)
        self.edit_button.clicked.connect(self.edit)
class MainWindow(QMainWindow):
    siteLoaded = pyqtSignal(object)

    def __init__(self):
        QMainWindow.__init__(self)
        self.site = None
        self.editor = ""
        self.install_directory = os.getcwd()
        self.content_after_animation = ""
        self.default_path = ""
        self.method_after_animation = ""

        Generator.install_directory = self.install_directory

        self.initUndoRedo()
        self.initGui()
        self.readSettings()
        self.loadPlugins()

        if self.default_path:
            if self.loadProject(os.path.join(self.default_path, "Site.qml")):
                gen = Generator()
                gen.generateSite(self, self.site)

        self.dashboard.setExpanded(True)
        self.showDashboard()
        self.statusBar().showMessage(
            QCoreApplication.translate("MainWindow", "Ready"))

    def actualThemeChanged(self, themename):
        self.theme_settings_button.setVisible(False)
        for name in Plugins.themePluginNames():
            tei = Plugins.getThemePlugin(name)
            if tei:
                if tei.theme_name == themename:
                    self.theme_settings_button.setVisible(True)
                    break

    def loadProject(self, filename):
        self.default_path = filename[0:-9]  # - /Site.qml
        if self.reloadProject(filename):
            # create temp dir for undo redo
            tempPath = self.site.source_path[self.site.source_path.rfind("/") +
                                             1:]
            temp = QDir(os.path.join(QDir.tempPath(), "FlatSiteBuilder"))
            temp.mkdir(tempPath)
            temp.cd(tempPath)
            temp.mkdir("pages")
            temp.mkdir("posts")

            # in case these subfolders were empty and not published to github
            dir = QDir(self.site.source_path)
            dir.mkdir("pages")
            dir.mkdir("posts")
            dir.mkdir("assets")
            dir.cd("assets")
            dir.mkdir("images")
            return True
        else:
            return False

    def initUndoRedo(self):
        self.undoStack = QUndoStack()
        temp = QDir(os.path.join(QDir.tempPath(), "FlatSiteBuilder"))
        if temp.exists():
            temp.removeRecursively()
        temp.setPath(QDir.tempPath())
        temp.mkdir("FlatSiteBuilder")

    def initGui(self):
        self.installEventFilter(self)
        self.dashboard = Expander(
            QCoreApplication.translate("MainWindow", "Dashboard"),
            ":/images/dashboard_normal.png", ":/images/dashboard_hover.png",
            ":/images/dashboard_selected.png")
        self.content = Expander(
            QCoreApplication.translate("MainWindow",
                                       "Content"), ":/images/pages_normal.png",
            ":/images/pages_hover.png", ":/images/pages_selected.png")
        self.appearance = Expander(
            QCoreApplication.translate("MainWindow", "Appearance"),
            ":/images/appearance_normal.png", ":/images/appearance_hover.png",
            ":/images/appearance_selected.png")
        self.settings = Expander(
            QCoreApplication.translate("MainWindow", "Settings"),
            ":/images/settings_normal.png", ":/images/settings_hover.png",
            ":/images/settings_selected.png")

        self.setWindowTitle(QCoreApplication.applicationName() + " " +
                            QCoreApplication.applicationVersion())
        vbox = QVBoxLayout()
        vbox.addWidget(self.dashboard)
        vbox.addWidget(self.content)
        vbox.addWidget(self.appearance)
        vbox.addWidget(self.settings)
        vbox.addStretch()

        content_box = QVBoxLayout()
        pages_button = HyperLink(
            QCoreApplication.translate("MainWindow", "Pages"))
        posts_button = HyperLink(
            QCoreApplication.translate("MainWindow", "Posts"))
        content_box.addWidget(pages_button)
        content_box.addWidget(posts_button)
        self.content.addLayout(content_box)

        app_box = QVBoxLayout()
        themes_button = HyperLink(
            QCoreApplication.translate("MainWindow", "Themes"))
        menus_button = HyperLink(
            QCoreApplication.translate("MainWindow", "Menus"))
        self.theme_settings_button = HyperLink(
            QCoreApplication.translate("MainWindow", "Theme Settings"))
        self.theme_settings_button.setVisible(False)
        app_box.addWidget(menus_button)
        app_box.addWidget(themes_button)
        app_box.addWidget(self.theme_settings_button)

        self.appearance.addLayout(app_box)

        scroll_content = QWidget()
        scroll_content.setLayout(vbox)
        scroll = QScrollArea()
        scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        scroll.setWidget(scroll_content)
        scroll.setWidgetResizable(True)
        scroll.setMaximumWidth(200)
        scroll.setMinimumWidth(200)

        self.navigationdock = QDockWidget(
            QCoreApplication.translate("MainWindow", "Navigation"), self)
        self.navigationdock.setAllowedAreas(Qt.LeftDockWidgetArea
                                            | Qt.RightDockWidgetArea)
        self.navigationdock.setWidget(scroll)
        self.navigationdock.setObjectName("Navigation")

        self.addDockWidget(Qt.LeftDockWidgetArea, self.navigationdock)

        self.showDock = FlatButton(":/images/edit_normal.png",
                                   ":/images/edit_hover.png")
        self.showDock.setToolTip(
            QCoreApplication.translate("MainWindow", "Show Navigation"))
        self.statusBar().addPermanentWidget(self.showDock)

        self.dashboard.expanded.connect(self.dashboardExpanded)
        self.dashboard.clicked.connect(self.showDashboard)
        self.content.expanded.connect(self.contentExpanded)
        self.content.clicked.connect(self.showPages)
        self.appearance.expanded.connect(self.appearanceExpanded)
        self.appearance.clicked.connect(self.showMenus)
        self.settings.expanded.connect(self.settingsExpanded)
        self.settings.clicked.connect(self.showSettings)
        menus_button.clicked.connect(self.showMenus)
        pages_button.clicked.connect(self.showPages)
        posts_button.clicked.connect(self.showPosts)
        themes_button.clicked.connect(self.showThemes)
        self.theme_settings_button.clicked.connect(self.showThemesSettings)
        self.showDock.clicked.connect(self.showMenu)
        self.navigationdock.visibilityChanged.connect(
            self.dockVisibilityChanged)

    def showDashboard(self):
        if self.editor:
            self.method_after_animation = "showDashboard"
            self.editor.closeEditor()
            return

        db = Dashboard(self.site, self.default_path)
        db.loadSite.connect(self.loadProject)
        db.previewSite.connect(self.previewSite)
        db.publishSite.connect(self.publishSite)
        db.createSite.connect(self.createSite)
        db.buildSite.connect(self.buildSite)

        self.siteLoaded.connect(db.siteLoaded)
        self.setCentralWidget(db)

    def setCentralWidget(self, widget):
        # do not delete plugin editors
        old_widget = self.takeCentralWidget()
        if not isinstance(old_widget, PublisherInterface) and not isinstance(
                old_widget, ThemeEditorInterface):
            del old_widget
        super().setCentralWidget(widget)
        widget.show()

    def closeEvent(self, event):
        self.writeSettings()
        event.accept()

    def writeSettings(self):
        settings = QSettings(QSettings.IniFormat, QSettings.UserScope,
                             QCoreApplication.organizationName(),
                             QCoreApplication.applicationName())
        settings.setValue("geometry", self.saveGeometry())
        settings.setValue("state", self.saveState())
        if self.site:
            settings.setValue("lastSite", self.site.source_path)

    def readSettings(self):
        settings = QSettings(QSettings.IniFormat, QSettings.UserScope,
                             QCoreApplication.organizationName(),
                             QCoreApplication.applicationName())
        geometry = settings.value("geometry", QByteArray())
        if geometry.isEmpty():
            availableGeometry = QApplication.desktop().availableGeometry(self)
            self.resize(int(availableGeometry.width() / 2),
                        int(availableGeometry.height() / 2))
            self.move(int(((availableGeometry.width() - self.width()) / 2)),
                      int((availableGeometry.height() - self.height()) / 2))
        else:
            self.restoreGeometry(geometry)
            self.restoreState(settings.value("state"))
        self.default_path = settings.value("lastSite")

    def reloadProject(self, filename):
        sys.stdout.flush()
        engine = QQmlEngine()
        self.site_component = component = QQmlComponent(engine)
        self.site_component.loadUrl(QUrl.fromLocalFile(filename))
        self.site = self.site_component.create()
        if self.site is not None:
            self.site.setFilename(filename)
            self.site.setWindow(self)
        else:
            for error in self.site_component.errors():
                print(error.toString())
            return False
        if self.site.output == "":
            self.site.output = "docs"
        self.site.loadMenus()
        self.site.loadPages()
        self.site.loadPosts()

        self.theme_settings_button.setVisible(False)
        Plugins.setActualThemeEditorPlugin("")
        for key in Plugins.themePluginNames():
            tei = Plugins.getThemePlugin(key)
            if tei:
                if tei.theme_name == self.site.theme:
                    Plugins.setActualThemeEditorPlugin(tei.class_name)
                    self.theme_settings_button.setVisible(True)
                    break

        #if not self.site.publisher:
        #    if len(Plugins.publishPluginNames()) > 0:
        #        self.site.publisher = Plugins.publishPluginNames[0]

        Plugins.setActualPublishPlugin(self.site.publisher)
        self.siteLoaded.emit(self.site)
        return True

    def dashboardExpanded(self, value):
        if value:
            self.content.setExpanded(False)
            self.appearance.setExpanded(False)
            self.settings.setExpanded(False)

    def contentExpanded(self, value):
        if value:
            self.dashboard.setExpanded(False)
            self.appearance.setExpanded(False)
            self.settings.setExpanded(False)

    def appearanceExpanded(self, value):
        if value:
            self.dashboard.setExpanded(False)
            self.content.setExpanded(False)
            self.settings.setExpanded(False)

    def settingsExpanded(self, value):
        if value:
            self.dashboard.setExpanded(False)
            self.content.setExpanded(False)
            self.appearance.setExpanded(False)

    def showMenus(self):
        if self.editor:
            self.method_after_animation = "showMenus"
            self.editor.closeEditor()
            return

        edit = MenuList(self, self.site)
        edit.editContent.connect(self.editMenu)
        self.setCentralWidget(edit)

    def showPages(self):
        if self.editor:
            self.method_after_animation = "showPages"
            self.editor.closeEditor()
            return

        list = ContentList(self.site, ContentType.PAGE)
        list.editContent.connect(self.editContent)
        self.setCentralWidget(list)

    def showPosts(self):
        if self.editor:
            self.method_after_animation = "showPosts"
            self.editor.closeEditor()
            return

        list = ContentList(self.site, ContentType.POST)
        list.editContent.connect(self.editContent)
        self.setCentralWidget(list)

    def showThemes(self):
        if self.editor:
            self.method_after_animation = "showThemes"
            self.editor.closeEditor()
            return

        tc = ThemeChooser(self, self.site)
        self.setCentralWidget(tc)

    def showThemesSettings(self):
        tei = Plugins.getThemePlugin(Plugins.actualThemeEditorPlugin())
        if tei:
            if self.editor:
                self.method_after_animation = "showThemesSettings"
                self.editor.closeEditor()
                return

            path = self.site.source_path
            tei.setWindow(self)
            tei.setSourcePath(path)
            self.setCentralWidget(tei)
        else:
            self.statusBar().showMessage(
                QCoreApplication.translate("MainWindow",
                                           "Unable to load plugin") + " " +
                Plugins.actualThemeEditorPlugin())

    def showSettings(self):
        if self.editor:
            self.method_after_animation = "showSettings"
            self.editor.closeEditor()
            return

        sse = SiteSettingsEditor(self, self.site)
        self.setCentralWidget(sse)

    def showMenu(self):
        self.navigationdock.setVisible(True)

    def dockVisibilityChanged(self, visible):
        self.showDock.setVisible(not visible)

    def previewSite(self, content=None):
        if self.editor and content:
            self.content_after_animation = content
            self.editor.closeEditor()
            return

        dir = os.path.join(self.default_path, self.site.output)

        if not content:
            if len(self.site.pages) > 0:
                content = self.site.pages[0]
                for c in self.site.pages:
                    if c.url == "index.html":
                        content = c
                        break
            elif len(self.site.posts) > 0:
                content = self.site.posts()[0]

        if content:
            file = content.url
            self.webView = QWebEngineView()
            self.webView.loadFinished.connect(self.webViewLoadFinished)
            url = pathlib.Path(os.path.join(dir, file)).as_uri()
            self.webView.setUrl(QUrl(url))
            self.setCursor(Qt.WaitCursor)
        else:
            self.statusBar().showMessage(
                QCoreApplication.translate(
                    "MainWindow", "Site has no pages or posts to preview."))

    def webViewLoadFinished(self, success):
        if success:
            self.setCentralWidget(self.webView)
            self.webView.loadFinished.disconnect(self.webViewLoadFinished)
        else:
            QMessageBox.warning(
                self, "FlatSiteBuilder",
                QCoreApplication.translate("MainWindow",
                                           "Unable to open webpage."))
        self.setCursor(Qt.ArrowCursor)

    def publishSite(self):
        pluginName = Plugins.actualPublishPlugin()
        pi = Plugins.getPublishPlugin(pluginName)
        if pi:
            self.setCentralWidget(pi)
            pi.setSitePath(self.install_directory, self.site.source_path)
        else:
            QMessageBox.warning(
                self, "FlatSiteBuilder",
                QCoreApplication.translate(
                    "MainWindow", "Website has no publish plugin configured."))

    def createSite(self):
        wiz = SiteWizard(self.install_directory, parent=self)
        wiz.loadSite.connect(self.loadProject)
        wiz.buildSite.connect(self.buildSite)
        wiz.show()

    def buildSite(self):
        self.site.loadMenus()
        self.site.loadPages()
        self.site.loadPosts()
        if len(self.site.pages) == 0 and len(self.site.posts) == 0:
            self.statusBar().showMessage(
                QCoreApplication.translate(
                    "MainWindow", "Site has no pages or posts to build."))
        else:
            gen = Generator()
            gen.generateSite(self, self.site)
            self.statusBar().showMessage(
                self.site.title + " " +
                QCoreApplication.translate("MainWindow", "has been generated"))

    def editMenu(self, item):
        menu = item.data(Qt.UserRole)
        me = MenuEditor(self, menu, self.site)
        self.editor = me
        list = self.centralWidget()
        if list:
            list.registerMenuEditor(me)
            list.editedItemChanged.connect(self.editedItemChanged)

        self.editor.closes.connect(self.editorClosed)
        self.editor.contentChanged.connect(self.menuChanged)
        self.animate(item)

    def editContent(self, item):
        content = item.data(Qt.UserRole)
        self.editor = ContentEditor(self, self.site, content)
        self.siteLoaded.connect(self.editor.siteLoaded)
        self.editor.closes.connect(self.editorClosed)
        self.editor.preview.connect(self.previewSite)
        self.animate(item)

    def animate(self, item):
        panel = self.centralWidget()
        self.list = item.tableWidget()
        self.row = item.row()

        # create a cell widget to get the right position in the table
        self.cellWidget = QWidget()
        self.cellWidget.setMaximumHeight(0)
        self.list.setCellWidget(self.row, 1, self.cellWidget)
        pos = self.cellWidget.mapTo(panel, QPoint(0, 0))

        self.editor.setParent(panel)
        self.editor.move(pos)
        self.editor.resize(self.cellWidget.size())
        self.editor.show()

        self.animation = QPropertyAnimation(self.editor,
                                            "geometry".encode("utf-8"))
        self.animation.setDuration(300)
        self.animation.setStartValue(
            QRect(pos.x(), pos.y(),
                  self.cellWidget.size().width(),
                  self.cellWidget.size().height()))
        self.animation.setEndValue(
            QRect(0, 0,
                  panel.size().width(),
                  panel.size().height()))
        self.animation.start()

    def eventFilter(self, watched, event):
        if watched == self and event.type() == QEvent.Resize and self.editor:
            w = self.centralWidget()
            if w:
                self.editor.resize(w.size())
        return False

    def editorClosed(self):
        pos = self.cellWidget.mapTo(self.centralWidget(), QPoint(0, 0))
        # correct end values in case of resizing the window
        self.animation.setStartValue(
            QRect(pos.x(), pos.y(),
                  self.cellWidget.size().width(),
                  self.cellWidget.size().height()))
        self.animation.finished.connect(self.animationFineshedZoomOut)
        self.animation.setDirection(QAbstractAnimation.Backward)
        self.animation.start()

    def animationFineshedZoomOut(self):
        self.list.removeCellWidget(self.row, 1)
        del self.animation

        # in the case self.editor was a MenuEditor, we have to unregister it in the MenuList
        # should be refactored some day :-)
        list = self.centralWidget()
        if list is MenuEditor:
            list.unregisterMenuEditor()

        if isinstance(list, ContentList):
            list.reload()

        del self.editor
        self.editor = None

        if self.method_after_animation == "showDashboard":
            self.showDashboard()
            self.method_after_animation = ""
        elif self.method_after_animation == "showSettings":
            self.showSettings()
        elif self.method_after_animation == "showThemesSettings":
            self.showThemesSettings()
        elif self.method_after_animation == "showThemes":
            self.showThemes()
        elif self.method_after_animation == "showMenus":
            self.showMenus()
        elif self.method_after_animation == "showPages":
            self.showPages()
        elif self.method_after_animation == "showPosts":
            self.showPosts()

        if self.content_after_animation:
            self.previewSite(self.content_after_animation)
            self.content_after_animation = None

    def contentChanged(self, content):
        self.list.item(self.row, 1).setText(content.title())
        self.list.item(self.row, 2).setText(content.source())
        self.list.item(self.row, 3).setText(content.layout())
        self.list.item(self.row, 4).setText(content.author())
        self.list.item(self.row,
                       5).setText(content.date().toString("dd.MM.yyyy"))

    def menuChanged(self, menu):
        self.list.item(self.row, 1).setText(menu.name())

    def editedItemChanged(self, item):
        # this will happen, if the MenuList.reloadMenu() has been called by the undo.command
        self.list = item.tableWidget()
        self.row = item.row()
        self.cellWidget = QWidget()
        self.list.setCellWidget(self.row, 1, self.cellWidget)

    def loadPlugins(self):
        # check if we are running in a frozen environment (pyinstaller --onefile)
        if getattr(sys, "frozen", False):
            bundle_dir = sys._MEIPASS
            # if we are running in a onefile environment, then copy all plugin to /tmp/...
            if bundle_dir != os.getcwd():
                os.mkdir(os.path.join(bundle_dir, "plugins"))
                for root, dirs, files in os.walk(
                        os.path.join(os.getcwd(), "plugins")):
                    for file in files:
                        shutil.copy(os.path.join(root, file),
                                    os.path.join(bundle_dir, "plugins"))
                        print("copy", file)
                    break  # do not copy __pycache__
        else:
            bundle_dir = os.getcwd()

        plugins_dir = os.path.join(bundle_dir, "plugins")
        for root, dirs, files in os.walk(plugins_dir):
            for file in files:
                modulename, ext = os.path.splitext(file)
                if ext == ".py":
                    module = import_module("plugins." + modulename)
                    for name, klass in inspect.getmembers(
                            module, inspect.isclass):
                        if klass.__module__ == "plugins." + modulename:
                            instance = klass()
                            if isinstance(instance, ElementEditorInterface):
                                Plugins.addElementPlugin(name, instance)
                                instance.registerContenType()
                            elif isinstance(instance, ThemeEditorInterface):
                                Plugins.addThemePlugin(name, instance)
                            elif isinstance(instance, PublisherInterface):
                                Plugins.addPublishPlugin(name, instance)
                            elif isinstance(instance, GeneratorInterface):
                                Plugins.addGeneratorPlugin(name, instance)
            break  # not to list __pycache__
    def initGui(self):
        self.installEventFilter(self)
        self.dashboard = Expander(
            QCoreApplication.translate("MainWindow", "Dashboard"),
            ":/images/dashboard_normal.png", ":/images/dashboard_hover.png",
            ":/images/dashboard_selected.png")
        self.content = Expander(
            QCoreApplication.translate("MainWindow",
                                       "Content"), ":/images/pages_normal.png",
            ":/images/pages_hover.png", ":/images/pages_selected.png")
        self.appearance = Expander(
            QCoreApplication.translate("MainWindow", "Appearance"),
            ":/images/appearance_normal.png", ":/images/appearance_hover.png",
            ":/images/appearance_selected.png")
        self.settings = Expander(
            QCoreApplication.translate("MainWindow", "Settings"),
            ":/images/settings_normal.png", ":/images/settings_hover.png",
            ":/images/settings_selected.png")

        self.setWindowTitle(QCoreApplication.applicationName() + " " +
                            QCoreApplication.applicationVersion())
        vbox = QVBoxLayout()
        vbox.addWidget(self.dashboard)
        vbox.addWidget(self.content)
        vbox.addWidget(self.appearance)
        vbox.addWidget(self.settings)
        vbox.addStretch()

        content_box = QVBoxLayout()
        pages_button = HyperLink(
            QCoreApplication.translate("MainWindow", "Pages"))
        posts_button = HyperLink(
            QCoreApplication.translate("MainWindow", "Posts"))
        content_box.addWidget(pages_button)
        content_box.addWidget(posts_button)
        self.content.addLayout(content_box)

        app_box = QVBoxLayout()
        themes_button = HyperLink(
            QCoreApplication.translate("MainWindow", "Themes"))
        menus_button = HyperLink(
            QCoreApplication.translate("MainWindow", "Menus"))
        self.theme_settings_button = HyperLink(
            QCoreApplication.translate("MainWindow", "Theme Settings"))
        self.theme_settings_button.setVisible(False)
        app_box.addWidget(menus_button)
        app_box.addWidget(themes_button)
        app_box.addWidget(self.theme_settings_button)

        self.appearance.addLayout(app_box)

        scroll_content = QWidget()
        scroll_content.setLayout(vbox)
        scroll = QScrollArea()
        scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        scroll.setWidget(scroll_content)
        scroll.setWidgetResizable(True)
        scroll.setMaximumWidth(200)
        scroll.setMinimumWidth(200)

        self.navigationdock = QDockWidget(
            QCoreApplication.translate("MainWindow", "Navigation"), self)
        self.navigationdock.setAllowedAreas(Qt.LeftDockWidgetArea
                                            | Qt.RightDockWidgetArea)
        self.navigationdock.setWidget(scroll)
        self.navigationdock.setObjectName("Navigation")

        self.addDockWidget(Qt.LeftDockWidgetArea, self.navigationdock)

        self.showDock = FlatButton(":/images/edit_normal.png",
                                   ":/images/edit_hover.png")
        self.showDock.setToolTip(
            QCoreApplication.translate("MainWindow", "Show Navigation"))
        self.statusBar().addPermanentWidget(self.showDock)

        self.dashboard.expanded.connect(self.dashboardExpanded)
        self.dashboard.clicked.connect(self.showDashboard)
        self.content.expanded.connect(self.contentExpanded)
        self.content.clicked.connect(self.showPages)
        self.appearance.expanded.connect(self.appearanceExpanded)
        self.appearance.clicked.connect(self.showMenus)
        self.settings.expanded.connect(self.settingsExpanded)
        self.settings.clicked.connect(self.showSettings)
        menus_button.clicked.connect(self.showMenus)
        pages_button.clicked.connect(self.showPages)
        posts_button.clicked.connect(self.showPosts)
        themes_button.clicked.connect(self.showThemes)
        self.theme_settings_button.clicked.connect(self.showThemesSettings)
        self.showDock.clicked.connect(self.showMenu)
        self.navigationdock.visibilityChanged.connect(
            self.dockVisibilityChanged)
class RowEditor(QWidget):
    rowEditorCopied = pyqtSignal(object)

    def __init__(self):
        QWidget.__init__(self)

        from widgets.content import ContentType
        from widgets.flatbutton import FlatButton
        from widgets.hyperlink import HyperLink
        from widgets.section import Section

        self.editButton = FlatButton(":/images/edit_normal.png",
                                     ":/images/edit_hover.png")
        self.copyButton = FlatButton(":/images/copy_normal.png",
                                     ":/images/copy_hover.png")
        self.deleteButton = FlatButton(":/images/trash_normal.png",
                                       ":/images/trash_hover.png")
        self.addColumns = HyperLink("(+) Add Columns")
        self.editButton.setToolTip("Edit Row")
        self.deleteButton.setToolTip("Delete Row")
        self.copyButton.setToolTip("Copy Row")
        self.editButton.setMaximumWidth(24)
        self.copyButton.setMaximumWidth(24)
        self.deleteButton.setMaximumWidth(24)
        vbox = QVBoxLayout()
        vbox.setAlignment(Qt.AlignTop)
        vbox.setSpacing(5)
        vbox.addWidget(self.editButton)
        vbox.addWidget(self.copyButton)
        vbox.addWidget(self.deleteButton, 0, Qt.AlignBottom)
        layout = QHBoxLayout()

        pal = self.palette()
        pal.setColor(QPalette.Background,
                     QColor(self.palette().alternateBase().color()))
        self.setPalette(pal)
        self.setAutoFillBackground(True)

        self.highlightedRect = QRect()
        self.layout = QGridLayout()
        self.layout.addWidget(self.addColumns, 0, 0, 1, 1, Qt.AlignCenter)
        self.layout.setColumnStretch(0, 1)

        layout.addItem(vbox)
        layout.addLayout(self.layout)
        self.setLayout(layout)

        self.deleteButton.clicked.connect(self.delete)
        self.copyButton.clicked.connect(self.copy)
        self.editButton.clicked.connect(self.edit)
        self.addColumns.clicked.connect(self.insertColumns)

    def edit(self):
        ce = self.getContentEditor()
        if ce:
            ce.rowEdit(self)

    def copy(self):
        self.rowEditorCopied.emit(self)

    def delete(self):
        se = self.parentWidget()
        if se:
            se.removeRowEditor(self)
            se.section._items.remove(self.row)
        ce = self.getContentEditor()
        if ce:
            ce.editChanged("Delete Row")

    def addColumn(self, ce, column):
        if self.addColumns.isVisible():
            self.addColumns.setVisible(False)
            self.layout.removeWidget(self.addColumns)

        self.layout.addWidget(ce, 0, column)
        self.layout.setColumnStretch(column, ce.column.span)

    def load(self, row):
        from widgets.columneditor import ColumnEditor

        self.row = row
        i = 0
        for column in self.row.columns:
            ce = ColumnEditor()
            ce.load(column)
            self.addColumn(ce, i)
            i = i + 1

    def getContentEditor(self):
        se = self.parentWidget()
        if se:
            pe = se.parentWidget()
            if pe:
                sa = pe.parentWidget()
                if sa:
                    vp = sa.parentWidget()
                    if vp:
                        cee = vp.parentWidget()
                        if cee:
                            return cee
        return None

    def insertColumns(self):
        dlg = ColumnsDialog()
        dlg.exec()
        if dlg.result == 0:
            return

        if dlg.result == 1:  # 1/1
            col = Column()
            col.span = 12
            self.row._columns.append(col)
            ce = ColumnEditor()
            ce.load(col)
            self.addColumn(ce, 0)

        elif dlg.result == 2:  # 1/2 - 1/2
            for i in range(2):
                col = Column()
                col.span = 6
                self.row._columns.append(col)
                ce = ColumnEditor()
                ce.load(col)
                self.addColumn(ce, i)

        elif dlg.result == 3:  # 1/3 - 1/3 - 1/3
            for i in range(3):
                col = Column()
                col.span = 4
                self.row._columns.append(col)
                ce = ColumnEditor()
                ce.load(col)
                self.addColumn(ce, i)

        elif dlg.result == 4:  # 1/4 - 1/4 - 1/4 - 1/4
            for i in range(4):
                col = Column()
                col.span = 3
                self.row._columns.append(col)
                ce = ColumnEditor()
                ce.load(col)
                self.addColumn(ce, i)

        elif dlg.result == 5:  # 2/3 - 1/3
            col = Column()
            col.span = 8
            self.row._columns.append(col)
            ce = ColumnEditor()
            ce.load(col)
            self.addColumn(ce, 0)
            col = Column()
            col.span = 4
            self.row._columns.append(col)
            ce = ColumnEditor()
            ce.load(col)
            self.addColumn(ce, 1)

        elif dlg.result == 6:  # 1/3 - 2/3
            col = Column()
            col.span = 4
            self.row._columns.append(col)
            ce = ColumnEditor()
            ce.load(col)
            self.addColumn(ce, 0)
            col = Column()
            col.span = 8
            self.row._columns.append(col)
            ce = ColumnEditor()
            ce.load(col)
            self.addColumn(ce, 1)

        elif dlg.result == 7:  # 1/4 - 3/4
            col = Column()
            col.span = 2
            self.row._columns.append(col)
            ce = ColumnEditor()
            ce.load(col)
            self.addColumn(ce, 0)
            col = Column()
            col.span = 9
            self.row._columns.append(col)
            ce = ColumnEditor()
            ce.load(col)
            self.addColumn(ce, 1)

        elif dlg.result == 8:  # 3/4 - 1/4
            col = Column()
            col.span = 9
            self.row._columns.append(col)
            ce = ColumnEditor()
            ce.load(col)
            self.addColumn(ce, 0)
            col = Column()
            col.span = 3
            self.row._columns.append(col)
            ce = ColumnEditor()
            ce.load(col)
            self.addColumn(ce, 1)

        elif dlg.result == 9:  # 1/2 - 1/4 - 1/4
            col = Column()
            col.span = 6
            self.row._columns.append(col)
            ce = ColumnEditor()
            ce.load(col)
            self.addColumn(ce, 0)
            col = Column()
            col.span = 3
            self.row._columns.append(col)
            ce = ColumnEditor()
            ce.load(col)
            self.addColumn(ce, 1)
            col = Column()
            col.span = 3
            self.row._columns.append(col)
            ce = ColumnEditor()
            ce.load(col)
            self.addColumn(ce, 2)

        elif dlg.result == 10:  # 1/4 - 1/4 - 1/2
            col = Column()
            col.span = 3
            self.row._columns.append(col)
            ce = ColumnEditor()
            ce.load(col)
            self.addColumn(ce, 0)
            col = Column()
            col.span = 3
            self.row._columns.append(col)
            ce = ColumnEditor()
            ce.load(col)
            self.addColumn(ce, 1)
            col = Column()
            col.span = 6
            self.row._columns.append(col)
            ce = ColumnEditor()
            ce.load(col)
            self.addColumn(ce, 2)

        elif dlg.result == 11:  # 1/4 - 1/2 - 1/4
            col = Column()
            col.span = 3
            self.row._columns.append(col)
            ce = ColumnEditor()
            ce.load(col)
            self.addColumn(ce, 0)
            col = Column()
            col.span = 6
            self.row._columns.append(col)
            ce = ColumnEditor()
            ce.load(col)
            self.addColumn(ce, 1)
            col = Column()
            col.span = 3
            self.row._columns.append(col)
            ce = ColumnEditor()
            ce.load(col)
            self.addColumn(ce, 2)

        ce = self.getContentEditor()
        if ce:
            ce.editChanged("Add Columns")

    def enableColumnAcceptDrop(self, mode):
        for i in range(self.layout.count()):
            ce = self.layout.itemAt(i).widget()
            if ce:
                ce.setAcceptDrops(mode)

    def mousePressEvent(self, event):
        from widgets.sectioneditor import SectionEditor
        mimeData = WidgetMimeData()
        mimeData.setSize(self.size().width(), self.size().height())
        mimeData.setData(self)
        parent = self.parentWidget()
        if isinstance(parent, SectionEditor):
            mimeData.source_list = parent.section._items

        pixmap = QPixmap(self.size())
        self.render(pixmap)

        drag = QDrag(self)
        drag.setMimeData(mimeData)
        drag.setHotSpot(event.pos())
        drag.setPixmap(pixmap)

        se = self.parentWidget()
        se.removeRowEditor(self)
        pe = se.parentWidget()
        pe.enableColumnAcceptDrop(False)
        self.hide()

        if drag.exec(Qt.MoveAction) == Qt.IgnoreAction:
            se.addRowEditor(self)
            self.show()

        pe.enableColumnAcceptDrop(True)
Esempio n. 9
0
    def __init__(self, win, site, content):
        AnimateableEditor.__init__(self)

        self.win = win
        self.site = site
        self.content = content
        self.is_new = False
        self.editor = None
        self.undoStack = QUndoStack()
        self.changed = False
        self.setAutoFillBackground(True)

        self.previewLink = HyperLink("")
        self.vbox = QVBoxLayout()
        self.layout = QGridLayout()
        self.titleLabel = QLabel()

        fnt = self.titleLabel.font()
        fnt.setPointSize(20)
        fnt.setBold(True)
        self.titleLabel.setFont(fnt)
        self.script = QPushButton("Page Script")
        self.title = QLineEdit()
        self.source = QLineEdit()
        self.source.setPlaceholderText("*.qml")
        self.excerpt = QLineEdit()
        self.date = QLineEdit()
        self.labelPermalink = QLabel("Permalink")
        self.labelTitle = QLabel("Title")
        self.labelAuthor = QLabel("Author")
        self.labelKeyword = QLabel("Keywords")
        self.labelLayout = QLabel("Layout")
        self.labelMenu = QLabel("Menu")
        self.author = QLineEdit()
        self.keywords = QLineEdit()
        self.menus = QComboBox()
        self.layouts = QComboBox()
        self.layouts.setMaximumWidth(100)

        for menu in self.site.menus.menus:
            self.menus.addItem(menu.name)

        for root, dirs, files in os.walk(
                os.path.join(self.site.source_path, "layouts")):
            for file in files:
                self.layouts.addItem(Path(file).stem)

        for root, dirs, files in os.walk(
                os.path.join(Generator.themesPath(), self.site.theme,
                             "layouts")):
            for file in files:
                self.layouts.addItem(Path(file).stem)

        self.close = FlatButton(":/images/close_normal.png",
                                ":/images/close_hover.png")
        self.close.setToolTip("Close Content Editor")
        self.undo = FlatButton(":/images/undo_normal.png",
                               ":/images/undo_hover.png", "",
                               ":/images/undo_disabled.png")
        self.redo = FlatButton(":/images/redo_normal.png",
                               ":/images/redo_hover.png", "",
                               ":/images/redo_disabled.png")
        self.undo.setToolTip("Undo")
        self.redo.setToolTip("Redo")
        self.undo.setEnabled(False)
        self.redo.setEnabled(False)
        hbox = QHBoxLayout()
        hbox.addWidget(self.undo)
        hbox.addWidget(self.redo)
        hbox.addWidget(self.close)

        self.scroll = QScrollArea()
        self.scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.scroll.setWidgetResizable(True)
        self.scroll.installEventFilter(self)
        self.layout.addWidget(self.titleLabel, 0, 0)
        self.layout.addWidget(self.previewLink, 0, 1)
        self.layout.addLayout(hbox, 0, 3)
        self.layout.addWidget(self.labelTitle, 1, 0)
        self.layout.addWidget(self.title, 2, 0)
        self.layout.addWidget(self.labelPermalink, 1, 1)
        self.layout.addWidget(self.source, 2, 1)
        self.layout.addWidget(self.labelAuthor, 3, 0)
        self.layout.addWidget(self.author, 4, 0)
        self.layout.addWidget(self.labelKeyword, 3, 1)
        self.layout.addWidget(self.keywords, 4, 1)
        self.layout.addWidget(self.labelMenu, 3, 2)
        self.layout.addWidget(self.menus, 4, 2)
        self.layout.addWidget(self.labelLayout, 3, 3)
        self.layout.addWidget(self.layouts, 4, 3)
        self.layout.addWidget(self.scroll, 7, 0, 1, 4)
        self.layout.addWidget(self.script, 8, 0, 1, 4)
        self.vbox.addLayout(self.layout)
        self.setLayout(self.vbox)

        if self.content.content_type == ContentType.POST:
            self.previewLink.setText("view post")
            self.excerptLabel = QLabel("Excerpt")
            self.layout.addWidget(self.excerptLabel, 5, 0)
            self.layout.addWidget(self.excerpt, 6, 0, 1, 2)
            self.datelabel = QLabel("Date")
            self.layout.addWidget(self.datelabel, 5, 2)
            self.layout.addWidget(self.date, 6, 2, 1, 2)
            self.filename = self.site.source_path + "/posts/" + content.source
        else:
            self.previewLink.setText("view page")
            self.filename = self.site.source_path + "/pages/" + content.source

        self.load()

        self.close.clicked.connect(self.closeEditor)
        self.title.editingFinished.connect(self.titleFinished)
        self.title.textChanged.connect(self.titleChanged)
        self.source.editingFinished.connect(self.sourceChanged)
        self.excerpt.editingFinished.connect(self.excerptChanged)
        self.date.editingFinished.connect(self.dateChanged)
        self.author.editingFinished.connect(self.authorChanged)
        self.keywords.editingFinished.connect(self.keywordsChanged)
        self.menus.currentTextChanged.connect(self.menuChanged)
        self.layouts.currentTextChanged.connect(self.layoutChanged)
        self.undoStack.canUndoChanged.connect(self.canUndoChanged)
        self.undoStack.canRedoChanged.connect(self.canRedoChanged)
        self.undoStack.undoTextChanged.connect(self.undoTextChanged)
        self.undoStack.redoTextChanged.connect(self.redoTextChanged)
        self.undo.clicked.connect(self.undoAction)
        self.redo.clicked.connect(self.redoAction)
        self.previewLink.clicked.connect(self.previewPage)
        self.script.clicked.connect(self.scriptClicked)
Esempio n. 10
0
class ContentEditor(AnimateableEditor):
    contentChanged = pyqtSignal(object)
    preview = pyqtSignal(object)

    def __init__(self, win, site, content):
        AnimateableEditor.__init__(self)

        self.win = win
        self.site = site
        self.content = content
        self.is_new = False
        self.editor = None
        self.undoStack = QUndoStack()
        self.changed = False
        self.setAutoFillBackground(True)

        self.previewLink = HyperLink("")
        self.vbox = QVBoxLayout()
        self.layout = QGridLayout()
        self.titleLabel = QLabel()

        fnt = self.titleLabel.font()
        fnt.setPointSize(20)
        fnt.setBold(True)
        self.titleLabel.setFont(fnt)
        self.script = QPushButton("Page Script")
        self.title = QLineEdit()
        self.source = QLineEdit()
        self.source.setPlaceholderText("*.qml")
        self.excerpt = QLineEdit()
        self.date = QLineEdit()
        self.labelPermalink = QLabel("Permalink")
        self.labelTitle = QLabel("Title")
        self.labelAuthor = QLabel("Author")
        self.labelKeyword = QLabel("Keywords")
        self.labelLayout = QLabel("Layout")
        self.labelMenu = QLabel("Menu")
        self.author = QLineEdit()
        self.keywords = QLineEdit()
        self.menus = QComboBox()
        self.layouts = QComboBox()
        self.layouts.setMaximumWidth(100)

        for menu in self.site.menus.menus:
            self.menus.addItem(menu.name)

        for root, dirs, files in os.walk(
                os.path.join(self.site.source_path, "layouts")):
            for file in files:
                self.layouts.addItem(Path(file).stem)

        for root, dirs, files in os.walk(
                os.path.join(Generator.themesPath(), self.site.theme,
                             "layouts")):
            for file in files:
                self.layouts.addItem(Path(file).stem)

        self.close = FlatButton(":/images/close_normal.png",
                                ":/images/close_hover.png")
        self.close.setToolTip("Close Content Editor")
        self.undo = FlatButton(":/images/undo_normal.png",
                               ":/images/undo_hover.png", "",
                               ":/images/undo_disabled.png")
        self.redo = FlatButton(":/images/redo_normal.png",
                               ":/images/redo_hover.png", "",
                               ":/images/redo_disabled.png")
        self.undo.setToolTip("Undo")
        self.redo.setToolTip("Redo")
        self.undo.setEnabled(False)
        self.redo.setEnabled(False)
        hbox = QHBoxLayout()
        hbox.addWidget(self.undo)
        hbox.addWidget(self.redo)
        hbox.addWidget(self.close)

        self.scroll = QScrollArea()
        self.scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.scroll.setWidgetResizable(True)
        self.scroll.installEventFilter(self)
        self.layout.addWidget(self.titleLabel, 0, 0)
        self.layout.addWidget(self.previewLink, 0, 1)
        self.layout.addLayout(hbox, 0, 3)
        self.layout.addWidget(self.labelTitle, 1, 0)
        self.layout.addWidget(self.title, 2, 0)
        self.layout.addWidget(self.labelPermalink, 1, 1)
        self.layout.addWidget(self.source, 2, 1)
        self.layout.addWidget(self.labelAuthor, 3, 0)
        self.layout.addWidget(self.author, 4, 0)
        self.layout.addWidget(self.labelKeyword, 3, 1)
        self.layout.addWidget(self.keywords, 4, 1)
        self.layout.addWidget(self.labelMenu, 3, 2)
        self.layout.addWidget(self.menus, 4, 2)
        self.layout.addWidget(self.labelLayout, 3, 3)
        self.layout.addWidget(self.layouts, 4, 3)
        self.layout.addWidget(self.scroll, 7, 0, 1, 4)
        self.layout.addWidget(self.script, 8, 0, 1, 4)
        self.vbox.addLayout(self.layout)
        self.setLayout(self.vbox)

        if self.content.content_type == ContentType.POST:
            self.previewLink.setText("view post")
            self.excerptLabel = QLabel("Excerpt")
            self.layout.addWidget(self.excerptLabel, 5, 0)
            self.layout.addWidget(self.excerpt, 6, 0, 1, 2)
            self.datelabel = QLabel("Date")
            self.layout.addWidget(self.datelabel, 5, 2)
            self.layout.addWidget(self.date, 6, 2, 1, 2)
            self.filename = self.site.source_path + "/posts/" + content.source
        else:
            self.previewLink.setText("view page")
            self.filename = self.site.source_path + "/pages/" + content.source

        self.load()

        self.close.clicked.connect(self.closeEditor)
        self.title.editingFinished.connect(self.titleFinished)
        self.title.textChanged.connect(self.titleChanged)
        self.source.editingFinished.connect(self.sourceChanged)
        self.excerpt.editingFinished.connect(self.excerptChanged)
        self.date.editingFinished.connect(self.dateChanged)
        self.author.editingFinished.connect(self.authorChanged)
        self.keywords.editingFinished.connect(self.keywordsChanged)
        self.menus.currentTextChanged.connect(self.menuChanged)
        self.layouts.currentTextChanged.connect(self.layoutChanged)
        self.undoStack.canUndoChanged.connect(self.canUndoChanged)
        self.undoStack.canRedoChanged.connect(self.canRedoChanged)
        self.undoStack.undoTextChanged.connect(self.undoTextChanged)
        self.undoStack.redoTextChanged.connect(self.redoTextChanged)
        self.undo.clicked.connect(self.undoAction)
        self.redo.clicked.connect(self.redoAction)
        self.previewLink.clicked.connect(self.previewPage)
        self.script.clicked.connect(self.scriptClicked)

    def scriptClicked(self):
        self.editor = Plugins.element_plugins["TextEditor"]
        self.editor.setContent(None)
        self.editor.setText(self.content.script)
        self.editor.setCaption("Page Script")
        self.editor.close.connect(self.scriptEditorClose)
        self.animate(self.scroll.widget().placeholder)

    def scriptEditorClose(self):
        if self.editor and self.editor.changed:
            self.content.script = self.editor.getText()
            self.editChanged("Update Script")
            self.editor.close.disconnect()
        self.editorClosed()

    def previewPage(self):
        self.preview.emit(self.content)

    def rowEdit(self, re):
        from widgets.rowpropertyeditor import RowPropertyEditor

        self.row_editor = re
        self.editor = RowPropertyEditor()
        self.editor.setRow(re.row)
        self.editor.close.connect(self.rowEditorClose)
        self.animate(re)

    def rowEditorClose(self):
        if self.editor and self.editor.changed:
            self.row_editor.load(self.editor.row)
            self.editChanged("Update Row")
            self.editor.close.disconnect()
        self.editorClosed()

    def canUndoChanged(self, can):
        self.undo.setEnabled(can)

    def canRedoChanged(self, can):
        self.redo.setEnabled(can)

    def undoTextChanged(self, text):
        self.undo.setToolTip("Undo " + text)

    def redoTextChanged(self, text):
        self.redo.setToolTip("Redo " + text)

    def undoAction(self):
        self.undoStack.undo()

    def redoAction(self):
        self.undoStack.redo()

    def menuChanged(self, menu):
        if menu != self.content.menu:
            self.content.menu = menu
            self.contentChanged.emit(self.content)
            self.editChanged("Menu Changed")

    def layoutChanged(self, layout):
        if layout != self.content.layout:
            self.content.layout = layout
            self.contentChanged.emit(self.content)
            self.editChanged("Layout Changed")

    def keywordsChanged(self):
        if self.keywords.text() != self.content.keywords:
            self.content.keywords = self.keywords.text()
            self.contentChanged.emit(self.content)
            self.editChanged("Keywords Changed")

    def authorChanged(self):
        if self.author.text() != self.content.author:
            self.content.author = self.author.text()
            self.contentChanged.emit(self.content)
            self.editChanged("Author Changed")

    def excerptChanged(self):
        if self.excerpt.text() != self.content.excerpt:
            self.content.excerpt = self.excerpt.text()
            self.contentChanged.emit(self.content)
            self.editChanged("Excerpt Changed")

    def dateChanged(self):
        if self.date.text() != self.content.date.toString("dd.MM.yyyy"):
            self.content.date = QDate.fromString(self.date.text(),
                                                 "dd.MM.yyyy")
            self.contentChanged.emit(self.content)
            self.editChanged("Date Changed")

    def sourceChanged(self):
        if self.source.text() != self.content.source:
            oldname = self.filename
            self.content.source = self.source.text()
            if self.content.content_type == ContentType.PAGE:
                self.filename = self.site.source_path + "/pages/" + self.content.source
            else:
                self.filename = self.site.source_path + "/posts/" + self.content.source

            self.contentChanged.emit(self.content)

            renameCommand = RenameContentCommand(self, oldname, self.filename,
                                                 "content file renamed")
            self.undoStack.push(renameCommand)

    def titleChanged(self, title):
        if self.is_new:
            source = title.lower().replace(" ", "_") + ".qml"
            self.source.setText(source)

    def titleFinished(self):
        if self.title.text() != self.content.title:
            if self.is_new:
                self.sourceChanged()
            self.content.title = self.title.text()
            self.contentChanged.emit(self.content)
            self.editChanged("Titel Changed")

    def sectionEdit(self, se):
        self.section_editor = se

        self.editor = SectionPropertyEditor()
        self.editor.setSection(se.section)
        self.editor.close.connect(self.sectionEditorClose)
        self.animate(se)

    def sectionEditorClose(self):
        if self.editor.changed:
            self.section_editor.setSection(self.editor.section)
            self.editChanged("Update Section")
            self.editor.close.disconnect()
        self.editorClosed()

    def load(self):
        from widgets.sectioneditor import SectionEditor
        self.content = self.site.loadContent(self.content.source,
                                             self.content.content_type)
        self.is_new = not self.content.title
        self.title.setText(self.content.title)
        self.source.setText(self.content.source)
        self.author.setText(self.content.author)
        self.keywords.setText(self.content.keywords)
        self.menus.setCurrentText(self.content.menu)
        self.layouts.setCurrentText(self.content.layout)
        if self.content.content_type == ContentType.POST:
            self.excerpt.setText(self.content.excerpt)
            self.date.setText(self.content.date.toString("dd.MM.yyyy"))

        pe = PageEditor()
        self.scroll.setWidget(pe)
        for item in self.content.items:
            if isinstance(item, Section):
                se = SectionEditor(item.fullwidth)
                se.load(item)
                pe.addSection(se)
            # todo other types

    def siteLoaded(self, site):
        self.site = site
        if self.content.contentType == ContentType.PAGE:
            for c in self.site.pages:
                if c.source == self.content.source:
                    self.title.setText(c.title)
        else:
            for c in self.site.posts:
                if c.source == self.content.source:
                    self.excerpt.setText(c.excerpt)
                    self.title.setText(c.title)

    def closeEditor(self):
        if self.editor:
            self.editor.closeEditor()
        self.closes.emit()

    def elementEdit(self, ee):
        self.element_editor = ee
        plugin_name = ""
        if ee.type:
            plugin_name = Plugins.getElementPluginByTagname(ee.type)
        if plugin_name:
            self.editor = Plugins.element_plugins[plugin_name]
        else:
            self.editor = Plugins.element_plugins["TextEditor"]
            self.editor.setCaption("Text Module")
        self.editor.site = self.site
        self.editor.setContent(ee.getContent())
        self.editor.close.connect(self.editorClose)
        self.animate(ee)

    def animate(self, widget):
        self.sourcewidget = widget
        pos = widget.mapTo(self.scroll, QPoint(0, 0))

        self.editor.setParent(self.scroll)
        self.editor.move(pos)
        self.editor.resize(widget.size())
        self.editor.show()

        self.animationgroup = QParallelAnimationGroup()
        self.animx = QPropertyAnimation()
        self.animx.setDuration(300)
        self.animx.setStartValue(pos.x())
        self.animx.setEndValue(0)
        self.animx.setTargetObject(self.editor)
        self.animx.setPropertyName("x".encode("utf-8"))
        self.animationgroup.addAnimation(self.animx)
        self.animy = QPropertyAnimation()
        self.animy.setDuration(300)
        self.animy.setStartValue(pos.y())
        self.animy.setEndValue(0)
        self.animy.setTargetObject(self.editor)
        self.animy.setPropertyName("y".encode("utf-8"))
        self.animationgroup.addAnimation(self.animy)
        self.animw = QPropertyAnimation()
        self.animw.setDuration(300)
        self.animw.setStartValue(widget.size().width())
        self.animw.setEndValue(self.scroll.size().width())
        self.animw.setTargetObject(self.editor)
        self.animw.setPropertyName("width".encode("utf-8"))
        self.animationgroup.addAnimation(self.animw)
        self.animh = QPropertyAnimation()
        self.animh.setDuration(300)
        self.animh.setStartValue(widget.size().height())
        self.animh.setEndValue(self.scroll.size().height())
        self.animh.setTargetObject(self.editor)
        self.animh.setPropertyName("height".encode("utf-8"))
        self.animationgroup.addAnimation(self.animh)
        self.animationgroup.finished.connect(self.animationFineshedZoomIn)
        self.animationgroup.start()

    def animationFineshedZoomIn(self):
        self.scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

        self.title.setEnabled(False)
        self.author.setEnabled(False)
        self.keywords.setEnabled(False)
        self.menus.setEnabled(False)
        self.layouts.setEnabled(False)
        self.labelAuthor.setEnabled(False)
        self.labelKeyword.setEnabled(False)
        self.labelMenu.setEnabled(False)
        self.labelLayout.setEnabled(False)
        self.labelTitle.setEnabled(False)
        self.labelPermalink.setEnabled(False)
        self.previewLink.hide()
        self.undo.hide()
        self.redo.hide()
        self.close.hide()
        self.source.setEnabled(False)
        if self.content.content_type == ContentType.POST:
            self.excerpt.setEnabled(False)
            self.excerptLabel.setEnabled(False)
        self.animationgroup.finished.disconnect(self.animationFineshedZoomIn)

    def editorClose(self):
        if self.editor.changed:
            self.element_editor.setContent(self.editor.getContent())
            self.editChanged("Update Element")
        self.editor.close.disconnect()
        self.editorClosed()

    def editorClosed(self):
        self.scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        pos = self.sourcewidget.mapTo(self.scroll, QPoint(0, 0))
        # correct end values in case of resizing the window
        self.animx.setStartValue(pos.x())
        self.animy.setStartValue(pos.y())
        self.animw.setStartValue(self.sourcewidget.size().width())
        self.animh.setStartValue(self.sourcewidget.size().height())
        self.animationgroup.setDirection(QAbstractAnimation.Backward)
        self.animationgroup.finished.connect(self.animationFineshedZoomOut)
        self.animationgroup.start()

    def animationFineshedZoomOut(self):
        from widgets.rowpropertyeditor import RowPropertyEditor
        from widgets.sectionpropertyeditor import SectionPropertyEditor

        self.title.setEnabled(True)
        self.source.setEnabled(True)
        self.author.setEnabled(True)
        self.keywords.setEnabled(True)
        self.menus.setEnabled(True)
        self.layouts.setEnabled(True)
        self.labelAuthor.setEnabled(True)
        self.labelKeyword.setEnabled(True)
        self.labelMenu.setEnabled(True)
        self.labelLayout.setEnabled(True)
        self.labelTitle.setEnabled(True)
        self.labelPermalink.setEnabled(True)
        self.previewLink.show()
        self.undo.show()
        self.redo.show()
        self.close.show()
        if self.content.content_type == ContentType.POST:
            self.excerpt.setEnabled(True)
            self.excerptLabel.setEnabled(True)
        del self.animationgroup
        self.editor.hide()
        # parent has to be set to NULL, otherwise the plugin will be dropped by parent
        self.editor.setParent(None)
        # only delete Row- and SectionPropertyEditor the other editors are plugins
        if isinstance(self.editor, RowPropertyEditor):
            del self.editor
        elif isinstance(self.editor, SectionPropertyEditor):
            self.editor.close.disconnect(self.sectionEditorClose)
            del self.editor
        self.editor = None

    def editChanged(self, text):
        changeCommand = ChangeContentCommand(self.win, self, text)
        self.undoStack.push(changeCommand)

    def save(self):
        self.content.save(self.filename)

    def contentRenamed(self, name):
        self.filename = name
        base = os.path.basename(name)
        self.source.setText(base)
        self.content.source = base