コード例 #1
0
 def _addRootFolderEntry(self, itemClass):
     """Add a menu entry for a root folder of a given class.
     """
     aNew = self.mAddRoot.addAction(trConst(nwLabels.CLASS_NAME[itemClass]))
     aNew.setIcon(self.mainTheme.getIcon(nwLabels.CLASS_ICON[itemClass]))
     aNew.triggered.connect(
         lambda: self.projTree.newTreeItem(nwItemType.ROOT, itemClass))
     self.mAddRoot.addAction(aNew)
コード例 #2
0
    def describeMe(self, hLevel=None):
        """Return a string description of the item.
        """
        descKey = "none"
        if self._type == nwItemType.ROOT:
            descKey = "root"
        elif self._type == nwItemType.FOLDER:
            descKey = "folder"
        elif self._type == nwItemType.FILE:
            if self._layout == nwItemLayout.DOCUMENT:
                if hLevel == "H1":
                    descKey = "doc_h1"
                elif hLevel == "H2":
                    descKey = "doc_h2"
                elif hLevel == "H3":
                    descKey = "doc_h3"
                else:
                    descKey = "document"
            elif self._layout == nwItemLayout.NOTE:
                descKey = "note"

        return trConst(nwLabels.ITEM_DESCRIPTION.get(descKey, ""))
コード例 #3
0
ファイル: outline.py プロジェクト: ccwanggl/novelWriter
    def clearOutline(self):
        """Clear the tree and header and set the default values for the
        columns arrays.
        """
        self.clear()
        self.setColumnCount(1)
        self.setHeaderLabel(trConst(nwLabels.OUTLINE_COLS[nwOutline.TITLE]))

        self._treeOrder = []
        self._colWidth = {}
        self._colHidden = {}
        self._colIdx = {}
        self._treeNCols = 0

        for hItem in nwOutline:
            self._treeOrder.append(hItem)
            self._colWidth[hItem] = self.DEF_WIDTH[hItem]
            self._colHidden[hItem] = self.DEF_HIDDEN[hItem]

        self._treeNCols = len(self._treeOrder)

        return
コード例 #4
0
    def __init__(self, theOutline):
        QMenu.__init__(self, theOutline)

        self.acceptToggle = True

        mnuHead = QAction(self.tr("Select Columns"), self)
        self.addAction(mnuHead)
        self.addSeparator()

        self.actionMap = {}
        for hItem in nwOutline:
            if hItem == nwOutline.TITLE:
                continue
            self.actionMap[hItem] = QAction(
                trConst(nwLabels.OUTLINE_COLS[hItem]), self)
            self.actionMap[hItem].setCheckable(True)
            self.actionMap[hItem].toggled.connect(
                lambda isChecked, tItem=hItem: self.columnToggled.emit(
                    isChecked, tItem))
            self.addAction(self.actionMap[hItem])

        return
コード例 #5
0
    def _popMetaBox(self, qPos, tHandle, sTitle):
        """Show the novel meta data box.
        """
        logger.debug("Generating meta data tooltip for '%s:%s'", tHandle,
                     sTitle)

        pIndex = self.theProject.index
        novIdx = pIndex.getNovelData(tHandle, sTitle)
        refTags = pIndex.getReferences(tHandle, sTitle)

        synopText = novIdx.synopsis
        if synopText:
            synopLabel = trConst(nwLabels.OUTLINE_COLS[nwOutline.SYNOP])
            synopText = f"<p><b>{synopLabel}</b>: {synopText}</p>"

        refLines = []
        refLines = self._appendMetaTag(refTags, nwKeyWords.POV_KEY, refLines)
        refLines = self._appendMetaTag(refTags, nwKeyWords.FOCUS_KEY, refLines)
        refLines = self._appendMetaTag(refTags, nwKeyWords.CHAR_KEY, refLines)
        refLines = self._appendMetaTag(refTags, nwKeyWords.PLOT_KEY, refLines)
        refLines = self._appendMetaTag(refTags, nwKeyWords.TIME_KEY, refLines)
        refLines = self._appendMetaTag(refTags, nwKeyWords.WORLD_KEY, refLines)
        refLines = self._appendMetaTag(refTags, nwKeyWords.OBJECT_KEY,
                                       refLines)
        refLines = self._appendMetaTag(refTags, nwKeyWords.ENTITY_KEY,
                                       refLines)
        refLines = self._appendMetaTag(refTags, nwKeyWords.CUSTOM_KEY,
                                       refLines)

        refText = ""
        if refLines:
            refList = "<br>".join(refLines)
            refText = f"<p>{refList}</p>"

        ttText = refText + synopText or self.tr("No meta data")
        if ttText:
            QToolTip.showText(qPos, ttText)

        return
