diff --git a/novelwriter/assets/images/welcome-dark.jpg b/novelwriter/assets/images/welcome-dark.jpg index d8fd1c5f8..1b4349120 100644 Binary files a/novelwriter/assets/images/welcome-dark.jpg and b/novelwriter/assets/images/welcome-dark.jpg differ diff --git a/novelwriter/assets/images/welcome-light.jpg b/novelwriter/assets/images/welcome-light.jpg index 70cf548c1..1a1b9f6a7 100644 Binary files a/novelwriter/assets/images/welcome-light.jpg and b/novelwriter/assets/images/welcome-light.jpg differ diff --git a/novelwriter/config.py b/novelwriter/config.py index ad39b2184..568c03767 100644 --- a/novelwriter/config.py +++ b/novelwriter/config.py @@ -110,7 +110,7 @@ def __init__(self) -> None: # Size Settings self._mainWinSize = [1200, 650] # Last size of the main GUI window - self._welcomeSize = [800, 500] # Last size of the welcome window + self._welcomeSize = [800, 550] # Last size of the welcome window self._prefsWinSize = [700, 615] # Last size of the Preferences dialog self._mainPanePos = [300, 800] # Last position of the main window splitter self._viewPanePos = [500, 150] # Last position of the document viewer splitter diff --git a/novelwriter/dialogs/docmerge.py b/novelwriter/dialogs/docmerge.py index a0c436114..0466b09cf 100644 --- a/novelwriter/dialogs/docmerge.py +++ b/novelwriter/dialogs/docmerge.py @@ -74,7 +74,7 @@ def __init__(self, parent: QWidget, sHandle: str, itemList: list[str]) -> None: # Merge Options self.trashLabel = QLabel(self.tr("Move merged items to Trash")) - self.trashSwitch = NSwitch(width=2*iPx, height=iPx) + self.trashSwitch = NSwitch(self, height=iPx) self.optBox = QGridLayout() self.optBox.addWidget(self.trashLabel, 0, 0) diff --git a/novelwriter/dialogs/docsplit.py b/novelwriter/dialogs/docsplit.py index b8add4c04..6c96fc163 100644 --- a/novelwriter/dialogs/docsplit.py +++ b/novelwriter/dialogs/docsplit.py @@ -92,15 +92,15 @@ def __init__(self, parent: QWidget, sHandle: str) -> None: # Split Options self.folderLabel = QLabel(self.tr("Split into a new folder")) - self.folderSwitch = NSwitch(width=2*iPx, height=iPx) + self.folderSwitch = NSwitch(self, height=iPx) self.folderSwitch.setChecked(intoFolder) self.hierarchyLabel = QLabel(self.tr("Create document hierarchy")) - self.hierarchySwitch = NSwitch(width=2*iPx, height=iPx) + self.hierarchySwitch = NSwitch(self, height=iPx) self.hierarchySwitch.setChecked(docHierarchy) self.trashLabel = QLabel(self.tr("Move split document to Trash")) - self.trashSwitch = NSwitch(width=2*iPx, height=iPx) + self.trashSwitch = NSwitch(self, height=iPx) self.optBox = QGridLayout() self.optBox.addWidget(self.folderLabel, 0, 0) diff --git a/novelwriter/extensions/switch.py b/novelwriter/extensions/switch.py index 54db8914c..ab32ddbbb 100644 --- a/novelwriter/extensions/switch.py +++ b/novelwriter/extensions/switch.py @@ -34,11 +34,11 @@ class NSwitch(QAbstractButton): __slots__ = ("_xW", "_xH", "_xR", "_rB", "_rH", "_rR", "_offset") - def __init__(self, parent: QWidget | None = None, width: int = 0, height: int = 0) -> None: + def __init__(self, parent: QWidget | None = None, height: int = 0) -> None: super().__init__(parent=parent) - self._xW = width or CONFIG.pxInt(40) self._xH = height or CONFIG.pxInt(20) + self._xW = 2*self._xH self._xR = int(self._xH*0.5) self._rB = int(CONFIG.guiScale*2) self._rH = self._xH - 2*self._rB @@ -61,7 +61,7 @@ def offset(self) -> int: # type: ignore return self._offset @offset.setter # type: ignore - def offset(self, offset: int): + def offset(self, offset: int) -> None: self._offset = offset self.update() return diff --git a/novelwriter/extensions/switchbox.py b/novelwriter/extensions/switchbox.py index 5a21ddf7e..28f9d81a4 100644 --- a/novelwriter/extensions/switchbox.py +++ b/novelwriter/extensions/switchbox.py @@ -87,7 +87,7 @@ def addItem(self, qIcon: QIcon, text: str, identifier: str, default: bool = Fals label = QLabel(text) self._content.addWidget(label, self._index, 1, Qt.AlignLeft) - switch = NSwitch(width=self._wSwitch, height=self._hSwitch) + switch = NSwitch(self, height=self._hSwitch) switch.setChecked(default) switch.toggled.connect(lambda state: self._emitSwitchSignal(identifier, state)) self._content.addWidget(switch, self._index, 2, Qt.AlignRight) diff --git a/novelwriter/tools/manussettings.py b/novelwriter/tools/manussettings.py index 28404c50e..fe78f3b4d 100644 --- a/novelwriter/tools/manussettings.py +++ b/novelwriter/tools/manussettings.py @@ -659,7 +659,7 @@ def __init__(self, buildMain: GuiBuildSettings, build: BuildSettings) -> None: self.btnScene.clicked.connect(lambda: self._editHeading(self.EDIT_SCENE)) self.hdeScene = QLabel(self.tr("Hide")) self.hdeScene.setToolTip(sceneHideTip) - self.swtScene = NSwitch(self, width=2*iPx, height=iPx) + self.swtScene = NSwitch(self, height=iPx) self.swtScene.setToolTip(sceneHideTip) wrapScene = QHBoxLayout() @@ -686,7 +686,7 @@ def __init__(self, buildMain: GuiBuildSettings, build: BuildSettings) -> None: self.btnSection.clicked.connect(lambda: self._editHeading(self.EDIT_SECTION)) self.hdeSection = QLabel(self.tr("Hide")) self.hdeSection.setToolTip(sectionHideTip) - self.swtSection = NSwitch(self, width=2*iPx, height=iPx) + self.swtSection = NSwitch(self, height=iPx) self.swtSection.setToolTip(sectionHideTip) wrapSection = QHBoxLayout() @@ -894,10 +894,10 @@ def __init__(self, buildMain: GuiBuildSettings, build: BuildSettings) -> None: iPx = SHARED.theme.baseIconSize # Text Content - self.incSynopsis = NSwitch(self, width=2*iPx, height=iPx) - self.incComments = NSwitch(self, width=2*iPx, height=iPx) - self.incKeywords = NSwitch(self, width=2*iPx, height=iPx) - self.incBodyText = NSwitch(self, width=2*iPx, height=iPx) + self.incSynopsis = NSwitch(self, height=iPx) + self.incComments = NSwitch(self, height=iPx) + self.incKeywords = NSwitch(self, height=iPx) + self.incBodyText = NSwitch(self, height=iPx) self.addGroupLabel(self._build.getLabel("text.grpContent")) self.addRow(self._build.getLabel("text.includeSynopsis"), self.incSynopsis) @@ -906,7 +906,7 @@ def __init__(self, buildMain: GuiBuildSettings, build: BuildSettings) -> None: self.addRow(self._build.getLabel("text.includeBodyText"), self.incBodyText) # Insert Content - self.addNoteHead = NSwitch(self, width=2*iPx, height=iPx) + self.addNoteHead = NSwitch(self, height=iPx) self.addGroupLabel(self._build.getLabel("text.grpInsert")) self.addRow(self._build.getLabel("text.addNoteHeadings"), self.addNoteHead) @@ -989,9 +989,9 @@ def __init__(self, buildMain: GuiBuildSettings, build: BuildSettings) -> None: self.addGroupLabel(self._build.getLabel("format.grpOptions")) - self.justifyText = NSwitch(self, width=2*iPx, height=iPx) - self.stripUnicode = NSwitch(self, width=2*iPx, height=iPx) - self.replaceTabs = NSwitch(self, width=2*iPx, height=iPx) + self.justifyText = NSwitch(self, height=iPx) + self.stripUnicode = NSwitch(self, height=iPx) + self.replaceTabs = NSwitch(self, height=iPx) self.addRow(self._build.getLabel("format.justifyText"), self.justifyText) self.addRow(self._build.getLabel("format.stripUnicode"), self.stripUnicode) @@ -1219,7 +1219,7 @@ def __init__(self, buildMain: GuiBuildSettings, build: BuildSettings) -> None: # Open Document self.addGroupLabel(self._build.getLabel("odt")) - self.odtAddColours = NSwitch(self, width=2*iPx, height=iPx) + self.odtAddColours = NSwitch(self, height=iPx) self.addRow(self._build.getLabel("odt.addColours"), self.odtAddColours) self.odtPageHeader = QLineEdit(self) @@ -1242,7 +1242,7 @@ def __init__(self, buildMain: GuiBuildSettings, build: BuildSettings) -> None: # HTML Document self.addGroupLabel(self._build.getLabel("html")) - self.htmlAddStyles = NSwitch(self, width=2*iPx, height=iPx) + self.htmlAddStyles = NSwitch(self, height=iPx) self.addRow(self._build.getLabel("html.addStyles"), self.htmlAddStyles) # Finalise diff --git a/novelwriter/tools/noveldetails.py b/novelwriter/tools/noveldetails.py index 1dcbbeb69..05cf04360 100644 --- a/novelwriter/tools/noveldetails.py +++ b/novelwriter/tools/noveldetails.py @@ -384,7 +384,7 @@ def __init__(self, parent: QWidget) -> None: self.dblLabel = QLabel(self.tr("Chapters on odd pages")) - self.dblValue = NSwitch(self, 2*iPx, iPx) + self.dblValue = NSwitch(self, height=iPx) self.dblValue.setChecked(clearDouble) self.dblValue.clicked.connect(self._populateTree) diff --git a/novelwriter/tools/welcome.py b/novelwriter/tools/welcome.py index 1fa3ace32..7353c086a 100644 --- a/novelwriter/tools/welcome.py +++ b/novelwriter/tools/welcome.py @@ -34,8 +34,8 @@ pyqtSignal, pyqtSlot ) from PyQt5.QtWidgets import ( - QDialog, QDialogButtonBox, QFileDialog, QFormLayout, QHBoxLayout, QLabel, - QLineEdit, QListView, QMenu, QPushButton, QScrollArea, QShortcut, + QAction, QDialog, QDialogButtonBox, QFileDialog, QFormLayout, QHBoxLayout, + QLabel, QLineEdit, QListView, QMenu, QPushButton, QScrollArea, QShortcut, QStackedWidget, QStyle, QStyleOptionViewItem, QStyledItemDelegate, QToolButton, QVBoxLayout, QWidget, qApp ) @@ -43,13 +43,15 @@ from novelwriter import CONFIG, SHARED, __version__, __date__ from novelwriter.enum import nwItemClass from novelwriter.common import formatInt, formatVersion, makeFileNameSafe -from novelwriter.constants import nwUnicode +from novelwriter.constants import nwFiles, nwUnicode from novelwriter.core.coretools import ProjectBuilder from novelwriter.extensions.switch import NSwitch from novelwriter.extensions.modified import NComboBox, NSpinBox logger = logging.getLogger(__name__) +PANEL_ALPHA = 0.7 + class GuiWelcome(QDialog): @@ -62,15 +64,16 @@ def __init__(self, parent: QWidget) -> None: self.setObjectName("GuiWelcome") self.setWindowTitle(self.tr("Welcome")) - self.setMinimumWidth(CONFIG.pxInt(700)) - self.setMinimumHeight(CONFIG.pxInt(400)) + self.setMinimumWidth(CONFIG.pxInt(650)) + self.setMinimumHeight(CONFIG.pxInt(450)) hA = CONFIG.pxInt(8) hB = CONFIG.pxInt(16) hC = CONFIG.pxInt(24) hD = CONFIG.pxInt(36) hE = CONFIG.pxInt(48) - hF = CONFIG.pxInt(96) + hF = CONFIG.pxInt(128) + self._hPx = CONFIG.pxInt(600) self.resize(*CONFIG.welcomeWinSize) @@ -127,14 +130,14 @@ def __init__(self, parent: QWidget) -> None: self.innerBox.addWidget(self.nwInfo) self.innerBox.addSpacing(hA) self.innerBox.addWidget(self.mainStack) - self.innerBox.addSpacing(hA) + self.innerBox.addSpacing(hB) self.innerBox.addWidget(self.btnBox) topRight = Qt.AlignmentFlag.AlignTop | Qt.AlignmentFlag.AlignRight self.outerBox = QHBoxLayout() self.outerBox.addWidget(self.nwLogo, 3, topRight) - self.outerBox.addLayout(self.innerBox, 7) + self.outerBox.addLayout(self.innerBox, 9) self.outerBox.setContentsMargins(hF, hE, hC, hE) self.setLayout(self.outerBox) @@ -155,7 +158,7 @@ def __del__(self) -> None: # pragma: no cover def paintEvent(self, event: QPaintEvent) -> None: """Overload the paint event to draw the background image.""" hWin = self.height() - hPix = min(hWin, 700) + hPix = min(hWin, self._hPx) tMode = Qt.TransformationMode.SmoothTransformation painter = QPainter(self) painter.fillRect(self.rect(), self.bgColor) @@ -238,8 +241,13 @@ def __init__(self, parent: QWidget) -> None: self.listWidget.customContextMenuRequested.connect(self._openContextMenu) # Info / Tool + self.aMissing = QAction(self) + self.aMissing.setIcon(SHARED.theme.getIcon("alert_warn")) + self.aMissing.setToolTip(self.tr("The project path is not reachable.")) + self.selectedPath = QLineEdit(self) self.selectedPath.setReadOnly(True) + self.selectedPath.addAction(self.aMissing, QLineEdit.ActionPosition.TrailingPosition) self.keyDelete = QShortcut(self) self.keyDelete.setKey(Qt.Key.Key_Delete) @@ -257,9 +265,10 @@ def __init__(self, parent: QWidget) -> None: baseCol = self.palette().base().color() self.setStyleSheet(( - "QListView {{border: none; background: rgba({r},{g},{b},0.65);}} " - "QLineEdit {{border: none; background: rgba({r},{g},{b},0.65); padding: {m}px;}} " - ).format(r=baseCol.red(), g=baseCol.green(), b=baseCol.blue(), m=CONFIG.pxInt(4))) + "QListView {{border: none; background: rgba({r},{g},{b},{a});}} " + "QLineEdit {{border: none; background: rgba({r},{g},{b},{a}); padding: {m}px;}} " + ).format(r=baseCol.red(), g=baseCol.green(), b=baseCol.blue(), + a=PANEL_ALPHA, m=CONFIG.pxInt(4))) return @@ -283,7 +292,11 @@ def _projectClicked(self, index: QModelIndex) -> None: """Process single click on project item.""" path = self.tr("Path") value = index.data()[1] if index.isValid() else "" - self.selectedPath.setText(f"{path}: {value}") + text = f"{path}: {value}" + self.selectedPath.setText(text) + self.selectedPath.setToolTip(text) + self.selectedPath.setCursorPosition(0) + self.aMissing.setVisible(not (Path(value) / nwFiles.PROJ_FILE).is_file()) return @pyqtSlot(QModelIndex) @@ -482,9 +495,9 @@ def __init__(self, parent: QWidget) -> None: baseCol = self.palette().base().color() self.setStyleSheet(( - "QScrollArea {{border: none; background: rgba({r},{g},{b},0.65);}} " - "_NewProjectForm {{border: none; background: rgba({r},{g},{b},0.65);}} " - ).format(r=baseCol.red(), g=baseCol.green(), b=baseCol.blue())) + "QScrollArea {{border: none; background: rgba({r},{g},{b},{a});}} " + "_NewProjectForm {{border: none; background: rgba({r},{g},{b},{a});}} " + ).format(r=baseCol.red(), g=baseCol.green(), b=baseCol.blue(), a=PANEL_ALPHA)) return @@ -520,6 +533,8 @@ def __init__(self, parent: QWidget) -> None: self._fillMode = self.FILL_BLANK self._copyPath = None + iPx = SHARED.theme.baseIconSize + # Project Settings # ================ @@ -623,19 +638,19 @@ def __init__(self, parent: QWidget) -> None: # Project Notes # ============= - self.addPlot = NSwitch(self) + self.addPlot = NSwitch(self, height=iPx) self.addPlot.setChecked(True) self.addPlot.clicked.connect(self._syncSwitches) - self.addChar = NSwitch(self) + self.addChar = NSwitch(self, height=iPx) self.addChar.setChecked(True) self.addChar.clicked.connect(self._syncSwitches) - self.addWorld = NSwitch(self) + self.addWorld = NSwitch(self, height=iPx) self.addWorld.setChecked(False) self.addWorld.clicked.connect(self._syncSwitches) - self.addNotes = NSwitch() + self.addNotes = NSwitch(self, height=iPx) self.addNotes.setChecked(False) self.notesForm = QFormLayout() diff --git a/novelwriter/tools/writingstats.py b/novelwriter/tools/writingstats.py index 1309c61f1..a215df20c 100644 --- a/novelwriter/tools/writingstats.py +++ b/novelwriter/tools/writingstats.py @@ -193,37 +193,37 @@ def __init__(self, mainGui: GuiMain) -> None: self.filterForm = QGridLayout(self) self.filterBox.setLayout(self.filterForm) - self.incNovel = NSwitch(width=2*sPx, height=sPx) + self.incNovel = NSwitch(self, height=sPx) self.incNovel.setChecked( pOptions.getBool("GuiWritingStats", "incNovel", True) ) self.incNovel.clicked.connect(self._updateListBox) - self.incNotes = NSwitch(width=2*sPx, height=sPx) + self.incNotes = NSwitch(self, height=sPx) self.incNotes.setChecked( pOptions.getBool("GuiWritingStats", "incNotes", True) ) self.incNotes.clicked.connect(self._updateListBox) - self.hideZeros = NSwitch(width=2*sPx, height=sPx) + self.hideZeros = NSwitch(self, height=sPx) self.hideZeros.setChecked( pOptions.getBool("GuiWritingStats", "hideZeros", True) ) self.hideZeros.clicked.connect(self._updateListBox) - self.hideNegative = NSwitch(width=2*sPx, height=sPx) + self.hideNegative = NSwitch(self, height=sPx) self.hideNegative.setChecked( pOptions.getBool("GuiWritingStats", "hideNegative", False) ) self.hideNegative.clicked.connect(self._updateListBox) - self.groupByDay = NSwitch(width=2*sPx, height=sPx) + self.groupByDay = NSwitch(self, height=sPx) self.groupByDay.setChecked( pOptions.getBool("GuiWritingStats", "groupByDay", False) ) self.groupByDay.clicked.connect(self._updateListBox) - self.showIdleTime = NSwitch(width=2*sPx, height=sPx) + self.showIdleTime = NSwitch(self, height=sPx) self.showIdleTime.setChecked( pOptions.getBool("GuiWritingStats", "showIdleTime", False) ) diff --git a/tests/reference/baseConfig_novelwriter.conf b/tests/reference/baseConfig_novelwriter.conf index 32a9883e1..998394a08 100644 --- a/tests/reference/baseConfig_novelwriter.conf +++ b/tests/reference/baseConfig_novelwriter.conf @@ -1,5 +1,5 @@ [Meta] -timestamp = 2023-12-29 14:11:20 +timestamp = 2024-02-09 12:05:00 [Main] theme = default @@ -14,7 +14,7 @@ lastpath = [Sizes] mainwindow = 1200, 650 -welcome = 800, 500 +welcome = 800, 550 preferences = 700, 615 mainpane = 300, 800 viewpane = 500, 150