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)
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 __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)
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)
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)
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)
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