コード例 #6
0
    def __init__(self, theParent):
        QScrollArea.__init__(self, theParent)

        logger.debug("Initialising GuiOutlineDetails ...")

        self.mainConf = novelwriter.CONFIG
        self.theParent = theParent
        self.theProject = theParent.theProject
        self.theTheme = theParent.theTheme
        self.theIndex = theParent.theIndex
        self.optState = theParent.theProject.optState

        # Sizes
        minTitle = 30 * self.theTheme.textNWidth
        maxTitle = 40 * self.theTheme.textNWidth
        wCount = self.theTheme.getTextWidth("999,999")
        hSpace = int(self.mainConf.pxInt(10))
        vSpace = int(self.mainConf.pxInt(4))

        # Details Area
        self.titleLabel = QLabel("<b>%s</b>" % self.tr("Title"))
        self.fileLabel = QLabel("<b>%s</b>" % self.tr("Document"))
        self.itemLabel = QLabel("<b>%s</b>" % self.tr("Status"))
        self.titleValue = QLabel("")
        self.fileValue = QLabel("")
        self.itemValue = QLabel("")

        self.titleValue.setMinimumWidth(minTitle)
        self.titleValue.setMaximumWidth(maxTitle)
        self.fileValue.setMinimumWidth(minTitle)
        self.fileValue.setMaximumWidth(maxTitle)
        self.itemValue.setMinimumWidth(minTitle)
        self.itemValue.setMaximumWidth(maxTitle)

        # Stats Area
        self.cCLabel = QLabel("<b>%s</b>" % self.tr("Characters"))
        self.wCLabel = QLabel("<b>%s</b>" % self.tr("Words"))
        self.pCLabel = QLabel("<b>%s</b>" % self.tr("Paragraphs"))
        self.cCValue = QLabel("")
        self.wCValue = QLabel("")
        self.pCValue = QLabel("")

        self.cCValue.setMinimumWidth(wCount)
        self.wCValue.setMinimumWidth(wCount)
        self.pCValue.setMinimumWidth(wCount)
        self.cCValue.setAlignment(Qt.AlignRight)
        self.wCValue.setAlignment(Qt.AlignRight)
        self.pCValue.setAlignment(Qt.AlignRight)

        # Synopsis
        self.synopLabel = QLabel("<b>%s</b>" % self.tr("Synopsis"))
        self.synopValue = QLabel("")
        self.synopLWrap = QHBoxLayout()
        self.synopValue.setWordWrap(True)
        self.synopValue.setAlignment(Qt.AlignTop | Qt.AlignLeft)
        self.synopLWrap.addWidget(self.synopValue, 1)

        # Tags
        self.povKeyLabel = QLabel(
            "<b>%s</b>" % trConst(nwLabels.KEY_NAME[nwKeyWords.POV_KEY]))
        self.focKeyLabel = QLabel(
            "<b>%s</b>" % trConst(nwLabels.KEY_NAME[nwKeyWords.FOCUS_KEY]))
        self.chrKeyLabel = QLabel(
            "<b>%s</b>" % trConst(nwLabels.KEY_NAME[nwKeyWords.CHAR_KEY]))
        self.pltKeyLabel = QLabel(
            "<b>%s</b>" % trConst(nwLabels.KEY_NAME[nwKeyWords.PLOT_KEY]))
        self.timKeyLabel = QLabel(
            "<b>%s</b>" % trConst(nwLabels.KEY_NAME[nwKeyWords.TIME_KEY]))
        self.wldKeyLabel = QLabel(
            "<b>%s</b>" % trConst(nwLabels.KEY_NAME[nwKeyWords.WORLD_KEY]))
        self.objKeyLabel = QLabel(
            "<b>%s</b>" % trConst(nwLabels.KEY_NAME[nwKeyWords.OBJECT_KEY]))
        self.entKeyLabel = QLabel(
            "<b>%s</b>" % trConst(nwLabels.KEY_NAME[nwKeyWords.ENTITY_KEY]))
        self.cstKeyLabel = QLabel(
            "<b>%s</b>" % trConst(nwLabels.KEY_NAME[nwKeyWords.CUSTOM_KEY]))

        self.povKeyLWrap = QHBoxLayout()
        self.focKeyLWrap = QHBoxLayout()
        self.chrKeyLWrap = QHBoxLayout()
        self.pltKeyLWrap = QHBoxLayout()
        self.timKeyLWrap = QHBoxLayout()
        self.wldKeyLWrap = QHBoxLayout()
        self.objKeyLWrap = QHBoxLayout()
        self.entKeyLWrap = QHBoxLayout()
        self.cstKeyLWrap = QHBoxLayout()

        self.povKeyValue = QLabel("")
        self.focKeyValue = QLabel("")
        self.chrKeyValue = QLabel("")
        self.pltKeyValue = QLabel("")
        self.timKeyValue = QLabel("")
        self.wldKeyValue = QLabel("")
        self.objKeyValue = QLabel("")
        self.entKeyValue = QLabel("")
        self.cstKeyValue = QLabel("")

        self.povKeyValue.setWordWrap(True)
        self.focKeyValue.setWordWrap(True)
        self.chrKeyValue.setWordWrap(True)
        self.pltKeyValue.setWordWrap(True)
        self.timKeyValue.setWordWrap(True)
        self.wldKeyValue.setWordWrap(True)
        self.objKeyValue.setWordWrap(True)
        self.entKeyValue.setWordWrap(True)
        self.cstKeyValue.setWordWrap(True)

        self.povKeyValue.linkActivated.connect(self._tagClicked)
        self.focKeyValue.linkActivated.connect(self._tagClicked)
        self.chrKeyValue.linkActivated.connect(self._tagClicked)
        self.pltKeyValue.linkActivated.connect(self._tagClicked)
        self.timKeyValue.linkActivated.connect(self._tagClicked)
        self.wldKeyValue.linkActivated.connect(self._tagClicked)
        self.objKeyValue.linkActivated.connect(self._tagClicked)
        self.entKeyValue.linkActivated.connect(self._tagClicked)
        self.cstKeyValue.linkActivated.connect(self._tagClicked)

        self.povKeyLWrap.addWidget(self.povKeyValue, 1)
        self.focKeyLWrap.addWidget(self.focKeyValue, 1)
        self.chrKeyLWrap.addWidget(self.chrKeyValue, 1)
        self.pltKeyLWrap.addWidget(self.pltKeyValue, 1)
        self.timKeyLWrap.addWidget(self.timKeyValue, 1)
        self.wldKeyLWrap.addWidget(self.wldKeyValue, 1)
        self.objKeyLWrap.addWidget(self.objKeyValue, 1)
        self.entKeyLWrap.addWidget(self.entKeyValue, 1)
        self.cstKeyLWrap.addWidget(self.cstKeyValue, 1)

        # Selected Item Details
        self.mainGroup = QGroupBox(self.tr("Title Details"), self)
        self.mainForm = QGridLayout()
        self.mainGroup.setLayout(self.mainForm)

        self.mainForm.addWidget(self.titleLabel, 0, 0, 1, 1,
                                Qt.AlignTop | Qt.AlignLeft)
        self.mainForm.addWidget(self.titleValue, 0, 1, 1, 1,
                                Qt.AlignTop | Qt.AlignLeft)
        self.mainForm.addWidget(self.cCLabel, 0, 2, 1, 1,
                                Qt.AlignTop | Qt.AlignLeft)
        self.mainForm.addWidget(self.cCValue, 0, 3, 1, 1,
                                Qt.AlignTop | Qt.AlignRight)
        self.mainForm.addWidget(self.fileLabel, 1, 0, 1, 1,
                                Qt.AlignTop | Qt.AlignLeft)
        self.mainForm.addWidget(self.fileValue, 1, 1, 1, 1,
                                Qt.AlignTop | Qt.AlignLeft)
        self.mainForm.addWidget(self.wCLabel, 1, 2, 1, 1,
                                Qt.AlignTop | Qt.AlignLeft)
        self.mainForm.addWidget(self.wCValue, 1, 3, 1, 1,
                                Qt.AlignTop | Qt.AlignRight)
        self.mainForm.addWidget(self.itemLabel, 2, 0, 1, 1,
                                Qt.AlignTop | Qt.AlignLeft)
        self.mainForm.addWidget(self.itemValue, 2, 1, 1, 1,
                                Qt.AlignTop | Qt.AlignLeft)
        self.mainForm.addWidget(self.pCLabel, 2, 2, 1, 1,
                                Qt.AlignTop | Qt.AlignLeft)
        self.mainForm.addWidget(self.pCValue, 2, 3, 1, 1,
                                Qt.AlignTop | Qt.AlignRight)
        self.mainForm.addWidget(self.synopLabel, 3, 0, 1, 4,
                                Qt.AlignTop | Qt.AlignLeft)
        self.mainForm.addLayout(self.synopLWrap, 4, 0, 1, 4,
                                Qt.AlignTop | Qt.AlignLeft)

        self.mainForm.setColumnStretch(1, 1)
        self.mainForm.setRowStretch(4, 1)
        self.mainForm.setHorizontalSpacing(hSpace)
        self.mainForm.setVerticalSpacing(vSpace)

        # Selected Item Tags
        self.tagsGroup = QGroupBox(self.tr("Reference Tags"), self)
        self.tagsForm = QGridLayout()
        self.tagsGroup.setLayout(self.tagsForm)

        self.tagsForm.addWidget(self.povKeyLabel, 0, 0, 1, 1,
                                Qt.AlignTop | Qt.AlignLeft)
        self.tagsForm.addLayout(self.povKeyLWrap, 0, 1, 1, 1,
                                Qt.AlignTop | Qt.AlignLeft)
        self.tagsForm.addWidget(self.focKeyLabel, 1, 0, 1, 1,
                                Qt.AlignTop | Qt.AlignLeft)
        self.tagsForm.addLayout(self.focKeyLWrap, 1, 1, 1, 1,
                                Qt.AlignTop | Qt.AlignLeft)
        self.tagsForm.addWidget(self.chrKeyLabel, 2, 0, 1, 1,
                                Qt.AlignTop | Qt.AlignLeft)
        self.tagsForm.addLayout(self.chrKeyLWrap, 2, 1, 1, 1,
                                Qt.AlignTop | Qt.AlignLeft)
        self.tagsForm.addWidget(self.pltKeyLabel, 3, 0, 1, 1,
                                Qt.AlignTop | Qt.AlignLeft)
        self.tagsForm.addLayout(self.pltKeyLWrap, 3, 1, 1, 1,
                                Qt.AlignTop | Qt.AlignLeft)
        self.tagsForm.addWidget(self.timKeyLabel, 4, 0, 1, 1,
                                Qt.AlignTop | Qt.AlignLeft)
        self.tagsForm.addLayout(self.timKeyLWrap, 4, 1, 1, 1,
                                Qt.AlignTop | Qt.AlignLeft)
        self.tagsForm.addWidget(self.wldKeyLabel, 5, 0, 1, 1,
                                Qt.AlignTop | Qt.AlignLeft)
        self.tagsForm.addLayout(self.wldKeyLWrap, 5, 1, 1, 1,
                                Qt.AlignTop | Qt.AlignLeft)
        self.tagsForm.addWidget(self.objKeyLabel, 6, 0, 1, 1,
                                Qt.AlignTop | Qt.AlignLeft)
        self.tagsForm.addLayout(self.objKeyLWrap, 6, 1, 1, 1,
                                Qt.AlignTop | Qt.AlignLeft)
        self.tagsForm.addWidget(self.entKeyLabel, 7, 0, 1, 1,
                                Qt.AlignTop | Qt.AlignLeft)
        self.tagsForm.addLayout(self.entKeyLWrap, 7, 1, 1, 1,
                                Qt.AlignTop | Qt.AlignLeft)
        self.tagsForm.addWidget(self.cstKeyLabel, 8, 0, 1, 1,
                                Qt.AlignTop | Qt.AlignLeft)
        self.tagsForm.addLayout(self.cstKeyLWrap, 8, 1, 1, 1,
                                Qt.AlignTop | Qt.AlignLeft)

        self.tagsForm.setColumnStretch(1, 1)
        self.tagsForm.setRowStretch(8, 1)
        self.tagsForm.setHorizontalSpacing(hSpace)
        self.tagsForm.setVerticalSpacing(vSpace)

        # Assemble
        self.outerWidget = QWidget()
        self.outerBox = QHBoxLayout()
        self.outerBox.addWidget(self.mainGroup, 0)
        self.outerBox.addWidget(self.tagsGroup, 1)

        self.outerWidget.setLayout(self.outerBox)
        self.setWidget(self.outerWidget)

        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.setWidgetResizable(True)

        self.initDetails()

        logger.debug("GuiOutlineDetails initialisation complete")

        return
