summaryrefslogtreecommitdiff
path: root/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/Notepad
diff options
context:
space:
mode:
Diffstat (limited to 'raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/Notepad')
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/Notepad/Notepad.qml531
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/Notepad/NotepadSettings.qml367
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/Notepad/NotepadTabs.qml285
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/Notepad/NotepadTextEditor.qml924
4 files changed, 0 insertions, 2107 deletions
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/Notepad/Notepad.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/Notepad/Notepad.qml
deleted file mode 100644
index e294695..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/Notepad/Notepad.qml
+++ /dev/null
@@ -1,531 +0,0 @@
-pragma ComponentBehavior: Bound
-import QtQuick
-import Quickshell
-import Quickshell.Io
-import qs.Common
-import qs.Modals.Common
-import qs.Modals.FileBrowser
-import qs.Services
-import qs.Widgets
-
-Item {
- id: root
-
- property bool fileDialogOpen: false
- property string currentFileName: ""
- property url currentFileUrl
- property bool confirmationDialogOpen: false
- property string pendingAction: ""
- property url pendingFileUrl
- property string lastSavedFileContent: ""
- property var currentTab: NotepadStorageService.tabs.length > NotepadStorageService.currentTabIndex ? NotepadStorageService.tabs[NotepadStorageService.currentTabIndex] : null
- property bool showSettingsMenu: false
- property string pendingSaveContent: ""
- property var slideout: null
-
- signal hideRequested
- signal previewRequested(string content)
-
- Ref {
- service: NotepadStorageService
- }
-
- Connections {
- target: slideout
- enabled: slideout !== null
- function onAboutToHide() {
- textEditor.autoSaveToSession()
- }
- }
-
- function hasUnsavedChanges() {
- return textEditor.hasUnsavedChanges();
- }
-
- function hasUnsavedTemporaryContent() {
- return hasUnsavedChanges();
- }
-
- function createNewTab() {
- performCreateNewTab();
- }
-
- function performCreateNewTab() {
- NotepadStorageService.createNewTab();
- textEditor.text = "";
- textEditor.lastSavedContent = "";
- textEditor.contentLoaded = true;
- textEditor.textArea.forceActiveFocus();
- }
-
- function closeTab(tabIndex) {
- if (tabIndex === NotepadStorageService.currentTabIndex && hasUnsavedChanges()) {
- root.pendingAction = "close_tab_" + tabIndex;
- root.confirmationDialogOpen = true;
- confirmationDialogLoader.active = true;
- if (confirmationDialogLoader.item)
- confirmationDialogLoader.item.open();
- } else {
- performCloseTab(tabIndex);
- }
- }
-
- function performCloseTab(tabIndex) {
- NotepadStorageService.closeTab(tabIndex);
- Qt.callLater(() => {
- textEditor.loadCurrentTabContent();
- });
- }
-
- function switchToTab(tabIndex) {
- if (tabIndex < 0 || tabIndex >= NotepadStorageService.tabs.length)
- return;
- if (textEditor.contentLoaded) {
- textEditor.autoSaveToSession();
- }
-
- NotepadStorageService.switchToTab(tabIndex);
- Qt.callLater(() => {
- textEditor.loadCurrentTabContent();
- if (currentTab) {
- root.currentFileName = currentTab.fileName || "";
- root.currentFileUrl = currentTab.fileUrl || "";
- }
- });
- }
-
- function saveToFile(fileUrl) {
- if (!currentTab)
- return;
- var content = textEditor.text;
- var filePath = fileUrl.toString().replace(/^file:\/\//, '');
-
- saveFileView.path = "";
- pendingSaveContent = content;
- saveFileView.path = filePath;
-
- Qt.callLater(() => {
- saveFileView.setText(pendingSaveContent);
- });
- }
-
- function loadFromFile(fileUrl) {
- if (hasUnsavedTemporaryContent()) {
- root.pendingFileUrl = fileUrl;
- root.pendingAction = "load_file";
- root.confirmationDialogOpen = true;
- confirmationDialogLoader.active = true;
- if (confirmationDialogLoader.item)
- confirmationDialogLoader.item.open();
- } else {
- performLoadFromFile(fileUrl);
- }
- }
-
- function performLoadFromFile(fileUrl) {
- const filePath = fileUrl.toString().replace(/^file:\/\//, '');
- const fileName = filePath.split('/').pop();
-
- loadFileView.path = "";
- loadFileView.path = filePath;
-
- if (loadFileView.waitForJob()) {
- Qt.callLater(() => {
- var content = loadFileView.text();
- if (currentTab && content !== undefined && content !== null) {
- textEditor.text = content;
- textEditor.lastSavedContent = content;
- textEditor.contentLoaded = true;
- root.lastSavedFileContent = content;
-
- NotepadStorageService.updateTabMetadata(NotepadStorageService.currentTabIndex, {
- title: fileName,
- filePath: filePath,
- isTemporary: false
- });
-
- root.currentFileName = fileName;
- root.currentFileUrl = fileUrl;
- textEditor.saveCurrentTabContent();
- }
- });
- }
- }
-
- Column {
- anchors.fill: parent
- spacing: Theme.spacingM
-
- NotepadTabs {
- id: tabBar
- width: parent.width
- contentLoaded: textEditor.contentLoaded
-
- onTabSwitched: tabIndex => {
- switchToTab(tabIndex);
- }
-
- onTabClosed: tabIndex => {
- closeTab(tabIndex);
- }
-
- onNewTabRequested: {
- createNewTab();
- }
- }
-
- NotepadTextEditor {
- id: textEditor
- width: parent.width
- height: parent.height - tabBar.height - Theme.spacingM * 2
-
- onSaveRequested: {
- if (currentTab && !currentTab.isTemporary && currentTab.filePath) {
- var fileUrl = "file://" + currentTab.filePath;
- saveToFile(fileUrl);
- } else {
- root.fileDialogOpen = true;
- saveBrowserLoader.active = true;
- if (saveBrowserLoader.item)
- saveBrowserLoader.item.open();
- }
- }
-
- onOpenRequested: {
- textEditor.autoSaveToSession();
- if (textEditor.text.length > 0) {
- createNewTab();
- }
-
- root.fileDialogOpen = true;
- loadBrowserLoader.active = true;
- if (loadBrowserLoader.item)
- loadBrowserLoader.item.open();
- }
-
- onNewRequested: {
- textEditor.autoSaveToSession();
- createNewTab();
- }
-
- onPreviewRequested: {
- textEditor.togglePreview();
- }
-
- onEscapePressed: {
- textEditor.autoSaveToSession()
- root.hideRequested()
- }
-
- onSettingsRequested: {
- showSettingsMenu = !showSettingsMenu;
- }
- }
- }
-
- NotepadSettings {
- id: notepadSettings
- anchors.fill: parent
- isVisible: showSettingsMenu
- onSettingsRequested: showSettingsMenu = !showSettingsMenu
- onFindRequested: {
- showSettingsMenu = false;
- textEditor.showSearch();
- }
- }
-
- FileView {
- id: saveFileView
- blockWrites: true
- preload: false
- atomicWrites: true
- printErrors: true
-
- onSaved: {
- if (currentTab && saveFileView.path && pendingSaveContent) {
- NotepadStorageService.updateTabMetadata(NotepadStorageService.currentTabIndex, {
- hasUnsavedChanges: false,
- lastSavedContent: pendingSaveContent
- });
- root.lastSavedFileContent = pendingSaveContent;
- pendingSaveContent = "";
- }
- }
-
- onSaveFailed: error => {
- pendingSaveContent = "";
- }
- }
-
- FileView {
- id: loadFileView
- blockLoading: true
- preload: true
- atomicWrites: true
- printErrors: true
-
- onLoadFailed: error => {}
- }
-
- LazyLoader {
- id: saveBrowserLoader
- active: false
-
- FileBrowserSurfaceModal {
- id: saveBrowser
-
- browserTitle: I18n.tr("Save Notepad File")
- browserIcon: "save"
- browserType: "notepad_save"
- fileExtensions: ["*.txt", "*.md", "*.*"]
- allowStacking: true
- saveMode: true
- defaultFileName: {
- if (currentTab && currentTab.title && currentTab.title !== "Untitled") {
- return currentTab.title;
- } else if (currentTab && !currentTab.isTemporary && currentTab.filePath) {
- return currentTab.filePath.split('/').pop();
- } else {
- return "note.txt";
- }
- }
-
- onFileSelected: path => {
- root.fileDialogOpen = false;
- const cleanPath = decodeURI(path.toString().replace(/^file:\/\//, ''));
- const fileName = cleanPath.split('/').pop();
- const fileUrl = "file://" + cleanPath;
-
- root.currentFileName = fileName;
- root.currentFileUrl = fileUrl;
-
- if (currentTab) {
- NotepadStorageService.saveTabAs(NotepadStorageService.currentTabIndex, cleanPath);
- }
-
- saveToFile(fileUrl);
-
- if (root.pendingAction === "new") {
- Qt.callLater(() => {
- createNewTab();
- });
- } else if (root.pendingAction === "open") {
- Qt.callLater(() => {
- root.fileDialogOpen = true;
- loadBrowserLoader.active = true;
- if (loadBrowserLoader.item)
- loadBrowserLoader.item.open();
- });
- } else if (root.pendingAction.startsWith("close_tab_")) {
- Qt.callLater(() => {
- var tabIndex = parseInt(root.pendingAction.split("_")[2]);
- performCloseTab(tabIndex);
- });
- }
- root.pendingAction = "";
-
- close();
- }
-
- onDialogClosed: {
- root.fileDialogOpen = false;
- }
- }
- }
-
- LazyLoader {
- id: loadBrowserLoader
- active: false
-
- FileBrowserSurfaceModal {
- id: loadBrowser
-
- browserTitle: I18n.tr("Open Notepad File")
- browserIcon: "folder_open"
- browserType: "notepad_load"
- fileExtensions: ["*.txt", "*.md", "*.*"]
- allowStacking: true
-
- onFileSelected: path => {
- root.fileDialogOpen = false;
- const cleanPath = path.toString().replace(/^file:\/\//, '');
- const fileName = cleanPath.split('/').pop();
- const fileUrl = "file://" + cleanPath;
-
- root.currentFileName = fileName;
- root.currentFileUrl = fileUrl;
-
- loadFromFile(fileUrl);
- close();
- }
-
- onDialogClosed: {
- root.fileDialogOpen = false;
- }
- }
- }
-
- LazyLoader {
- id: confirmationDialogLoader
- active: false
-
- DankModal {
- id: confirmationDialog
-
- modalWidth: 400
- modalHeight: contentLoader.item ? contentLoader.item.implicitHeight + Theme.spacingM * 2 : 180
- shouldBeVisible: false
- allowStacking: true
-
- onBackgroundClicked: {
- close();
- root.confirmationDialogOpen = false;
- }
-
- content: Component {
- FocusScope {
- anchors.fill: parent
- focus: true
- implicitHeight: contentColumn.implicitHeight
-
- Keys.onEscapePressed: event => {
- confirmationDialog.close();
- root.confirmationDialogOpen = false;
- event.accepted = true;
- }
-
- Column {
- id: contentColumn
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.top: parent.top
- anchors.margins: Theme.spacingM
- spacing: Theme.spacingM
-
- StyledText {
- text: I18n.tr("Unsaved Changes")
- font.pixelSize: Theme.fontSizeLarge
- color: Theme.surfaceText
- font.weight: Font.Medium
- }
-
- StyledText {
- text: root.pendingAction === "new" ? I18n.tr("You have unsaved changes. Save before creating a new file?") : root.pendingAction.startsWith("close_tab_") ? I18n.tr("You have unsaved changes. Save before closing this tab?") : root.pendingAction === "load_file" || root.pendingAction === "open" ? I18n.tr("You have unsaved changes. Save before opening a file?") : I18n.tr("You have unsaved changes. Save before continuing?")
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceTextMedium
- width: parent.width
- wrapMode: Text.Wrap
- }
-
- Item {
- width: parent.width
- height: 36
-
- Row {
- anchors.right: parent.right
- anchors.verticalCenter: parent.verticalCenter
- spacing: Theme.spacingM
-
- Rectangle {
- width: Math.max(80, discardText.contentWidth + Theme.spacingM * 2)
- height: 36
- radius: Theme.cornerRadius
- color: discardArea.containsMouse ? Theme.surfaceTextHover : "transparent"
- border.color: Theme.surfaceVariantAlpha
- border.width: 1
-
- StyledText {
- id: discardText
- anchors.centerIn: parent
- text: I18n.tr("Don't Save")
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceText
- font.weight: Font.Medium
- }
-
- MouseArea {
- id: discardArea
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onClicked: {
- confirmationDialog.close();
- root.confirmationDialogOpen = false;
- if (root.pendingAction === "new") {
- createNewTab();
- } else if (root.pendingAction === "open") {
- root.fileDialogOpen = true;
- loadBrowserLoader.active = true;
- if (loadBrowserLoader.item)
- loadBrowserLoader.item.open();
- } else if (root.pendingAction === "load_file") {
- performLoadFromFile(root.pendingFileUrl);
- } else if (root.pendingAction.startsWith("close_tab_")) {
- var tabIndex = parseInt(root.pendingAction.split("_")[2]);
- performCloseTab(tabIndex);
- }
- root.pendingAction = "";
- root.pendingFileUrl = "";
- }
- }
- }
-
- Rectangle {
- width: Math.max(70, saveAsText.contentWidth + Theme.spacingM * 2)
- height: 36
- radius: Theme.cornerRadius
- color: saveAsArea.containsMouse ? Qt.darker(Theme.primary, 1.1) : Theme.primary
-
- StyledText {
- id: saveAsText
- anchors.centerIn: parent
- text: I18n.tr("Save")
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.background
- font.weight: Font.Medium
- }
-
- MouseArea {
- id: saveAsArea
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onClicked: {
- confirmationDialog.close();
- root.confirmationDialogOpen = false;
- root.fileDialogOpen = true;
- saveBrowserLoader.active = true;
- if (saveBrowserLoader.item)
- saveBrowserLoader.item.open();
- }
- }
-
- Behavior on color {
- ColorAnimation {
- duration: Theme.shortDuration
- easing.type: Theme.standardEasing
- }
- }
- }
- }
- }
- }
-
- DankActionButton {
- anchors.top: parent.top
- anchors.right: parent.right
- anchors.topMargin: Theme.spacingM
- anchors.rightMargin: Theme.spacingM
- iconName: "close"
- iconSize: Theme.iconSize - 4
- iconColor: Theme.surfaceText
- onClicked: {
- confirmationDialog.close();
- root.confirmationDialogOpen = false;
- }
- }
- }
- }
- }
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/Notepad/NotepadSettings.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/Notepad/NotepadSettings.qml
deleted file mode 100644
index 9265ddf..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/Notepad/NotepadSettings.qml
+++ /dev/null
@@ -1,367 +0,0 @@
-pragma ComponentBehavior: Bound
-import QtQuick
-import qs.Common
-import qs.Widgets
-
-Item {
- id: root
-
- property bool isVisible: false
- property var cachedFontFamilies: []
- property var cachedMonoFamilies: []
- property bool fontsEnumerated: false
-
- signal settingsRequested
- signal findRequested
-
- function enumerateFonts() {
- var fonts = ["Default"];
- var availableFonts = Qt.fontFamilies();
- var rootFamilies = [];
- var seenFamilies = new Set();
- for (var i = 0; i < availableFonts.length; i++) {
- var fontName = availableFonts[i];
- if (fontName.startsWith("."))
- continue;
- if (fontName === Theme.defaultFontFamily)
- continue;
- var rootName = fontName.replace(/ (Thin|Extra Light|Light|Regular|Medium|Semi Bold|Demi Bold|Bold|Extra Bold|Black|Heavy)$/i, "").replace(/ (Italic|Oblique|Condensed|Extended|Narrow|Wide)$/i, "").replace(/ (UI|Display|Text|Mono|Sans|Serif)$/i, function (match, suffix) {
- return match;
- }).trim();
- if (!seenFamilies.has(rootName) && rootName !== "") {
- seenFamilies.add(rootName);
- rootFamilies.push(rootName);
- }
- }
- cachedFontFamilies = fonts.concat(rootFamilies.sort());
- var monoFonts = ["Default"];
- var monoFamilies = [];
- var seenMonoFamilies = new Set();
- for (var j = 0; j < availableFonts.length; j++) {
- var fontName2 = availableFonts[j];
- if (fontName2.startsWith("."))
- continue;
- if (fontName2 === SettingsData.defaultMonoFontFamily)
- continue;
- var lowerName = fontName2.toLowerCase();
- if (lowerName.includes("mono") || lowerName.includes("code") || lowerName.includes("console") || lowerName.includes("terminal") || lowerName.includes("courier") || lowerName.includes("dejavu sans mono") || lowerName.includes("jetbrains") || lowerName.includes("fira") || lowerName.includes("hack") || lowerName.includes("source code") || lowerName.includes("ubuntu mono") || lowerName.includes("cascadia")) {
- var rootName2 = fontName2.replace(/ (Thin|Extra Light|Light|Regular|Medium|Semi Bold|Demi Bold|Bold|Extra Bold|Black|Heavy)$/i, "").replace(/ (Italic|Oblique|Condensed|Extended|Narrow|Wide)$/i, "").trim();
- if (!seenMonoFamilies.has(rootName2) && rootName2 !== "") {
- seenMonoFamilies.add(rootName2);
- monoFamilies.push(rootName2);
- }
- }
- }
- cachedMonoFamilies = monoFonts.concat(monoFamilies.sort());
- fontsEnumerated = true;
- }
-
- Component.onCompleted: {
- if (!fontsEnumerated) {
- enumerateFonts();
- }
- }
-
- MouseArea {
- anchors.fill: parent
- visible: root.isVisible
- onClicked: root.settingsRequested()
- z: 50
- }
-
- Rectangle {
- id: settingsMenu
- visible: root.isVisible
- anchors.horizontalCenter: parent.horizontalCenter
- anchors.verticalCenter: parent.verticalCenter
- width: 360
- height: settingsColumn.implicitHeight + Theme.spacingXL * 2
- radius: Theme.cornerRadius
- color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, Theme.notepadTransparency)
- border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
- border.width: 1
- z: 100
-
- Rectangle {
- anchors.fill: parent
- anchors.topMargin: 4
- anchors.leftMargin: 2
- anchors.rightMargin: -2
- anchors.bottomMargin: -4
- radius: parent.radius
- color: Qt.rgba(0, 0, 0, 0.15)
- z: parent.z - 1
- }
-
- Column {
- id: settingsColumn
- width: parent.width - Theme.spacingXL * 2
- anchors.horizontalCenter: parent.horizontalCenter
- anchors.top: parent.top
- anchors.topMargin: Theme.spacingXL
- spacing: Theme.spacingS
-
- Rectangle {
- width: parent.width
- height: 36
- color: "transparent"
-
- StyledText {
- anchors.left: parent.left
- anchors.leftMargin: -Theme.spacingXS
- anchors.verticalCenter: parent.verticalCenter
- text: I18n.tr("Notepad Font Settings")
- font.pixelSize: Theme.fontSizeMedium
- font.weight: Font.Medium
- color: Theme.surfaceText
- }
- }
-
- Rectangle {
- width: parent.width
- height: 1
- color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
- }
-
- DankToggle {
- anchors.left: parent.left
- anchors.leftMargin: -Theme.spacingM
- width: parent.width + Theme.spacingM
- text: I18n.tr("Use Monospace Font")
- description: "Toggle fonts"
- checked: SettingsData.notepadUseMonospace
- onToggled: checked => {
- SettingsData.notepadUseMonospace = checked;
- }
- }
-
- DankToggle {
- anchors.left: parent.left
- anchors.leftMargin: -Theme.spacingM
- width: parent.width + Theme.spacingM
- text: I18n.tr("Show Line Numbers")
- description: "Display line numbers in editor"
- checked: SettingsData.notepadShowLineNumbers
- onToggled: checked => {
- SettingsData.notepadShowLineNumbers = checked;
- }
- }
-
- StyledRect {
- width: parent.width
- height: 60
- radius: Theme.cornerRadius
- color: "transparent"
-
- StateLayer {
- anchors.fill: parent
- anchors.leftMargin: -Theme.spacingM
- width: parent.width + Theme.spacingM
- stateColor: Theme.primary
- cornerRadius: parent.radius
- onClicked: root.findRequested()
- }
-
- Row {
- anchors.left: parent.left
- anchors.leftMargin: -Theme.spacingM
- anchors.right: parent.right
- anchors.rightMargin: Theme.spacingM
- anchors.verticalCenter: parent.verticalCenter
- spacing: Theme.spacingM
-
- DankIcon {
- name: "search"
- size: Theme.iconSize - 2
- color: Theme.primary
- anchors.verticalCenter: parent.verticalCenter
- }
-
- Column {
- anchors.verticalCenter: parent.verticalCenter
- spacing: Theme.spacingXS
-
- StyledText {
- text: I18n.tr("Find in Text")
- font.pixelSize: Theme.fontSizeMedium
- font.weight: Font.Medium
- color: Theme.surfaceText
- }
-
- StyledText {
- text: I18n.tr("Open search bar to find text")
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceVariantText
- }
- }
- }
- }
-
- Rectangle {
- width: parent.width
- height: visible ? (fontDropdown.height + Theme.spacingS) : 0
- color: "transparent"
- visible: !SettingsData.notepadUseMonospace
-
- DankDropdown {
- id: fontDropdown
- anchors.left: parent.left
- anchors.leftMargin: -Theme.spacingM
- width: parent.width + Theme.spacingM
- text: I18n.tr("Font Family")
- options: cachedFontFamilies
- currentValue: {
- if (!SettingsData.notepadFontFamily || SettingsData.notepadFontFamily === "")
- return "Default (Global)";
- else
- return SettingsData.notepadFontFamily;
- }
- enableFuzzySearch: true
- onValueChanged: value => {
- if (value && (value.startsWith("Default") || value === "Default (Global)")) {
- SettingsData.notepadFontFamily = "";
- } else {
- SettingsData.notepadFontFamily = value;
- }
- }
- }
- }
-
- Rectangle {
- width: parent.width
- height: fontSizeRow.height + Theme.spacingS
- color: "transparent"
-
- Row {
- id: fontSizeRow
- width: parent.width
- spacing: Theme.spacingS
-
- Column {
- width: parent.width - fontSizeControls.width - Theme.spacingM
- spacing: Theme.spacingXS
-
- StyledText {
- text: I18n.tr("Font Size")
- font.pixelSize: Theme.fontSizeSmall
- font.weight: Font.Medium
- color: Theme.surfaceText
- }
-
- StyledText {
- text: SettingsData.notepadFontSize + "px"
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceVariantText
- width: parent.width
- }
- }
-
- Row {
- id: fontSizeControls
- spacing: Theme.spacingS
- anchors.verticalCenter: parent.verticalCenter
-
- DankActionButton {
- buttonSize: 32
- iconName: "remove"
- iconSize: Theme.iconSizeSmall
- enabled: SettingsData.notepadFontSize > 8
- backgroundColor: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.5)
- iconColor: Theme.surfaceText
- onClicked: {
- var newSize = Math.max(8, SettingsData.notepadFontSize - 1);
- SettingsData.notepadFontSize = newSize;
- }
- }
-
- Rectangle {
- width: 60
- height: 32
- radius: Theme.cornerRadius
- color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3)
- border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
- border.width: 1
-
- StyledText {
- anchors.centerIn: parent
- text: SettingsData.notepadFontSize + "px"
- font.pixelSize: Theme.fontSizeSmall
- font.weight: Font.Medium
- color: Theme.surfaceText
- }
- }
-
- DankActionButton {
- buttonSize: 32
- iconName: "add"
- iconSize: Theme.iconSizeSmall
- enabled: SettingsData.notepadFontSize < 48
- backgroundColor: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.5)
- iconColor: Theme.surfaceText
- onClicked: {
- var newSize = Math.min(48, SettingsData.notepadFontSize + 1);
- SettingsData.notepadFontSize = newSize;
- }
- }
- }
- }
- }
-
- Rectangle {
- width: parent.width
- height: transparencySliderColumn.height + Theme.spacingS
- color: "transparent"
-
- Column {
- id: transparencySliderColumn
- width: parent.width
- spacing: Theme.spacingS
-
- DankToggle {
- anchors.left: parent.left
- anchors.leftMargin: -Theme.spacingM
- width: parent.width + Theme.spacingM
- text: I18n.tr("Custom Transparency")
- description: "Override global transparency for Notepad"
- checked: SettingsData.notepadTransparencyOverride >= 0
- onToggled: checked => {
- if (checked) {
- SettingsData.notepadTransparencyOverride = SettingsData.notepadLastCustomTransparency;
- } else {
- SettingsData.notepadTransparencyOverride = -1;
- }
- }
- }
-
- DankSlider {
- anchors.left: parent.left
- anchors.leftMargin: -Theme.spacingM
- width: parent.width + Theme.spacingM
- height: 24
- visible: SettingsData.notepadTransparencyOverride >= 0
- value: Math.round((SettingsData.notepadTransparencyOverride >= 0 ? SettingsData.notepadTransparencyOverride : SettingsData.popupTransparency) * 100)
- minimum: 0
- maximum: 100
- unit: ""
- showValue: true
- wheelEnabled: false
- onSliderValueChanged: newValue => {
- if (SettingsData.notepadTransparencyOverride >= 0) {
- SettingsData.notepadTransparencyOverride = newValue / 100;
- }
- }
- }
- }
- }
-
- StyledText {
- width: parent.width
- text: SettingsData.notepadUseMonospace ? "Using global monospace font from Settings → Personalization" : "Global fonts can be configured in Settings → Personalization"
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceTextMedium
- wrapMode: Text.WordWrap
- opacity: 0.8
- }
- }
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/Notepad/NotepadTabs.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/Notepad/NotepadTabs.qml
deleted file mode 100644
index 05a21d1..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/Notepad/NotepadTabs.qml
+++ /dev/null
@@ -1,285 +0,0 @@
-pragma ComponentBehavior: Bound
-import QtQuick
-import QtQuick.Controls
-import qs.Common
-import qs.Services
-import qs.Widgets
-
-Column {
- id: root
-
- property var currentTab: NotepadStorageService.tabs.length > NotepadStorageService.currentTabIndex ? NotepadStorageService.tabs[NotepadStorageService.currentTabIndex] : null
- property bool contentLoaded: false
- property int draggedIndex: -1
- property int dropTargetIndex: -1
- property bool suppressShiftAnimation: false
- readonly property real tabItemSize: 128 + Theme.spacingXS
-
- signal tabSwitched(int tabIndex)
- signal tabClosed(int tabIndex)
- signal newTabRequested
-
- function hasUnsavedChangesForTab(tab) {
- if (!tab)
- return false;
-
- if (tab.id === currentTab?.id) {
- return root.parent?.hasUnsavedChanges ? root.parent.hasUnsavedChanges() : false;
- }
- return false;
- }
-
- spacing: Theme.spacingXS
-
- Row {
- width: parent.width
- height: 36
- spacing: Theme.spacingXS
-
- ScrollView {
- width: parent.width - newTabButton.width - Theme.spacingXS
- height: parent.height
- clip: true
-
- ScrollBar.horizontal.visible: false
- ScrollBar.vertical.visible: false
-
- Row {
- spacing: Theme.spacingXS
-
- Repeater {
- model: NotepadStorageService.tabs
-
- delegate: Item {
- id: delegateItem
- required property int index
- required property var modelData
-
- readonly property bool isActive: NotepadStorageService.currentTabIndex === index
- readonly property bool isHovered: tabMouseArea.containsMouse && !closeMouseArea.containsMouse
- readonly property real tabWidth: 128
- property bool longPressing: false
- property bool dragging: false
- property point dragStartPos: Qt.point(0, 0)
- property int targetIndex: -1
- property int originalIndex: -1
- property real dragAxisOffset: 0
-
- Timer {
- id: longPressTimer
- interval: 200
- repeat: false
- onTriggered: {
- if (NotepadStorageService.tabs.length > 1) {
- delegateItem.longPressing = true
- }
- }
- }
-
- readonly property real shiftOffset: {
- if (root.draggedIndex < 0)
- return 0
- if (index === root.draggedIndex)
- return 0
- var dragIdx = root.draggedIndex
- var dropIdx = root.dropTargetIndex
- var myIdx = index
- var shiftAmount = root.tabItemSize
- if (dropIdx < 0)
- return 0
- if (dragIdx < dropIdx && myIdx > dragIdx && myIdx <= dropIdx)
- return -shiftAmount
- if (dragIdx > dropIdx && myIdx >= dropIdx && myIdx < dragIdx)
- return shiftAmount
- return 0
- }
-
- width: tabWidth
- height: 32
- z: dragging ? 100 : 0
-
- transform: Translate {
- x: shiftOffset
- Behavior on x {
- enabled: !root.suppressShiftAnimation
- NumberAnimation {
- duration: 150
- easing.type: Easing.OutCubic
- }
- }
- }
-
- Item {
- id: tabVisual
- anchors.fill: parent
- z: 1
- layer.enabled: dragging
- layer.smooth: true
-
- transform: Translate {
- x: dragging ? dragAxisOffset : 0
- }
-
- Rectangle {
- id: tabRect
- anchors.fill: parent
- radius: Theme.cornerRadius
- color: isActive ? Theme.primaryPressed : isHovered ? Theme.primaryHoverLight : Theme.withAlpha(Theme.primaryPressed, 0)
- border.width: isActive || dragging ? 0 : 1
- border.color: dragging ? Theme.primary : Theme.outlineMedium
- clip: true
-
- Row {
- id: tabContent
- anchors.fill: parent
- anchors.leftMargin: Theme.spacingM
- anchors.rightMargin: Theme.spacingM
- spacing: Theme.spacingXS
-
- StyledText {
- id: tabText
- width: parent.width - (tabCloseButton.visible ? tabCloseButton.width + Theme.spacingXS : 0)
- text: {
- var prefix = ""
- if (hasUnsavedChangesForTab(modelData)) {
- prefix = "● "
- }
- return prefix + (modelData.title || "Untitled")
- }
- font.pixelSize: Theme.fontSizeSmall
- color: isActive ? Theme.primary : Theme.surfaceText
- font.weight: isActive ? Font.Medium : Font.Normal
- elide: Text.ElideMiddle
- maximumLineCount: 1
- wrapMode: Text.NoWrap
- anchors.verticalCenter: parent.verticalCenter
- }
-
- Rectangle {
- id: tabCloseButton
- width: 20
- height: 20
- radius: Theme.cornerRadius
- color: closeMouseArea.containsMouse ? Theme.surfaceTextHover : Theme.withAlpha(Theme.surfaceTextHover, 0)
- visible: NotepadStorageService.tabs.length > 1
- anchors.verticalCenter: parent.verticalCenter
-
- DankIcon {
- name: "close"
- size: 14
- color: Theme.surfaceTextMedium
- anchors.centerIn: parent
- }
-
- MouseArea {
- id: closeMouseArea
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- z: 100
-
- onClicked: root.tabClosed(index)
- }
- }
- }
-
- Behavior on color {
- ColorAnimation {
- duration: Theme.shortDuration
- easing.type: Theme.standardEasing
- }
- }
- }
- }
-
- MouseArea {
- id: tabMouseArea
- anchors.fill: parent
- hoverEnabled: true
- preventStealing: dragging || longPressing
- cursorShape: dragging || longPressing ? Qt.ClosedHandCursor : Qt.PointingHandCursor
- acceptedButtons: Qt.LeftButton
-
- onPressed: mouse => {
- if (mouse.button === Qt.LeftButton && NotepadStorageService.tabs.length > 1) {
- delegateItem.dragStartPos = Qt.point(mouse.x, mouse.y)
- longPressTimer.start()
- }
- }
-
- onReleased: mouse => {
- longPressTimer.stop()
- var wasDragging = delegateItem.dragging
- var didReorder = wasDragging && delegateItem.targetIndex >= 0 && delegateItem.targetIndex !== delegateItem.originalIndex
-
- if (didReorder) {
- root.suppressShiftAnimation = true
- NotepadStorageService.reorderTab(delegateItem.originalIndex, delegateItem.targetIndex)
- }
-
- delegateItem.longPressing = false
- delegateItem.dragging = false
- delegateItem.dragAxisOffset = 0
- delegateItem.targetIndex = -1
- delegateItem.originalIndex = -1
- root.draggedIndex = -1
- root.dropTargetIndex = -1
- if (didReorder) {
- Qt.callLater(() => {
- root.suppressShiftAnimation = false
- })
- }
-
- if (wasDragging || mouse.button !== Qt.LeftButton)
- return
- root.tabSwitched(index)
- }
-
- onPositionChanged: mouse => {
- if (delegateItem.longPressing && !delegateItem.dragging) {
- var distance = Math.sqrt(Math.pow(mouse.x - delegateItem.dragStartPos.x, 2) + Math.pow(mouse.y - delegateItem.dragStartPos.y, 2))
- if (distance > 5) {
- delegateItem.dragging = true
- delegateItem.targetIndex = index
- delegateItem.originalIndex = index
- root.draggedIndex = index
- root.dropTargetIndex = index
- }
- }
-
- if (!delegateItem.dragging)
- return
-
- var axisOffset = mouse.x - delegateItem.dragStartPos.x
- delegateItem.dragAxisOffset = axisOffset
-
- var itemSize = root.tabItemSize
- var rawSlot = axisOffset / itemSize
- var slotOffset = rawSlot >= 0
- ? Math.floor(rawSlot + 0.4)
- : Math.ceil(rawSlot - 0.4)
- var tabCount = NotepadStorageService.tabs.length
- var newTargetIndex = Math.max(0, Math.min(tabCount - 1, delegateItem.originalIndex + slotOffset))
-
- if (newTargetIndex !== delegateItem.targetIndex) {
- delegateItem.targetIndex = newTargetIndex
- root.dropTargetIndex = newTargetIndex
- }
- }
- }
- }
- }
- }
- }
-
- DankActionButton {
- id: newTabButton
- width: 32
- height: 32
- iconName: "add"
- iconSize: Theme.iconSize - 4
- iconColor: Theme.surfaceText
- onClicked: root.newTabRequested()
- }
- }
-}
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/Notepad/NotepadTextEditor.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/Notepad/NotepadTextEditor.qml
deleted file mode 100644
index 7ea0b27..0000000
--- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/Notepad/NotepadTextEditor.qml
+++ /dev/null
@@ -1,924 +0,0 @@
-import QtQuick
-import QtQuick.Controls
-import QtQuick.Layouts
-import Quickshell.Io
-import qs.Common
-import qs.Services
-import qs.Widgets
-
-pragma ComponentBehavior: Bound
-
-Column {
- id: root
-
- Component.onCompleted: {
- if (PluginService.isPluginLoaded("dankNotepadModule")) {
- pluginHighlightedHtml = SettingsData.getBuiltInPluginSetting("dankNotepadModule", "highlightedHtml", "")
- }
- }
-
- property alias text: textArea.text
- property alias textArea: textArea
- property bool contentLoaded: false
- property string lastSavedContent: ""
- property var currentTab: NotepadStorageService.tabs.length > NotepadStorageService.currentTabIndex ? NotepadStorageService.tabs[NotepadStorageService.currentTabIndex] : null
- property bool searchVisible: false
- property string searchQuery: ""
- property var searchMatches: []
- property int currentMatchIndex: -1
- property int matchCount: 0
- property bool inlinePreviewVisible: false
- property string previewMode: "split" // split | full
- property string pluginHighlightedHtml: ""
- property string lastPluginContent: ""
- property int loadRequestId: 0
-
- signal saveRequested()
- signal openRequested()
- signal newRequested()
- signal previewRequested()
- signal escapePressed()
- signal contentChanged()
- signal settingsRequested()
-
- function hasUnsavedChanges() {
- if (!currentTab || !contentLoaded) {
- return false
- }
-
- if (currentTab.isTemporary) {
- return textArea.text.length > 0
- }
- return textArea.text !== lastSavedContent
- }
-
- function loadCurrentTabContent() {
- if (!currentTab) return
-
- const requestedTabId = currentTab.id
- const requestId = ++loadRequestId
- contentLoaded = false
- NotepadStorageService.loadTabContent(
- NotepadStorageService.currentTabIndex,
- (content) => {
- const activeTab = NotepadStorageService.tabs.length > NotepadStorageService.currentTabIndex
- ? NotepadStorageService.tabs[NotepadStorageService.currentTabIndex]
- : null
- if (requestId !== loadRequestId || !activeTab || activeTab.id !== requestedTabId)
- return
-
- lastSavedContent = content
- textArea.text = content
- contentLoaded = true
- syncContentToPlugin()
- }
- )
- }
-
- function saveCurrentTabContent() {
- if (!currentTab || !contentLoaded) return
-
- NotepadStorageService.saveTabContent(
- NotepadStorageService.currentTabIndex,
- textArea.text
- )
- lastSavedContent = textArea.text
- }
-
- function autoSaveToSession() {
- if (!currentTab || !contentLoaded) return
- saveCurrentTabContent()
- }
-
- function setTextDocumentLineHeight() {
- return
- }
-
- property string lastTextForLineModel: ""
- property var lineModel: []
-
- function updateLineModel() {
- if (!SettingsData.notepadShowLineNumbers) {
- lineModel = []
- lastTextForLineModel = ""
- return
- }
-
- if (textArea.text !== lastTextForLineModel || lineModel.length === 0) {
- lastTextForLineModel = textArea.text
- lineModel = textArea.text.split('\n')
- }
- }
-
- function performSearch() {
- let matches = []
- currentMatchIndex = -1
-
- if (!searchQuery || searchQuery.length === 0) {
- searchMatches = []
- matchCount = 0
- textArea.select(0, 0)
- return
- }
-
- const text = textArea.text
- const query = searchQuery.toLowerCase()
- let index = 0
-
- while (index < text.length) {
- const foundIndex = text.toLowerCase().indexOf(query, index)
- if (foundIndex === -1) break
-
- matches.push({
- start: foundIndex,
- end: foundIndex + searchQuery.length
- })
- index = foundIndex + 1
- }
-
- searchMatches = matches
- matchCount = matches.length
-
- if (matchCount > 0) {
- currentMatchIndex = 0
- highlightCurrentMatch()
- } else {
- textArea.select(0, 0)
- }
- }
-
- function highlightCurrentMatch() {
- if (currentMatchIndex >= 0 && currentMatchIndex < searchMatches.length) {
- const match = searchMatches[currentMatchIndex]
-
- textArea.cursorPosition = match.start
- textArea.moveCursorSelection(match.end, TextEdit.SelectCharacters)
-
- const flickable = textArea.parent
- if (flickable && flickable.contentY !== undefined) {
- const lineHeight = textArea.font.pixelSize * 1.5
- const approxLine = textArea.text.substring(0, match.start).split('\n').length
- const targetY = approxLine * lineHeight - flickable.height / 2
- flickable.contentY = Math.max(0, Math.min(targetY, flickable.contentHeight - flickable.height))
- }
- }
- }
-
- function findNext() {
- if (matchCount === 0 || searchMatches.length === 0) return
-
- currentMatchIndex = (currentMatchIndex + 1) % matchCount
- highlightCurrentMatch()
- }
-
- function findPrevious() {
- if (matchCount === 0 || searchMatches.length === 0) return
-
- currentMatchIndex = currentMatchIndex <= 0 ? matchCount - 1 : currentMatchIndex - 1
- highlightCurrentMatch()
- }
-
- function showSearch() {
- searchVisible = true
- Qt.callLater(() => {
- searchField.forceActiveFocus()
- })
- }
-
- function togglePreview() {
- if (!inlinePreviewVisible) {
- inlinePreviewVisible = true
- previewMode = "split"
- } else if (previewMode === "split") {
- previewMode = "full"
- } else {
- inlinePreviewVisible = false
- previewMode = "split"
- }
- syncContentToPlugin()
- }
-
- function renderPreviewHtml() {
- if (!inlinePreviewVisible) return ""
- return pluginHighlightedHtml.length > 0 ? pluginHighlightedHtml : "<p><i>Rendering preview…</i></p>"
- }
-
- function syncContentToPlugin() {
- if (!PluginService.isPluginLoaded("dankNotepadModule"))
- return
-
- if (!currentTab)
- return
-
- const filePath = currentTab?.filePath || ""
- const ext = filePath.split('.').pop().toLowerCase()
- const content = textArea.text
-
- if (content === lastPluginContent && SettingsData.getBuiltInPluginSetting("dankNotepadModule", "previewActive", false) === inlinePreviewVisible) {
- return
- }
-
- lastPluginContent = content
- SettingsData.setBuiltInPluginSetting("dankNotepadModule", "previewActive", inlinePreviewVisible)
- SettingsData.setBuiltInPluginSetting("dankNotepadModule", "currentFilePath", filePath)
- SettingsData.setBuiltInPluginSetting("dankNotepadModule", "currentFileExtension", ext)
- SettingsData.setBuiltInPluginSetting("dankNotepadModule", "sourceContent", content)
- SettingsData.setBuiltInPluginSetting("dankNotepadModule", "updatedAt", Date.now())
- }
-
- function hideSearch() {
- searchVisible = false
- searchQuery = ""
- searchMatches = []
- matchCount = 0
- currentMatchIndex = -1
- textArea.select(0, 0)
- textArea.forceActiveFocus()
- }
-
- function copyPlainTextToClipboard() {
- if (!inlinePreviewVisible || !textArea.text) return
-
- const content = textArea.text
- if (content.length > 0) {
- const proc = Qt.createQmlObject(`
- import QtQuick
- import Quickshell.Io
- Process {
- property string content: ""
- command: ["sh", "-c", "printf '%s' \\"$CONTENT\\" | dms clipboard copy"]
- environment: { "CONTENT": content }
- running: false
- }`,
- root,
- "copyProc"
- )
- proc.content = content
- proc.running = true
- proc.exited.connect(() => {
- ToastService.showInfo(I18n.tr("Copied to clipboard"))
- proc.destroy()
- })
- }
- }
-
- function copyHtmlToClipboard() {
- if (!inlinePreviewVisible || !pluginHighlightedHtml) return
-
- if (pluginHighlightedHtml.length > 0) {
- const proc = Qt.createQmlObject(`
- import QtQuick
- import Quickshell.Io
- Process {
- property string content: ""
- command: ["sh", "-c", "printf '%s' \\"$CONTENT\\" | dms clipboard copy"]
- environment: { "CONTENT": content }
- running: false
- }`,
- root,
- "copyProcHtml"
- )
- proc.content = pluginHighlightedHtml
- proc.running = true
- proc.exited.connect(() => {
- ToastService.showInfo(I18n.tr("HTML copied to clipboard"))
- proc.destroy()
- })
- }
- }
-
- spacing: Theme.spacingM
-
- StyledRect {
- id: searchBar
- width: parent.width
- height: 48
- visible: searchVisible
- opacity: searchVisible ? 1 : 0
- color: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency)
- border.color: searchField.activeFocus ? Theme.primary : Theme.outlineMedium
- border.width: searchField.activeFocus ? 2 : 1
- radius: Theme.cornerRadius
-
- Behavior on opacity {
- NumberAnimation {
- duration: Theme.shortDuration
- easing.type: Theme.standardEasing
- }
- }
-
- RowLayout {
- anchors.fill: parent
- anchors.leftMargin: Theme.spacingM
- anchors.rightMargin: Theme.spacingM
- spacing: Theme.spacingS
-
- // Search icon
- DankIcon {
- Layout.alignment: Qt.AlignVCenter
- name: "search"
- size: Theme.iconSize - 2
- color: searchField.activeFocus ? Theme.primary : Theme.surfaceVariantText
- }
-
- // Search input field
- TextInput {
- id: searchField
- Layout.fillWidth: true
- Layout.alignment: Qt.AlignVCenter
- height: 32
- font.pixelSize: Theme.fontSizeMedium
- color: Theme.surfaceText
- verticalAlignment: TextInput.AlignVCenter
- selectByMouse: true
- clip: true
-
- Component.onCompleted: {
- text = root.searchQuery
- }
-
- Connections {
- target: root
- function onSearchQueryChanged() {
- if (searchField.text !== root.searchQuery) {
- searchField.text = root.searchQuery
- }
- }
- }
-
- onTextChanged: {
- if (root.searchQuery !== text) {
- root.searchQuery = text
- root.performSearch()
- }
- }
- Keys.onEscapePressed: event => {
- root.hideSearch()
- event.accepted = true
- }
- Keys.onReturnPressed: event => {
- if (event.modifiers & Qt.ShiftModifier) {
- root.findPrevious()
- } else {
- root.findNext()
- }
- event.accepted = true
- }
- Keys.onEnterPressed: event => {
- if (event.modifiers & Qt.ShiftModifier) {
- root.findPrevious()
- } else {
- root.findNext()
- }
- event.accepted = true
- }
- }
-
- // Placeholder text
- StyledText {
- Layout.fillWidth: true
- Layout.alignment: Qt.AlignVCenter
- text: I18n.tr("Find in note...")
- font: searchField.font
- color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.5)
- visible: searchField.text.length === 0 && !searchField.activeFocus
- Layout.leftMargin: -(searchField.width - 20) // Position over the input field
- }
-
- // Match count display
- StyledText {
- Layout.alignment: Qt.AlignVCenter
- text: matchCount > 0 ? "%1/%2".arg(currentMatchIndex + 1).arg(matchCount) : searchQuery.length > 0 ? I18n.tr("No matches") : ""
- font.pixelSize: Theme.fontSizeSmall
- color: matchCount > 0 ? Theme.primary : Theme.surfaceTextMedium
- visible: searchQuery.length > 0
- Layout.rightMargin: Theme.spacingS
- }
-
- // Navigation buttons
- DankActionButton {
- id: prevButton
- Layout.alignment: Qt.AlignVCenter
- iconName: "keyboard_arrow_up"
- iconSize: Theme.iconSize
- iconColor: matchCount > 0 ? Theme.surfaceText : Theme.surfaceTextAlpha
- enabled: matchCount > 0
- onClicked: root.findPrevious()
- }
-
- DankActionButton {
- id: nextButton
- Layout.alignment: Qt.AlignVCenter
- iconName: "keyboard_arrow_down"
- iconSize: Theme.iconSize
- iconColor: matchCount > 0 ? Theme.surfaceText : Theme.surfaceTextAlpha
- enabled: matchCount > 0
- onClicked: root.findNext()
- }
-
- DankActionButton {
- id: closeSearchButton
- Layout.alignment: Qt.AlignVCenter
- iconName: "close"
- iconSize: Theme.iconSize - 2
- iconColor: Theme.surfaceText
- onClicked: root.hideSearch()
- }
- }
- }
-
- StyledRect {
- width: parent.width
- height: parent.height - bottomControls.height - Theme.spacingM - (searchVisible ? searchBar.height + Theme.spacingM : 0)
- color: Qt.rgba(Theme.surface.r, Theme.surface.g, Theme.surface.b, Theme.notepadTransparency)
- border.color: Theme.outlineMedium
- border.width: 1
- radius: Theme.cornerRadius
-
- RowLayout {
- id: editorPreviewRow
- anchors.fill: parent
- anchors.margins: 1
- spacing: Theme.spacingM
-
- Item {
- id: editorPane
- visible: !inlinePreviewVisible || previewMode === "split"
- Layout.fillHeight: true
- Layout.fillWidth: !inlinePreviewVisible || previewMode === "split"
- Layout.preferredWidth: inlinePreviewVisible ? parent.width * 0.55 : parent.width
- clip: true
-
- DankFlickable {
- id: flickable
- anchors.fill: parent
- clip: true
- contentWidth: width - 11
-
- Rectangle {
- id: lineNumberArea
- anchors.left: parent.left
- anchors.top: parent.top
- width: SettingsData.notepadShowLineNumbers ? Math.max(30, 32 + Theme.spacingXS) : 0
- height: textArea.contentHeight + textArea.topPadding + textArea.bottomPadding
- color: "transparent"
- visible: SettingsData.notepadShowLineNumbers
-
- ListView {
- id: lineNumberList
- anchors.top: parent.top
- anchors.topMargin: textArea.topPadding
- anchors.right: parent.right
- anchors.rightMargin: 2
- width: 32
- height: textArea.contentHeight
- model: SettingsData.notepadShowLineNumbers ? root.lineModel : []
- interactive: false
- spacing: 0
-
- delegate: Item {
- id: lineDelegate
- required property int index
- required property string modelData
- width: 32
- height: measuringText.contentHeight
-
- Text {
- id: measuringText
- width: textArea.width - textArea.leftPadding - textArea.rightPadding
- text: modelData || " "
- font: textArea.font
- wrapMode: Text.Wrap
- visible: false
- }
-
- StyledText {
- anchors.right: parent.right
- anchors.rightMargin: 4
- anchors.top: parent.top
- text: index + 1
- font.family: textArea.font.family
- font.pixelSize: textArea.font.pixelSize
- color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.4)
- horizontalAlignment: Text.AlignRight
- }
- }
- }
- }
-
- TextArea.flickable: TextArea {
- id: textArea
- placeholderText: ""
- placeholderTextColor: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.5)
- font.family: SettingsData.notepadUseMonospace ? SettingsData.monoFontFamily : (SettingsData.notepadFontFamily || SettingsData.fontFamily)
- font.pixelSize: SettingsData.notepadFontSize * SettingsData.fontScale
- font.letterSpacing: 0
- color: Theme.surfaceText
- selectedTextColor: Theme.background
- selectionColor: Theme.primary
- selectByMouse: true
- selectByKeyboard: true
- wrapMode: TextArea.Wrap
- focus: true
- activeFocusOnTab: true
- textFormat: TextEdit.PlainText
- inputMethodHints: Qt.ImhNoPredictiveText | Qt.ImhNoAutoUppercase
- persistentSelection: true
- tabStopDistance: 40
- leftPadding: (SettingsData.notepadShowLineNumbers ? lineNumberArea.width + Theme.spacingXS : Theme.spacingM)
- topPadding: Theme.spacingM
- rightPadding: Theme.spacingM
- bottomPadding: Theme.spacingM
- cursorDelegate: Rectangle {
- width: 1.5
- radius: 1
- color: Theme.surfaceText
- x: textArea.cursorRectangle.x
- y: textArea.cursorRectangle.y
- height: textArea.cursorRectangle.height
- opacity: 1.0
-
- SequentialAnimation on opacity {
- running: textArea.activeFocus
- loops: Animation.Infinite
- PropertyAnimation { from: 1.0; to: 0.0; duration: 650; easing.type: Easing.InOutQuad }
- PropertyAnimation { from: 0.0; to: 1.0; duration: 650; easing.type: Easing.InOutQuad }
- }
- }
-
- Component.onCompleted: {
- loadCurrentTabContent()
- setTextDocumentLineHeight()
- root.updateLineModel()
- Qt.callLater(() => {
- textArea.forceActiveFocus()
- })
- }
-
- Connections {
- target: NotepadStorageService
- function onCurrentTabIndexChanged() {
- loadCurrentTabContent()
- Qt.callLater(() => {
- textArea.forceActiveFocus()
- })
- }
- function onTabsChanged() {
- if (NotepadStorageService.tabs.length > 0 && !contentLoaded) {
- loadCurrentTabContent()
- }
- }
- }
-
- Connections {
- target: SettingsData
- function onNotepadShowLineNumbersChanged() {
- root.updateLineModel()
- }
- }
-
- onTextChanged: {
- if (contentLoaded && text !== lastSavedContent) {
- autoSaveTimer.restart()
- }
- root.contentChanged()
- root.updateLineModel()
- pluginSyncTimer.restart()
- }
-
- Keys.onEscapePressed: (event) => {
- root.escapePressed()
- event.accepted = true
- }
-
- Keys.onPressed: (event) => {
- if (event.modifiers & Qt.ControlModifier) {
- switch (event.key) {
- case Qt.Key_S:
- event.accepted = true
- root.saveRequested()
- break
- case Qt.Key_O:
- event.accepted = true
- root.openRequested()
- break
- case Qt.Key_N:
- event.accepted = true
- root.newRequested()
- break
- case Qt.Key_A:
- event.accepted = true
- textArea.selectAll()
- break
- case Qt.Key_F:
- event.accepted = true
- root.showSearch()
- break
- case Qt.Key_P:
- if (PluginService.isPluginLoaded("dankNotepadModule")) {
- event.accepted = true
- root.previewRequested()
- }
- break
- }
- }
- }
-
- background: Rectangle {
- color: "transparent"
- }
- }
-
- StyledText {
- id: placeholderOverlay
- text: I18n.tr("Start typing your notes here...")
- color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.5)
- font.family: textArea.font.family
- font.pixelSize: textArea.font.pixelSize
- visible: textArea.text.length === 0
- anchors.left: textArea.left
- anchors.top: textArea.top
- anchors.leftMargin: textArea.leftPadding
- anchors.topMargin: textArea.topPadding
- z: textArea.z + 1
- }
- }
- }
-
- Rectangle {
- id: previewDivider
- visible: inlinePreviewVisible && previewMode === "split"
- Layout.fillHeight: true
- Layout.preferredWidth: 1
- color: Theme.outlineMedium
- }
-
- Item {
- id: previewPane
- visible: inlinePreviewVisible
- Layout.fillHeight: true
- Layout.fillWidth: previewMode === "full"
- Layout.preferredWidth: previewMode === "full" ? parent.width : parent.width * 0.45
- clip: true
-
- // Preview header with copy buttons
- Rectangle {
- id: previewHeader
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
- height: 36
- color: Qt.rgba(Theme.surface.r, Theme.surface.g, Theme.surface.b, Theme.notepadTransparency)
- z: 2
-
- Row {
- anchors.right: parent.right
- anchors.verticalCenter: parent.verticalCenter
- anchors.rightMargin: Theme.spacingM
- spacing: Theme.spacingS
-
- // Copy plain text button
- DankActionButton {
- iconName: "content_copy"
- iconSize: Theme.iconSize - 4
- iconColor: Theme.surfaceTextMedium
- onClicked: copyPlainTextToClipboard()
- }
-
- StyledText {
- anchors.verticalCenter: parent.verticalCenter
- text: I18n.tr("Copy Text")
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceTextMedium
- }
-
- Rectangle {
- width: 1
- height: 20
- color: Theme.outlineVariant
- anchors.verticalCenter: parent.verticalCenter
- }
-
- // Copy HTML button
- DankActionButton {
- iconName: "code"
- iconSize: Theme.iconSize - 4
- iconColor: Theme.surfaceTextMedium
- onClicked: copyHtmlToClipboard()
- }
-
- StyledText {
- anchors.verticalCenter: parent.verticalCenter
- text: I18n.tr("Copy HTML")
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceTextMedium
- }
- }
- }
-
- DankFlickable {
- id: previewFlickable
- anchors.top: previewHeader.bottom
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.bottom: parent.bottom
- anchors.topMargin: Theme.spacingS
- clip: true
- contentWidth: width - 11
- contentHeight: previewText.paintedHeight + Theme.spacingM * 2
-
- Text {
- id: previewText
- width: parent.width - Theme.spacingM
- padding: Theme.spacingM
- wrapMode: Text.WordWrap
- textFormat: Text.RichText
- text: inlinePreviewVisible ? renderPreviewHtml() : ""
- color: Theme.surfaceText
- font.family: SettingsData.notepadFontFamily || SettingsData.fontFamily
- font.pixelSize: Theme.fontSizeMedium
- linkColor: Theme.primary
-
- onLinkActivated: url => Qt.openUrlExternally(url)
- }
- }
- }
- }
- }
-
- Column {
- id: bottomControls
- width: parent.width
- spacing: Theme.spacingS
-
- Item {
- width: parent.width
- height: 32
-
- Row {
- anchors.left: parent.left
- anchors.verticalCenter: parent.verticalCenter
- spacing: Theme.spacingL
-
- Row {
- spacing: Theme.spacingS
- DankActionButton {
- iconName: "save"
- iconSize: Theme.iconSize - 2
- iconColor: Theme.primary
- enabled: currentTab && (hasUnsavedChanges() || textArea.text.length > 0)
- onClicked: root.saveRequested()
- }
- StyledText {
- anchors.verticalCenter: parent.verticalCenter
- text: I18n.tr("Save")
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceTextMedium
- }
- }
-
- Row {
- spacing: Theme.spacingS
- DankActionButton {
- iconName: "folder_open"
- iconSize: Theme.iconSize - 2
- iconColor: Theme.secondary
- onClicked: root.openRequested()
- }
- StyledText {
- anchors.verticalCenter: parent.verticalCenter
- text: I18n.tr("Open")
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceTextMedium
- }
- }
-
- Row {
- spacing: Theme.spacingS
- DankActionButton {
- iconName: "note_add"
- iconSize: Theme.iconSize - 2
- iconColor: Theme.surfaceText
- onClicked: root.newRequested()
- }
- StyledText {
- anchors.verticalCenter: parent.verticalCenter
- text: I18n.tr("New")
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceTextMedium
- }
- }
-
- Row {
- spacing: Theme.spacingS
- visible: PluginService.isPluginLoaded("dankNotepadModule")
- DankActionButton {
- iconName: inlinePreviewVisible ? "visibility" : "visibility_off"
- iconSize: Theme.iconSize - 2
- iconColor: Theme.surfaceText
- enabled: textArea.text.length > 0
- onClicked: root.previewRequested()
- }
- StyledText {
- anchors.verticalCenter: parent.verticalCenter
- text: I18n.tr("Preview")
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceTextMedium
- }
- }
- }
-
- DankActionButton {
- anchors.right: parent.right
- anchors.verticalCenter: parent.verticalCenter
- iconName: "more_horiz"
- iconSize: Theme.iconSize - 2
- iconColor: Theme.surfaceText
- onClicked: root.settingsRequested()
- }
- }
-
- Row {
- width: parent.width
- spacing: Theme.spacingL
-
- StyledText {
- text: {
- const len = textArea.text.length;
- if (len === 0) return I18n.tr("Empty");
- return len === 1
- ? I18n.tr("%1 character").arg(len)
- : I18n.tr("%1 characters").arg(len);
- }
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceTextMedium
- }
-
- StyledText {
- text: textArea.lineCount === 1
- ? I18n.tr("Line: %1").arg(textArea.lineCount)
- : I18n.tr("Lines: %1").arg(textArea.lineCount)
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.surfaceTextMedium
- visible: textArea.text.length > 0
- opacity: 1.0
- }
-
- StyledText {
- text: {
- if (autoSaveTimer.running) {
- return I18n.tr("Auto-saving...")
- }
-
- if (hasUnsavedChanges()) {
- if (currentTab && currentTab.isTemporary) {
- return I18n.tr("Unsaved note...")
- } else {
- return I18n.tr("Unsaved changes")
- }
- } else {
- return I18n.tr("Saved")
- }
- }
- font.pixelSize: Theme.fontSizeSmall
- color: {
- if (autoSaveTimer.running) {
- return Theme.primary
- }
-
- if (hasUnsavedChanges()) {
- return Theme.warning
- } else {
- return Theme.success
- }
- }
- opacity: textArea.text.length > 0 ? 1.0 : 0.0
- }
- }
- }
-
- Timer {
- id: autoSaveTimer
- interval: 2000
- repeat: false
- onTriggered: {
- autoSaveToSession()
- }
- }
-
- Timer {
- id: pluginSyncTimer
- interval: 350
- repeat: false
- onTriggered: syncContentToPlugin()
- }
-
- Connections {
- target: SettingsData
- function onBuiltInPluginSettingsChanged() {
- if (PluginService.isPluginLoaded("dankNotepadModule")) {
- pluginHighlightedHtml = SettingsData.getBuiltInPluginSetting("dankNotepadModule", "highlightedHtml", "")
- }
- }
- }
-}