コード例 #7
0
ファイル: quotes.py プロジェクト: ccwanggl/novelWriter
    def __init__(self, theParent=None, currentQuote='"'):
        QDialog.__init__(self, parent=theParent)

        self.mainConf = novelwriter.CONFIG

        self.outerBox = QVBoxLayout()
        self.innerBox = QHBoxLayout()
        self.labelBox = QVBoxLayout()

        self.selectedQuote = currentQuote

        qMetrics = QFontMetrics(self.font())
        pxW = 7 * qMetrics.boundingRectChar("M").width()
        pxH = 7 * qMetrics.boundingRectChar("M").height()
        pxH = 7 * qMetrics.boundingRectChar("M").height()

        lblFont = self.font()
        lblFont.setPointSizeF(4 * lblFont.pointSizeF())

        # Preview Label
        self.previewLabel = QLabel(currentQuote)
        self.previewLabel.setFont(lblFont)
        self.previewLabel.setFixedSize(QSize(pxW, pxH))
        self.previewLabel.setAlignment(Qt.AlignCenter)
        self.previewLabel.setFrameStyle(QFrame.Box | QFrame.Plain)

        # Quote Symbols
        self.listBox = QListWidget()
        self.listBox.itemSelectionChanged.connect(self._selectedSymbol)

        minSize = 100
        for sKey, sLabel in nwQuotes.SYMBOLS.items():
            theText = "[ %s ] %s" % (sKey, trConst(sLabel))
            minSize = max(minSize, qMetrics.boundingRect(theText).width())
            qtItem = QListWidgetItem(theText)
            qtItem.setData(Qt.UserRole, sKey)
            self.listBox.addItem(qtItem)
            if sKey == currentQuote:
                self.listBox.setCurrentItem(qtItem)

        self.listBox.setMinimumWidth(minSize + self.mainConf.pxInt(40))
        self.listBox.setMinimumHeight(self.mainConf.pxInt(150))

        # Buttons
        self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok
                                          | QDialogButtonBox.Cancel)
        self.buttonBox.accepted.connect(self._doAccept)
        self.buttonBox.rejected.connect(self._doReject)

        # Assemble
        self.labelBox.addWidget(self.previewLabel, 0, Qt.AlignTop)
        self.labelBox.addStretch(1)

        self.innerBox.addLayout(self.labelBox)
        self.innerBox.addWidget(self.listBox)

        self.outerBox.addLayout(self.innerBox)
        self.outerBox.addWidget(self.buttonBox)

        self.setLayout(self.outerBox)

        return
コード例 #8
0
ファイル: outline.py プロジェクト: ccwanggl/novelWriter
    def _populateTree(self):
        """Build the tree based on the project index, and the header
        based on the defined constants, default values and user selected
        width, order and hidden state. All columns are populated, even
        if they are hidden. This ensures that showing and hiding columns
        is fast and doesn't require a rebuild of the tree.
        """
        self.clear()

        if self._firstView:
            theLabels = []
            for i, hItem in enumerate(self._treeOrder):
                theLabels.append(trConst(nwLabels.OUTLINE_COLS[hItem]))
                self._colIdx[hItem] = i

            self.setHeaderLabels(theLabels)
            for hItem in self._treeOrder:
                self.setColumnWidth(self._colIdx[hItem], self._colWidth[hItem])
                self.setColumnHidden(self._colIdx[hItem],
                                     self._colHidden[hItem])

            # Make sure title column is always visible,
            # and handle column always hidden
            self.setColumnHidden(self._colIdx[nwOutline.TITLE], False)

            headItem = self.headerItem()
            headItem.setTextAlignment(self._colIdx[nwOutline.CCOUNT],
                                      Qt.AlignRight)
            headItem.setTextAlignment(self._colIdx[nwOutline.WCOUNT],
                                      Qt.AlignRight)
            headItem.setTextAlignment(self._colIdx[nwOutline.PCOUNT],
                                      Qt.AlignRight)

        currTitle = None
        currChapter = None
        currScene = None

        for tKey, tHandle, sTitle, novIdx in self.theIndex.novelStructure(
                skipExcluded=True):

            tItem = self._createTreeItem(tHandle, sTitle, novIdx)

            tLevel = novIdx["level"]
            if tLevel == "H1":
                self.addTopLevelItem(tItem)
                currTitle = tItem
                currChapter = None
                currScene = None

            elif tLevel == "H2":
                if currTitle is None:
                    self.addTopLevelItem(tItem)
                else:
                    currTitle.addChild(tItem)
                currChapter = tItem
                currScene = None

            elif tLevel == "H3":
                if currChapter is None:
                    if currTitle is None:
                        self.addTopLevelItem(tItem)
                    else:
                        currTitle.addChild(tItem)
                else:
                    currChapter.addChild(tItem)
                currScene = tItem

            elif tLevel == "H4":
                if currScene is None:
                    if currChapter is None:
                        if currTitle is None:
                            self.addTopLevelItem(tItem)
                        else:
                            currTitle.addChild(tItem)
                    else:
                        currChapter.addChild(tItem)
                else:
                    currScene.addChild(tItem)

            tItem.setExpanded(True)

        self._lastBuild = time()

        return
コード例 #9
0
    def _buildInsertMenu(self):
        """Assemble the Insert menu.
        """
        # Insert
        self.insertMenu = self.addMenu(self.tr("&Insert"))

        # Insert > Dashes and Dots
        self.mInsDashes = self.insertMenu.addMenu(self.tr("Dashes"))

        # Insert > Short Dash
        self.aInsENDash = QAction(self.tr("Short Dash"), self)
        self.aInsENDash.setShortcut("Ctrl+K, -")
        self.aInsENDash.triggered.connect(
            lambda: self._docInsert(nwUnicode.U_ENDASH))
        self.mInsDashes.addAction(self.aInsENDash)

        # Insert > Long Dash
        self.aInsEMDash = QAction(self.tr("Long Dash"), self)
        self.aInsEMDash.setShortcut("Ctrl+K, _")
        self.aInsEMDash.triggered.connect(
            lambda: self._docInsert(nwUnicode.U_EMDASH))
        self.mInsDashes.addAction(self.aInsEMDash)

        # Insert > Long Dash
        self.aInsHorBar = QAction(self.tr("Horizontal Bar"), self)
        self.aInsHorBar.setShortcut("Ctrl+K, Ctrl+_")
        self.aInsHorBar.triggered.connect(
            lambda: self._docInsert(nwUnicode.U_HBAR))
        self.mInsDashes.addAction(self.aInsHorBar)

        # Insert > Figure Dash
        self.aInsFigDash = QAction(self.tr("Figure Dash"), self)
        self.aInsFigDash.setShortcut("Ctrl+K, ~")
        self.aInsFigDash.triggered.connect(
            lambda: self._docInsert(nwUnicode.U_FGDASH))
        self.mInsDashes.addAction(self.aInsFigDash)

        # Insert > Quote Marks
        self.mInsQuotes = self.insertMenu.addMenu(self.tr("Quote Marks"))

        # Insert > Left Single Quote
        self.aInsQuoteLS = QAction(self.tr("Left Single Quote"), self)
        self.aInsQuoteLS.setShortcut("Ctrl+K, 1")
        self.aInsQuoteLS.triggered.connect(
            lambda: self._docInsert(nwDocInsert.QUOTE_LS))
        self.mInsQuotes.addAction(self.aInsQuoteLS)

        # Insert > Right Single Quote
        self.aInsQuoteRS = QAction(self.tr("Right Single Quote"), self)
        self.aInsQuoteRS.setShortcut("Ctrl+K, 2")
        self.aInsQuoteRS.triggered.connect(
            lambda: self._docInsert(nwDocInsert.QUOTE_RS))
        self.mInsQuotes.addAction(self.aInsQuoteRS)

        # Insert > Left Double Quote
        self.aInsQuoteLD = QAction(self.tr("Left Double Quote"), self)
        self.aInsQuoteLD.setShortcut("Ctrl+K, 3")
        self.aInsQuoteLD.triggered.connect(
            lambda: self._docInsert(nwDocInsert.QUOTE_LD))
        self.mInsQuotes.addAction(self.aInsQuoteLD)

        # Insert > Right Double Quote
        self.aInsQuoteRD = QAction(self.tr("Right Double Quote"), self)
        self.aInsQuoteRD.setShortcut("Ctrl+K, 4")
        self.aInsQuoteRD.triggered.connect(
            lambda: self._docInsert(nwDocInsert.QUOTE_RD))
        self.mInsQuotes.addAction(self.aInsQuoteRD)

        # Insert > Alternative Apostrophe
        self.aInsMSApos = QAction(self.tr("Alternative Apostrophe"), self)
        self.aInsMSApos.setShortcut("Ctrl+K, '")
        self.aInsMSApos.triggered.connect(
            lambda: self._docInsert(nwUnicode.U_MAPOSS))
        self.mInsQuotes.addAction(self.aInsMSApos)

        # Insert > Symbols
        self.mInsPunct = self.insertMenu.addMenu(
            self.tr("General Punctuation"))

        # Insert > Ellipsis
        self.aInsEllipsis = QAction(self.tr("Ellipsis"), self)
        self.aInsEllipsis.setShortcut("Ctrl+K, .")
        self.aInsEllipsis.triggered.connect(
            lambda: self._docInsert(nwUnicode.U_HELLIP))
        self.mInsPunct.addAction(self.aInsEllipsis)

        # Insert > Prime
        self.aInsPrime = QAction(self.tr("Prime"), self)
        self.aInsPrime.setShortcut("Ctrl+K, Ctrl+'")
        self.aInsPrime.triggered.connect(
            lambda: self._docInsert(nwUnicode.U_PRIME))
        self.mInsPunct.addAction(self.aInsPrime)

        # Insert > Double Prime
        self.aInsDPrime = QAction(self.tr("Double Prime"), self)
        self.aInsDPrime.setShortcut("Ctrl+K, Ctrl+\"")
        self.aInsDPrime.triggered.connect(
            lambda: self._docInsert(nwUnicode.U_DPRIME))
        self.mInsPunct.addAction(self.aInsDPrime)

        # Insert > White Spaces
        self.mInsSpace = self.insertMenu.addMenu(self.tr("White Spaces"))

        # Insert > Non-Breaking Space
        self.aInsNBSpace = QAction(self.tr("Non-Breaking Space"), self)
        self.aInsNBSpace.setShortcut("Ctrl+K, Space")
        self.aInsNBSpace.triggered.connect(
            lambda: self._docInsert(nwUnicode.U_NBSP))
        self.mInsSpace.addAction(self.aInsNBSpace)

        # Insert > Thin Space
        self.aInsThinSpace = QAction(self.tr("Thin Space"), self)
        self.aInsThinSpace.setShortcut("Ctrl+K, Shift+Space")
        self.aInsThinSpace.triggered.connect(
            lambda: self._docInsert(nwUnicode.U_THSP))
        self.mInsSpace.addAction(self.aInsThinSpace)

        # Insert > Thin Non-Breaking Space
        self.aInsThinNBSpace = QAction(self.tr("Thin Non-Breaking Space"),
                                       self)
        self.aInsThinNBSpace.setShortcut("Ctrl+K, Ctrl+Space")
        self.aInsThinNBSpace.triggered.connect(
            lambda: self._docInsert(nwUnicode.U_THNBSP))
        self.mInsSpace.addAction(self.aInsThinNBSpace)

        # Insert > Symbols
        self.mInsSymbol = self.insertMenu.addMenu(self.tr("Other Symbols"))

        # Insert > List Bullet
        self.aInsBullet = QAction(self.tr("List Bullet"), self)
        self.aInsBullet.setShortcut("Ctrl+K, *")
        self.aInsBullet.triggered.connect(
            lambda: self._docInsert(nwUnicode.U_BULL))
        self.mInsSymbol.addAction(self.aInsBullet)

        # Insert > Hyphen Bullet
        self.aInsHyBull = QAction(self.tr("Hyphen Bullet"), self)
        self.aInsHyBull.setShortcut("Ctrl+K, Ctrl+-")
        self.aInsHyBull.triggered.connect(
            lambda: self._docInsert(nwUnicode.U_HYBULL))
        self.mInsSymbol.addAction(self.aInsHyBull)

        # Insert > Flower Mark
        self.aInsFlower = QAction(self.tr("Flower Mark"), self)
        self.aInsFlower.setShortcut("Ctrl+K, Ctrl+*")
        self.aInsFlower.triggered.connect(
            lambda: self._docInsert(nwUnicode.U_FLOWER))
        self.mInsSymbol.addAction(self.aInsFlower)

        # Insert > Per Mille
        self.aInsPerMille = QAction(self.tr("Per Mille"), self)
        self.aInsPerMille.setShortcut("Ctrl+K, %")
        self.aInsPerMille.triggered.connect(
            lambda: self._docInsert(nwUnicode.U_PERMIL))
        self.mInsSymbol.addAction(self.aInsPerMille)

        # Insert > Degree Symbol
        self.aInsDegree = QAction(self.tr("Degree Symbol"), self)
        self.aInsDegree.setShortcut("Ctrl+K, Ctrl+O")
        self.aInsDegree.triggered.connect(
            lambda: self._docInsert(nwUnicode.U_DEGREE))
        self.mInsSymbol.addAction(self.aInsDegree)

        # Insert > Minus Sign
        self.aInsMinus = QAction(self.tr("Minus Sign"), self)
        self.aInsMinus.setShortcut("Ctrl+K, Ctrl+M")
        self.aInsMinus.triggered.connect(
            lambda: self._docInsert(nwUnicode.U_MINUS))
        self.mInsSymbol.addAction(self.aInsMinus)

        # Insert > Times Sign
        self.aInsTimes = QAction(self.tr("Times Sign"), self)
        self.aInsTimes.setShortcut("Ctrl+K, Ctrl+X")
        self.aInsTimes.triggered.connect(
            lambda: self._docInsert(nwUnicode.U_TIMES))
        self.mInsSymbol.addAction(self.aInsTimes)

        # Insert > Division
        self.aInsDivide = QAction(self.tr("Division Sign"), self)
        self.aInsDivide.setShortcut("Ctrl+K, Ctrl+D")
        self.aInsDivide.triggered.connect(
            lambda: self._docInsert(nwUnicode.U_DIVIDE))
        self.mInsSymbol.addAction(self.aInsDivide)

        # Insert > Tags and References
        self.mInsKeywords = self.insertMenu.addMenu(
            self.tr("Tags and References"))
        self.mInsKWItems = {}
        self.mInsKWItems[nwKeyWords.TAG_KEY] = (QAction(self.mInsKeywords),
                                                "Ctrl+K, G")
        self.mInsKWItems[nwKeyWords.POV_KEY] = (QAction(self.mInsKeywords),
                                                "Ctrl+K, V")
        self.mInsKWItems[nwKeyWords.FOCUS_KEY] = (QAction(self.mInsKeywords),
                                                  "Ctrl+K, F")
        self.mInsKWItems[nwKeyWords.CHAR_KEY] = (QAction(self.mInsKeywords),
                                                 "Ctrl+K, C")
        self.mInsKWItems[nwKeyWords.PLOT_KEY] = (QAction(self.mInsKeywords),
                                                 "Ctrl+K, P")
        self.mInsKWItems[nwKeyWords.TIME_KEY] = (QAction(self.mInsKeywords),
                                                 "Ctrl+K, T")
        self.mInsKWItems[nwKeyWords.WORLD_KEY] = (QAction(self.mInsKeywords),
                                                  "Ctrl+K, L")
        self.mInsKWItems[nwKeyWords.OBJECT_KEY] = (QAction(self.mInsKeywords),
                                                   "Ctrl+K, O")
        self.mInsKWItems[nwKeyWords.ENTITY_KEY] = (QAction(self.mInsKeywords),
                                                   "Ctrl+K, E")
        self.mInsKWItems[nwKeyWords.CUSTOM_KEY] = (QAction(self.mInsKeywords),
                                                   "Ctrl+K, X")
        for n, keyWord in enumerate(self.mInsKWItems):
            self.mInsKWItems[keyWord][0].setText(
                trConst(nwLabels.KEY_NAME[keyWord]))
            self.mInsKWItems[keyWord][0].setShortcut(
                self.mInsKWItems[keyWord][1])
            self.mInsKWItems[keyWord][0].triggered.connect(
                lambda n, keyWord=keyWord: self._insertKeyWord(keyWord))
            self.mInsKeywords.addAction(self.mInsKWItems[keyWord][0])

        # Insert > Symbols
        self.mInsBreaks = self.insertMenu.addMenu(
            self.tr("Page Break and Space"))

        # Insert > New Page
        self.aInsNewPage = QAction(self.tr("Page Break"), self)
        self.aInsNewPage.triggered.connect(
            lambda: self._docInsert(nwDocInsert.NEW_PAGE))
        self.mInsBreaks.addAction(self.aInsNewPage)

        # Insert > Vertical Space (Single)
        self.aInsVSpaceS = QAction(self.tr("Vertical Space (Single)"), self)
        self.aInsVSpaceS.triggered.connect(
            lambda: self._docInsert(nwDocInsert.VSPACE_S))
        self.mInsBreaks.addAction(self.aInsVSpaceS)

        # Insert > Vertical Space (Multi)
        self.aInsVSpaceM = QAction(self.tr("Vertical Space (Multi)"), self)
        self.aInsVSpaceM.triggered.connect(
            lambda: self._docInsert(nwDocInsert.VSPACE_M))
        self.mInsBreaks.addAction(self.aInsVSpaceM)

        # Insert > Placeholder Text
        self.aLipsumText = QAction(self.tr("Placeholder Text"), self)
        self.aLipsumText.triggered.connect(
            lambda: self.mainGui.showLoremIpsumDialog())
        self.insertMenu.addAction(self.aLipsumText)

        return
コード例 #10
0
    def newTreeItem(self, itemType, itemClass):
        """Add new item to the tree, with a given itemType and
        itemClass, and attach it to the selected handle. Also make sure
        the item is added in a place it can be added, and that other
        meta data is set correctly to ensure a valid project tree.
        """
        pHandle = self.getSelectedHandle()
        nHandle = None

        if not self.theParent.hasProject:
            logger.error("No project open")
            return False

        if not isinstance(itemType, nwItemType):
            # This would indicate an internal bug
            logger.error("No itemType provided")
            return False

        # The item needs to be assigned an item class, so one must be
        # provided, or it must be possible to extract it from the parent
        # item of the new item.
        if itemClass is None and pHandle is not None:
            pItem = self.theProject.projTree[pHandle]
            if pItem is not None:
                itemClass = pItem.itemClass

        # If class is still not set, alert the user and exit
        if itemClass is None:
            if itemType == nwItemType.FILE:
                self.theParent.makeAlert(
                    self.
                    tr("Please select a valid location in the tree to add the document."
                       ), nwAlert.ERROR)
            else:
                self.theParent.makeAlert(
                    self.
                    tr("Please select a valid location in the tree to add the folder."
                       ), nwAlert.ERROR)
            return False

        # Everything is fine, we have what we need, so we proceed
        logger.verbose(
            "Adding new item of type '%s' and class '%s' to handle '%s'",
            itemType.name, itemClass.name, str(pHandle))

        if itemType == nwItemType.ROOT:
            tHandle = self.theProject.newRoot(
                trConst(nwLabels.CLASS_NAME[itemClass]), itemClass)
            if tHandle is None:
                logger.error("No root item added")
                return False

        else:
            # If no parent has been selected, make the new file under
            # the root NOVEL item.
            if pHandle is None:
                pHandle = self.theProject.projTree.findRoot(nwItemClass.NOVEL)

            # If still nothing, give up
            if pHandle is None:
                self.theParent.makeAlert(
                    self.tr(
                        "Did not find anywhere to add the file or folder!"),
                    nwAlert.ERROR)
                return False

            # Now check if the selected item is a file, in which case
            # the new file will be a sibling
            pItem = self.theProject.projTree[pHandle]
            if pItem.itemType == nwItemType.FILE:
                nHandle = pHandle
                pHandle = pItem.itemParent

            # If we again have no home, give up
            if pHandle is None:
                self.theParent.makeAlert(
                    self.tr(
                        "Did not find anywhere to add the file or folder!"),
                    nwAlert.ERROR)
                return False

            if self.theProject.projTree.isTrashRoot(pHandle):
                self.theParent.makeAlert(
                    self.
                    tr("Cannot add new files or folders to the Trash folder."),
                    nwAlert.ERROR)
                return False

            parTree = self.theProject.projTree.getItemPath(pHandle)

            # If we're still here, add the file or folder
            if itemType == nwItemType.FILE:
                tHandle = self.theProject.newFile(self.tr("New File"),
                                                  itemClass, pHandle)

            elif itemType == nwItemType.FOLDER:
                if len(parTree) >= nwConst.MAX_DEPTH - 1:
                    # Folders cannot be deeper than MAX_DEPTH - 1, leaving room
                    # for one more level of files.
                    self.theParent.makeAlert(
                        self.tr("Cannot add new folder to this item. "
                                "Maximum folder depth has been reached."),
                        nwAlert.ERROR)
                    return False
                tHandle = self.theProject.newFolder(self.tr("New Folder"),
                                                    itemClass, pHandle)

            else:
                logger.error("Failed to add new item")
                return False

        # If there is no handle set, return here
        if tHandle is None:
            return True

        # Add the new item to the tree
        self.revealNewTreeItem(tHandle, nHandle)
        self.theParent.editItem(tHandle)
        nwItem = self.theProject.projTree[tHandle]

        # If this is a folder, return here
        if nwItem.itemType != nwItemType.FILE:
            return True

        # This is a new files, so let's add some content
        newDoc = NWDoc(self.theProject, tHandle)
        curTxt = newDoc.readDocument()
        if curTxt is None:
            curTxt = ""

        if curTxt == "":
            if nwItem.itemLayout == nwItemLayout.DOCUMENT:
                newText = f"### {nwItem.itemName}\n\n"
            else:
                newText = f"# {nwItem.itemName}\n\n"

            # Save the text and index it
            newDoc.writeDocument(newText)
            self.theIndex.scanText(tHandle, newText)

            # Get Word Counts
            cC, wC, pC = self.theIndex.getCounts(tHandle)
            nwItem.setCharCount(cC)
            nwItem.setWordCount(wC)
            nwItem.setParaCount(pC)
            self.propagateCount(tHandle, wC)
            self.wordCountsChanged.emit()

        return True
コード例 #11
0
    def updateViewBox(self, tHandle):
        """Populate the details box from a given handle.
        """
        if tHandle is None:
            self.clearDetails()
            return

        nwItem = self.theProject.projTree[tHandle]
        if nwItem is None:
            self.clearDetails()
            return

        self._itemHandle = tHandle
        iPx = int(round(0.8 * self.theTheme.baseIconSize))

        # Label
        # =====

        theLabel = nwItem.itemName
        if len(theLabel) > 100:
            theLabel = theLabel[:96].rstrip() + " ..."

        if nwItem.itemType == nwItemType.FILE:
            if nwItem.isExported:
                self.labelIcon.setPixmap(self._expCheck)
            else:
                self.labelIcon.setPixmap(self._expCross)
        else:
            self.labelIcon.setPixmap(QPixmap(1, 1))

        self.labelData.setText(theLabel)

        # Status
        # ======

        theStatus, theIcon = nwItem.getImportStatus()
        self.statusIcon.setPixmap(theIcon.pixmap(iPx, iPx))
        self.statusData.setText(theStatus)

        # Class
        # =====

        classIcon = self.theTheme.getIcon(
            nwLabels.CLASS_ICON[nwItem.itemClass])
        self.classIcon.setPixmap(classIcon.pixmap(iPx, iPx))
        self.classData.setText(trConst(nwLabels.CLASS_NAME[nwItem.itemClass]))

        # Layout
        # ======

        hLevel = self.theParent.theIndex.getHandleHeaderLevel(tHandle)
        usageIcon = self.theTheme.getItemIcon(nwItem.itemType,
                                              nwItem.itemClass,
                                              nwItem.itemLayout, hLevel)
        self.usageIcon.setPixmap(usageIcon.pixmap(iPx, iPx))
        self.usageData.setText(nwItem.describeMe(hLevel))

        # Counts
        # ======

        if nwItem.itemType == nwItemType.FILE:
            self.cCountData.setText(f"{nwItem.charCount:n}")
            self.wCountData.setText(f"{nwItem.wordCount:n}")
            self.pCountData.setText(f"{nwItem.paraCount:n}")
        else:
            self.cCountData.setText("–")
            self.wCountData.setText("–")
            self.pCountData.setText("–")

        return
コード例 #12
0
    def __init__(self, theParent, tHandle):
        QDialog.__init__(self, theParent)

        logger.debug("Initialising GuiItemEditor ...")
        self.setObjectName("GuiItemEditor")

        self.mainConf = novelwriter.CONFIG
        self.theParent = theParent
        self.theProject = theParent.theProject

        ##
        #  Build GUI
        ##

        self.theItem = self.theProject.projTree[tHandle]
        if self.theItem is None:
            self.close()
            return

        self.setWindowTitle(self.tr("Item Settings"))

        mVd = self.mainConf.pxInt(220)
        mSp = self.mainConf.pxInt(16)
        vSp = self.mainConf.pxInt(4)

        # Item Label
        self.editName = QLineEdit()
        self.editName.setMinimumWidth(mVd)
        self.editName.setMaxLength(200)

        # Item Status
        self.editStatus = QComboBox()
        self.editStatus.setMinimumWidth(mVd)
        if self.theItem.itemClass in nwLists.CLS_NOVEL:
            for sLabel, _, _, sIcon in self.theProject.statusItems:
                self.editStatus.addItem(sIcon, sLabel, sLabel)
        else:
            for sLabel, _, _, sIcon in self.theProject.importItems:
                self.editStatus.addItem(sIcon, sLabel, sLabel)

        # Item Layout
        self.editLayout = QComboBox()
        self.editLayout.setMinimumWidth(mVd)
        validLayouts = []
        if self.theItem.itemType == nwItemType.FILE:
            if self.theItem.itemClass in nwLists.CLS_NOVEL:
                validLayouts.append(nwItemLayout.DOCUMENT)
            validLayouts.append(nwItemLayout.NOTE)
        else:
            validLayouts.append(nwItemLayout.NO_LAYOUT)
            self.editLayout.setEnabled(False)

        for itemLayout in nwItemLayout:
            if itemLayout in validLayouts:
                self.editLayout.addItem(
                    trConst(nwLabels.LAYOUT_NAME[itemLayout]), itemLayout)

        # Export Switch
        self.textExport = QLabel(self.tr("Include when building project"))
        self.editExport = QSwitch()
        if self.theItem.itemType == nwItemType.FILE:
            self.editExport.setEnabled(True)
            self.editExport.setChecked(self.theItem.isExported)
        else:
            self.editExport.setEnabled(False)
            self.editExport.setChecked(False)

        # Buttons
        self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok
                                          | QDialogButtonBox.Cancel)
        self.buttonBox.accepted.connect(self._doSave)
        self.buttonBox.rejected.connect(self._doClose)

        # Set Current Values
        self.editName.setText(self.theItem.itemName)
        self.editName.selectAll()

        currStatus, _ = self.theItem.getImportStatus()
        statusIdx = self.editStatus.findData(currStatus)
        if statusIdx != -1:
            self.editStatus.setCurrentIndex(statusIdx)

        layoutIdx = self.editLayout.findData(self.theItem.itemLayout)
        if layoutIdx != -1:
            self.editLayout.setCurrentIndex(layoutIdx)

        ##
        #  Assemble
        ##

        nameLabel = QLabel(self.tr("Label"))
        statusLabel = QLabel(self.tr("Status"))
        layoutLabel = QLabel(self.tr("Layout"))

        self.mainForm = QGridLayout()
        self.mainForm.setVerticalSpacing(vSp)
        self.mainForm.setHorizontalSpacing(mSp)
        self.mainForm.addWidget(nameLabel, 0, 0, 1, 1)
        self.mainForm.addWidget(self.editName, 0, 1, 1, 2)
        self.mainForm.addWidget(statusLabel, 1, 0, 1, 1)
        self.mainForm.addWidget(self.editStatus, 1, 1, 1, 2)
        self.mainForm.addWidget(layoutLabel, 2, 0, 1, 1)
        self.mainForm.addWidget(self.editLayout, 2, 1, 1, 2)
        self.mainForm.addWidget(self.textExport, 3, 0, 1, 2)
        self.mainForm.addWidget(self.editExport, 3, 2, 1, 1)
        self.mainForm.setColumnStretch(0, 0)
        self.mainForm.setColumnStretch(1, 1)
        self.mainForm.setColumnStretch(2, 0)

        self.outerBox = QVBoxLayout()
        self.outerBox.setSpacing(mSp)
        self.outerBox.addLayout(self.mainForm)
        self.outerBox.addStretch(1)
        self.outerBox.addWidget(self.buttonBox)
        self.setLayout(self.outerBox)

        self.rejected.connect(self._doClose)

        logger.debug("GuiItemEditor initialisation complete")

        return
コード例 #13
0
    def __init__(self, theWizard):
        QWizardPage.__init__(self)

        self.mainConf = novelwriter.CONFIG
        self.theWizard = theWizard

        self.setTitle(self.tr("Custom Project Options"))
        self.theText = QLabel(
            self.
            tr("Select which additional root folders to make, and how to populate "
               "the Novel folder. If you don't want to add chapters or scenes, set "
               "the values to 0. You can add scenes without chapters."))
        self.theText.setWordWrap(True)

        vS = self.mainConf.pxInt(12)

        # Root Folders
        self.rootGroup = QGroupBox(self.tr("Additional Root Folders"))
        self.rootForm = QGridLayout()
        self.rootGroup.setLayout(self.rootForm)

        self.lblPlot = QLabel(
            self.tr("{0} folder").format(
                trConst(nwLabels.CLASS_NAME[nwItemClass.PLOT])))
        self.lblChar = QLabel(
            self.tr("{0} folder").format(
                trConst(nwLabels.CLASS_NAME[nwItemClass.CHARACTER])))
        self.lblWorld = QLabel(
            self.tr("{0} folder").format(
                trConst(nwLabels.CLASS_NAME[nwItemClass.WORLD])))
        self.lblTime = QLabel(
            self.tr("{0} folder").format(
                trConst(nwLabels.CLASS_NAME[nwItemClass.TIMELINE])))
        self.lblObject = QLabel(
            self.tr("{0} folder").format(
                trConst(nwLabels.CLASS_NAME[nwItemClass.OBJECT])))
        self.lblEntity = QLabel(
            self.tr("{0} folder").format(
                trConst(nwLabels.CLASS_NAME[nwItemClass.ENTITY])))

        self.addPlot = QSwitch()
        self.addChar = QSwitch()
        self.addWorld = QSwitch()
        self.addTime = QSwitch()
        self.addObject = QSwitch()
        self.addEntity = QSwitch()

        self.addPlot.setChecked(True)
        self.addChar.setChecked(True)
        self.addWorld.setChecked(True)

        self.rootForm.addWidget(self.lblPlot, 0, 0)
        self.rootForm.addWidget(self.lblChar, 1, 0)
        self.rootForm.addWidget(self.lblWorld, 2, 0)
        self.rootForm.addWidget(self.lblTime, 3, 0)
        self.rootForm.addWidget(self.lblObject, 4, 0)
        self.rootForm.addWidget(self.lblEntity, 5, 0)
        self.rootForm.addWidget(self.addPlot, 0, 1, 1, 1, Qt.AlignRight)
        self.rootForm.addWidget(self.addChar, 1, 1, 1, 1, Qt.AlignRight)
        self.rootForm.addWidget(self.addWorld, 2, 1, 1, 1, Qt.AlignRight)
        self.rootForm.addWidget(self.addTime, 3, 1, 1, 1, Qt.AlignRight)
        self.rootForm.addWidget(self.addObject, 4, 1, 1, 1, Qt.AlignRight)
        self.rootForm.addWidget(self.addEntity, 5, 1, 1, 1, Qt.AlignRight)
        self.rootForm.setRowStretch(6, 1)

        # Novel Options
        self.novelGroup = QGroupBox(self.tr("Populate Novel Folder"))
        self.novelForm = QGridLayout()
        self.novelGroup.setLayout(self.novelForm)

        self.numChapters = QSpinBox()
        self.numChapters.setRange(0, 100)
        self.numChapters.setValue(5)

        self.numScenes = QSpinBox()
        self.numScenes.setRange(0, 200)
        self.numScenes.setValue(5)

        self.chFolders = QSwitch()
        self.chFolders.setChecked(True)

        self.novelForm.addWidget(QLabel(self.tr("Add chapters")), 0, 0)
        self.novelForm.addWidget(QLabel(self.tr("Scenes (per chapter)")), 1, 0)
        self.novelForm.addWidget(QLabel(self.tr("Add chapter folders")), 2, 0)
        self.novelForm.addWidget(self.numChapters, 0, 1, 1, 1, Qt.AlignRight)
        self.novelForm.addWidget(self.numScenes, 1, 1, 1, 1, Qt.AlignRight)
        self.novelForm.addWidget(self.chFolders, 2, 1, 1, 1, Qt.AlignRight)
        self.novelForm.setRowStretch(3, 1)

        # Wizard Fields
        self.registerField("addPlot", self.addPlot)
        self.registerField("addChar", self.addChar)
        self.registerField("addWorld", self.addWorld)
        self.registerField("addTime", self.addTime)
        self.registerField("addObject", self.addObject)
        self.registerField("addEntity", self.addEntity)
        self.registerField("numChapters", self.numChapters)
        self.registerField("numScenes", self.numScenes)
        self.registerField("chFolders", self.chFolders)

        # Assemble
        self.innerBox = QHBoxLayout()
        self.innerBox.addWidget(self.rootGroup)
        self.innerBox.addWidget(self.novelGroup)

        self.outerBox = QVBoxLayout()
        self.outerBox.setSpacing(vS)
        self.outerBox.addWidget(self.theText)
        self.outerBox.addLayout(self.innerBox)
        self.outerBox.addStretch(1)
        self.setLayout(self.outerBox)

        return
コード例 #14
0
    def _openContextMenu(self, clickPos):
        """The user right clicked an element in the project tree, so we
        open a context menu in-place.
        """
        tItem = None
        selItem = self.itemAt(clickPos)
        if isinstance(selItem, QTreeWidgetItem):
            tHandle = selItem.data(self.C_NAME, Qt.UserRole)
            tItem = self.theProject.tree[tHandle]

        if tItem is None:
            logger.debug("No item found")
            return False

        ctxMenu = QMenu()

        # Trash Folder
        # ============

        trashHandle = self.theProject.tree.trashRoot()
        if tItem.itemHandle == trashHandle and trashHandle is not None:
            # The trash folder only has one option
            ctxMenu.addAction(self.tr("Empty Trash"),
                              lambda: self.emptyTrash())
            ctxMenu.exec_(self.viewport().mapToGlobal(clickPos))
            return True

        # Document Actions
        # ================

        isFile = tItem.itemType == nwItemType.FILE
        if isFile:
            ctxMenu.addAction(
                self.tr("Open Document"),
                lambda: self.projView.openDocumentRequest.emit(
                    tHandle, nwDocMode.EDIT, -1, ""))
            ctxMenu.addAction(
                self.tr("View Document"),
                lambda: self.projView.openDocumentRequest.emit(
                    tHandle, nwDocMode.VIEW, -1, ""))
            ctxMenu.addSeparator()

        # Edit Item Settings
        # ==================

        ctxMenu.addAction(self.tr("Change Label"),
                          lambda: self.renameTreeItem(tHandle))

        if isFile:
            ctxMenu.addAction(self.tr("Toggle Exported"),
                              lambda: self._toggleItemExported(tHandle))

        if tItem.isNovelLike():
            mStatus = ctxMenu.addMenu(self.tr("Change Status"))
            for n, (key,
                    entry) in enumerate(self.theProject.statusItems.items()):
                aStatus = mStatus.addAction(entry["icon"], entry["name"])
                aStatus.triggered.connect(
                    lambda n, key=key: self._changeItemStatus(tHandle, key))
        else:
            mImport = ctxMenu.addMenu(self.tr("Change Importance"))
            for n, (key,
                    entry) in enumerate(self.theProject.importItems.items()):
                aImport = mImport.addAction(entry["icon"], entry["name"])
                aImport.triggered.connect(
                    lambda n, key=key: self._changeItemImport(tHandle, key))

        if isFile and tItem.documentAllowed():
            if tItem.itemLayout == nwItemLayout.NOTE:
                ctxMenu.addAction(
                    self.tr("Change to {0}").format(
                        trConst(nwLabels.LAYOUT_NAME[nwItemLayout.DOCUMENT])),
                    lambda: self._changeItemLayout(tHandle, nwItemLayout.
                                                   DOCUMENT))
            else:
                ctxMenu.addAction(
                    self.tr("Change to {0}").format(
                        trConst(nwLabels.LAYOUT_NAME[nwItemLayout.NOTE])),
                    lambda: self._changeItemLayout(tHandle, nwItemLayout.NOTE))

        ctxMenu.addSeparator()

        # Delete Item
        # ===========

        if tItem.itemClass == nwItemClass.TRASH or tItem.itemType == nwItemType.ROOT:
            ctxMenu.addAction(self.tr("Delete Permanently"),
                              lambda: self.deleteItem(tHandle))
        else:
            ctxMenu.addAction(self.tr("Move to Trash"),
                              lambda: self.deleteItem(tHandle))

        ctxMenu.exec_(self.viewport().mapToGlobal(clickPos))

        return True
コード例 #15
0
    def __init__(self, projView):
        QTreeWidget.__init__(self, projView)

        logger.debug("Initialising GuiProjectToolBar ...")

        self.mainConf = novelwriter.CONFIG
        self.projView = projView
        self.projTree = projView.projTree
        self.mainGui = projView.mainGui
        self.theProject = projView.mainGui.theProject
        self.mainTheme = projView.mainGui.mainTheme

        iPx = self.mainTheme.baseIconSize
        mPx = self.mainConf.pxInt(3)

        self.setContentsMargins(0, 0, 0, 0)
        self.setAutoFillBackground(True)

        qPalette = self.palette()
        qPalette.setBrush(QPalette.Window, qPalette.base())
        self.setPalette(qPalette)

        fadeCol = qPalette.text().color()
        buttonStyle = (
            "QToolButton {{padding: {0}px; border: none; background: transparent;}} "
            "QToolButton:hover {{border: none; background: rgba({1},{2},{3},0.2);}}"
        ).format(mPx, fadeCol.red(), fadeCol.green(), fadeCol.blue())

        # Widget Label
        self.viewLabel = QLabel("<b>%s</b>" % self.tr("Project Content"))
        self.viewLabel.setContentsMargins(0, 0, 0, 0)
        self.viewLabel.setSizePolicy(QSizePolicy.Expanding,
                                     QSizePolicy.Expanding)

        # Move Buttons
        self.tbMoveU = QToolButton(self)
        self.tbMoveU.setToolTip("%s [Ctrl+Up]" % self.tr("Move Up"))
        self.tbMoveU.setIcon(self.mainTheme.getIcon("up"))
        self.tbMoveU.setIconSize(QSize(iPx, iPx))
        self.tbMoveU.setStyleSheet(buttonStyle)
        self.tbMoveU.clicked.connect(lambda: self.projTree.moveTreeItem(-1))

        self.tbMoveD = QToolButton(self)
        self.tbMoveD.setToolTip("%s [Ctrl+Down]" % self.tr("Move Down"))
        self.tbMoveD.setIcon(self.mainTheme.getIcon("down"))
        self.tbMoveD.setIconSize(QSize(iPx, iPx))
        self.tbMoveD.setStyleSheet(buttonStyle)
        self.tbMoveD.clicked.connect(lambda: self.projTree.moveTreeItem(1))

        # Add Item Menu
        self.mAdd = QMenu()

        self.aAddEmpty = self.mAdd.addAction(
            trConst(nwLabels.ITEM_DESCRIPTION["document"]))
        self.aAddEmpty.setIcon(self.mainTheme.getIcon("proj_document"))
        self.aAddEmpty.triggered.connect(lambda: self.projTree.newTreeItem(
            nwItemType.FILE, hLevel=0, isNote=False))

        self.aAddChap = self.mAdd.addAction(
            trConst(nwLabels.ITEM_DESCRIPTION["doc_h2"]))
        self.aAddChap.setIcon(self.mainTheme.getIcon("proj_chapter"))
        self.aAddChap.triggered.connect(lambda: self.projTree.newTreeItem(
            nwItemType.FILE, hLevel=2, isNote=False))

        self.aAddScene = self.mAdd.addAction(
            trConst(nwLabels.ITEM_DESCRIPTION["doc_h3"]))
        self.aAddScene.setIcon(self.mainTheme.getIcon("proj_scene"))
        self.aAddScene.triggered.connect(lambda: self.projTree.newTreeItem(
            nwItemType.FILE, hLevel=3, isNote=False))

        self.aAddNote = self.mAdd.addAction(
            trConst(nwLabels.ITEM_DESCRIPTION["note"]))
        self.aAddNote.setIcon(self.mainTheme.getIcon("proj_note"))
        self.aAddNote.triggered.connect(lambda: self.projTree.newTreeItem(
            nwItemType.FILE, hLevel=1, isNote=True))

        self.aAddFolder = self.mAdd.addAction(
            trConst(nwLabels.ITEM_DESCRIPTION["folder"]))
        self.aAddFolder.setIcon(self.mainTheme.getIcon("proj_folder"))
        self.aAddFolder.triggered.connect(
            lambda: self.projTree.newTreeItem(nwItemType.FOLDER))

        self.mAddRoot = self.mAdd.addMenu(
            trConst(nwLabels.ITEM_DESCRIPTION["root"]))
        self._addRootFolderEntry(nwItemClass.NOVEL)
        self._addRootFolderEntry(nwItemClass.ARCHIVE)
        self.mAddRoot.addSeparator()
        self._addRootFolderEntry(nwItemClass.PLOT)
        self._addRootFolderEntry(nwItemClass.CHARACTER)
        self._addRootFolderEntry(nwItemClass.WORLD)
        self._addRootFolderEntry(nwItemClass.TIMELINE)
        self._addRootFolderEntry(nwItemClass.OBJECT)
        self._addRootFolderEntry(nwItemClass.ENTITY)
        self._addRootFolderEntry(nwItemClass.CUSTOM)

        self.tbAdd = QToolButton(self)
        self.tbAdd.setToolTip("%s [Ctrl+N]" % self.tr("Add Item"))
        self.tbAdd.setShortcut("Ctrl+N")
        self.tbAdd.setIcon(self.mainTheme.getIcon("add"))
        self.tbAdd.setIconSize(QSize(iPx, iPx))
        self.tbAdd.setStyleSheet(buttonStyle)
        self.tbAdd.setMenu(self.mAdd)
        self.tbAdd.setPopupMode(QToolButton.InstantPopup)

        # More Options Menu
        self.mMore = QMenu()

        self.aMoreUndo = self.mMore.addAction(self.tr("Undo Move"))
        self.aMoreUndo.triggered.connect(lambda: self.projTree.undoLastMove())

        self.aEmptyTrash = self.mMore.addAction(self.tr("Empty Trash"))
        self.aEmptyTrash.triggered.connect(lambda: self.projTree.emptyTrash())

        self.tbMore = QToolButton(self)
        self.tbMore.setToolTip(self.tr("More Options"))
        self.tbMore.setIcon(self.mainTheme.getIcon("menu"))
        self.tbMore.setIconSize(QSize(iPx, iPx))
        self.tbMore.setStyleSheet(buttonStyle)
        self.tbMore.setMenu(self.mMore)
        self.tbMore.setPopupMode(QToolButton.InstantPopup)

        # Assemble
        self.outerBox = QHBoxLayout()
        self.outerBox.addWidget(self.viewLabel)
        self.outerBox.addWidget(self.tbMoveU)
        self.outerBox.addWidget(self.tbMoveD)
        self.outerBox.addWidget(self.tbAdd)
        self.outerBox.addWidget(self.tbMore)
        self.outerBox.setContentsMargins(mPx, mPx, 0, mPx)
        self.outerBox.setSpacing(0)

        self.setLayout(self.outerBox)

        logger.debug("GuiProjectToolBar initialisation complete")

        return
コード例 #16
0
    def __init__(self, novelView):
        QTreeWidget.__init__(self, novelView)

        logger.debug("Initialising GuiNovelTree ...")

        self.mainConf = novelwriter.CONFIG
        self.novelView = novelView
        self.mainGui = novelView.mainGui
        self.mainTheme = novelView.mainGui.mainTheme
        self.theProject = novelView.mainGui.theProject

        # Internal Variables
        self._treeMap = {}
        self._lastBuild = 0
        self._lastCol = NovelTreeColumn.POV
        self._actHandle = None

        # Cached Strings
        self._povLabel = trConst(nwLabels.KEY_NAME[nwKeyWords.POV_KEY])
        self._focLabel = trConst(nwLabels.KEY_NAME[nwKeyWords.FOCUS_KEY])
        self._pltLabel = trConst(nwLabels.KEY_NAME[nwKeyWords.PLOT_KEY])

        # Build GUI
        # =========

        iPx = self.mainTheme.baseIconSize
        cMg = self.mainConf.pxInt(6)

        self.setIconSize(QSize(iPx, iPx))
        self.setFrameStyle(QFrame.NoFrame)
        self.setUniformRowHeights(True)
        self.setAllColumnsShowFocus(True)
        self.setHeaderHidden(True)
        self.setIndentation(0)
        self.setColumnCount(4)
        self.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.setSelectionMode(QAbstractItemView.SingleSelection)
        self.setExpandsOnDoubleClick(False)
        self.setDragEnabled(False)

        # Lock the column sizes
        treeHeader = self.header()
        treeHeader.setStretchLastSection(False)
        treeHeader.setMinimumSectionSize(iPx + cMg)
        treeHeader.setSectionResizeMode(self.C_TITLE, QHeaderView.Stretch)
        treeHeader.setSectionResizeMode(self.C_WORDS,
                                        QHeaderView.ResizeToContents)
        treeHeader.setSectionResizeMode(self.C_EXTRA,
                                        QHeaderView.ResizeToContents)
        treeHeader.setSectionResizeMode(self.C_MORE,
                                        QHeaderView.ResizeToContents)

        # Pre-Generate Tree Formatting
        fH1 = self.font()
        fH1.setBold(True)
        fH1.setUnderline(True)

        fH2 = self.font()
        fH2.setBold(True)

        self._hFonts = [self.font(), fH1, fH2, self.font(), self.font()]
        self._pIndent = [
            self.mainTheme.loadDecoration("deco_doc_h0", pxH=iPx),
            self.mainTheme.loadDecoration("deco_doc_h1", pxH=iPx),
            self.mainTheme.loadDecoration("deco_doc_h2", pxH=iPx),
            self.mainTheme.loadDecoration("deco_doc_h3", pxH=iPx),
            self.mainTheme.loadDecoration("deco_doc_h4", pxH=iPx),
        ]
        self._pMore = self.mainTheme.loadDecoration("deco_doc_more", pxH=iPx)
        self._pActive = self.mainTheme.loadDecoration("deco_more_on", pxH=iPx)
        self._pInactive = self.mainTheme.loadDecoration("deco_more_off",
                                                        pxH=iPx)

        # Connect signals
        self.clicked.connect(self._treeItemClicked)
        self.itemDoubleClicked.connect(self._treeDoubleClick)
        self.itemSelectionChanged.connect(self._treeSelectionChange)

        # Set custom settings
        self.initSettings()

        logger.debug("GuiNovelTree initialisation complete")

        return