From 873a28e1eb2bc0c7d364316cae5af574cd837729 Mon Sep 17 00:00:00 2001
From: Mario Abbate <89916197+mario-dedalus@users.noreply.github.com>
Date: Fri, 24 Apr 2026 11:06:06 +0200
Subject: [PATCH 1/4] Added a few modifications to this great script
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
I made a few modifications, maybe you like it? ๐
---
...nology management__tb_term_selector.py.txt | 9 +
FileExplorerNotes.ahk | 582 +++++++++++++++---
config.ini | Bin 0 -> 298 bytes
desktop.ini | Bin 0 -> 182 bytes
4 files changed, 513 insertions(+), 78 deletions(-)
create mode 100644 .filenotes/C__Users__aqbge__OneDrive - Dedalus S.p.A__Desktop__Wichtige Dateien__Skripte__Terminology management__tb_term_selector.py.txt
create mode 100644 config.ini
create mode 100644 desktop.ini
diff --git a/.filenotes/C__Users__aqbge__OneDrive - Dedalus S.p.A__Desktop__Wichtige Dateien__Skripte__Terminology management__tb_term_selector.py.txt b/.filenotes/C__Users__aqbge__OneDrive - Dedalus S.p.A__Desktop__Wichtige Dateien__Skripte__Terminology management__tb_term_selector.py.txt
new file mode 100644
index 0000000..114bcf6
--- /dev/null
+++ b/.filenotes/C__Users__aqbge__OneDrive - Dedalus S.p.A__Desktop__Wichtige Dateien__Skripte__Terminology management__tb_term_selector.py.txt
@@ -0,0 +1,9 @@
+Hallo,
+
+das ist ein Test.
+
+
+Du Mandala.
+
+
+Halidro!
\ No newline at end of file
diff --git a/FileExplorerNotes.ahk b/FileExplorerNotes.ahk
index d096e64..62b68bf 100644
--- a/FileExplorerNotes.ahk
+++ b/FileExplorerNotes.ahk
@@ -1,22 +1,34 @@
; ============================================================================
-; PROJECT : FileExplorerNotes v2.0
-; AUTHOR : Gued3s
+; PROJECT : FileExplorerNotes v3.0 (Enhanced)
+; BASED ON : FileExplorerNotes v2.0 by Gued3s
; DESCRIPTION : "Commit messages" for your local files. Context-aware
; description system for Windows Explorer.
-; ARCHITECTURE: AHK v2 Native GUI, Map-based Window Manager, Atomic I/O,
-; Win11 Tabs COM Resilience, O(1) FIFO Cache.
+; Enhancements: centralized notes storage,
+; configurable hotkeys via UI + tray menu.
; LICENSE : MIT
; ============================================================================
#Requires AutoHotkey v2.0
#SingleInstance Force
+TraySetIcon("C:\WINDOWS\system32\shell32.dll", 71)
; ============================================================================
; 1. GLOBAL CONFIGURATION
-; - Defines visual themes (Dark Mode) and cache limits.
-; - Initializes the window registry to prevent duplicates.
; ============================================================================
+; Paths
+global SCRIPT_DIR := A_ScriptDir
+global CONFIG_PATH := SCRIPT_DIR "\config.ini"
+global NOTES_DIR := SCRIPT_DIR "\.filenotes"
+
+; Ensure centralized notes folder exists (hidden)
+if !DirExist(NOTES_DIR) {
+ try {
+ DirCreate(NOTES_DIR)
+ FileSetAttrib("+H", NOTES_DIR)
+ }
+}
+
; Dark Mode Colors (Win11 Native)
global COLOR_BG := "1E1E1E"
global COLOR_EDIT := "2D2D2D"
@@ -33,39 +45,340 @@ global CACHE_MAX_AGE := 30000
; GUI Windows Registry (prevent duplicates, memory leaks)
global OpenGuis := Map()
+; --- Hotkey Configuration ---
+global HK_CREATE := LoadConfig("Hotkeys", "CreateNote", "^+d")
+global HK_PREVIEW := LoadConfig("Hotkeys", "Preview", "^q")
+global HK_SETTINGS := LoadConfig("Hotkeys", "Settings", "^+F12")
+
+; --- Auto-Preview Configuration ---
+global AUTO_PREVIEW_ENABLED := LoadConfig("AutoPreview", "Enabled", "1")
+global AUTO_PREVIEW_DURATION := LoadConfig("AutoPreview", "Duration", "3000")
+
+; --- Tooltip Style: "styled" or "default" ---
+global STYLE_AUTO := LoadConfig("Style", "AutoPreview", "styled")
+global STYLE_MANUAL := LoadConfig("Style", "ManualPreview", "styled")
+
+LoadConfig(section, key, defaultVal) {
+ try {
+ val := IniRead(CONFIG_PATH, section, key)
+ if (val != "" && val != "ERROR")
+ return val
+ }
+ ; Write default if missing
+ try IniWrite(defaultVal, CONFIG_PATH, section, key)
+ return defaultVal
+}
+
+SaveConfig(section, key, val) {
+ try IniWrite(val, CONFIG_PATH, section, key)
+}
+
; Apply Dark Mode Globally
if (VerCompare(A_OSVersion, "10.0.18362") >= 0) {
try DllCall("uxtheme\135", "int", 2)
}
+; Custom styled tooltip GUI
+global StyledTip := 0
+
OnExit(ExitHandler)
ExitHandler(*) {
ToolTip()
- ; Clean up any remaining GUI windows
+ HideStyledTip()
for filePath, guiObj in OpenGuis {
try guiObj.Destroy()
}
}
; ============================================================================
-; 2. EXPLORER HOTKEYS (Context-Aware)
-; - Restricts shortcuts to Windows Explorer windows only.
-; - Prevents interference with other applications.
+; 2. EXPLORER HOTKEYS (Context-Aware, Configurable)
; ============================================================================
-#HotIf WinActive("ahk_class CabinetWClass ahk_exe explorer.exe")
+RegisterHotkeys() {
+ try {
+ HotIfWinActive("ahk_class CabinetWClass ahk_exe explorer.exe")
+ Hotkey(HK_CREATE, (*) => CreateNote())
+ Hotkey(HK_PREVIEW, (*) => PreviewStart())
+ Hotkey(HK_PREVIEW " Up", (*) => PreviewStop())
+ HotIf()
+ } catch as err {
+ MsgBox("Failed to register Explorer hotkeys. Check config.ini for invalid values.`n`n" err.Message, "Hotkey Error", "Icon!")
+ }
+ ; Settings hotkey (always active)
+ try Hotkey(HK_SETTINGS, (*) => OpenSettingsGUI())
+ catch as err
+ MsgBox("Failed to register Settings hotkey. Check config.ini.`n`n" err.Message, "Hotkey Error", "Icon!")
+}
+RegisterHotkeys()
+
+; --- Tray Menu ---
+A_TrayMenu.Delete() ; Clear default menu
+A_TrayMenu.Add("Settings", (*) => OpenSettingsGUI())
+A_TrayMenu.Add("Open Notes Folder", (*) => Run(NOTES_DIR))
+A_TrayMenu.Add("Edit Script", (*) => Edit())
+A_TrayMenu.Add() ; Separator
+A_TrayMenu.Add("Reload Script", (*) => Reload())
+A_TrayMenu.Add("Exit", (*) => ExitApp())
+A_TrayMenu.Default := "Settings"
+
+; ============================================================================
+; 2a. AUTO-PREVIEW SYSTEM
+; Polls the focused file in Explorer and shows a styled tooltip
+; automatically when a note exists. No hotkey needed.
+; ============================================================================
+
+global AutoPreviewState := Map("LastPath", "", "Active", false)
+
+StartAutoPreview() {
+ global AutoPreviewState
+ if (AUTO_PREVIEW_ENABLED != "1") {
+ NoteCache.Clear()
+ return
+ }
+ AutoPreviewState["Active"] := true
+ SetTimer(AutoPreviewTick, 300)
+}
+
+StopAutoPreview() {
+ global AutoPreviewState
+ AutoPreviewState["Active"] := false
+ AutoPreviewState["LastPath"] := ""
+ SetTimer(AutoPreviewTick, 0)
+ NoteCache.Clear()
+}
+
+AutoPreviewTick() {
+ global AutoPreviewState, NoteCache
+
+ static _busy := false
+ if _busy
+ return
+ _busy := true
+
+ try {
+ if !WinActive("ahk_class CabinetWClass ahk_exe explorer.exe") {
+ if AutoPreviewState["LastPath"] != "" {
+ AutoPreviewState["LastPath"] := ""
+ HideStyledTip()
+ ToolTip()
+ }
+ return
+ }
+
+ shellWin := GetExplorerWindow()
+ if !shellWin
+ return
+
+ focusedPath := ""
+ try {
+ focusedItem := shellWin.Document.FocusedItem
+ if focusedItem
+ focusedPath := focusedItem.Path
+ }
+
+ if !focusedPath || InStr(focusedPath, "\.filenotes\") {
+ if AutoPreviewState["LastPath"] != "" {
+ AutoPreviewState["LastPath"] := ""
+ HideStyledTip()
+ ToolTip()
+ }
+ return
+ }
+
+ notePath := EncodeNotePath(focusedPath)
-^+d:: CreateNote() ; Ctrl+Shift+D : Create/Edit Note
-^q:: PreviewStart() ; Ctrl+Q (Hold) : Preview Note
-^q Up:: PreviewStop() ; Ctrl+Q (Release) : Hide Preview
+ ; Same file as last tick โ skip
+ if notePath = AutoPreviewState["LastPath"]
+ return
+
+ AutoPreviewState["LastPath"] := notePath
+
+ ; Only show for files that HAVE a note
+ if !FileExist(notePath) {
+ HideStyledTip()
+ ToolTip()
+ return
+ }
-#HotIf
+ ; Read content (use cache)
+ content := ReadNoteContent(notePath)
+ if !content {
+ HideStyledTip()
+ ToolTip()
+ return
+ }
+
+ SplitPath(focusedPath, &fName)
+ if (STYLE_AUTO = "styled")
+ ShowStyledTip("", content, true)
+ else {
+ preview := StrReplace(content, "`n", " ยท ")
+ if StrLen(preview) > 80
+ preview := SubStr(preview, 1, 80) "..."
+ ToolTip("๐ " preview)
+ }
+ ; Auto-hide after configured duration
+ duration := Integer(AUTO_PREVIEW_DURATION)
+ if (STYLE_AUTO = "styled")
+ SetTimer(HideStyledTip, -duration)
+ else
+ SetTimer(ClearDefaultTip, -duration)
+
+ } finally {
+ _busy := false
+ }
+}
+
+; Read note with cache support (shared with manual preview)
+ReadNoteContent(notePath) {
+ global NoteCache
+ currentFileTime := ""
+ try currentFileTime := FileGetTime(notePath, "M")
+
+ if NoteCache.Has(notePath) {
+ cachedData := NoteCache[notePath]
+ if currentFileTime = cachedData.FileTime && (A_TickCount - cachedData.AccessTime) < CACHE_MAX_AGE {
+ cachedData.AccessTime := A_TickCount
+ return cachedData.Content
+ } else {
+ NoteCache.Delete(notePath)
+ }
+ }
+
+ content := ""
+ try {
+ content := FileRead(notePath, "m4000 UTF-8-RAW")
+ if content {
+ NoteCache[notePath] := {
+ Content: content,
+ AccessTime: A_TickCount,
+ FileTime: currentFileTime
+ }
+ if NoteCache.Count > CACHE_MAX_SIZE {
+ for key in NoteCache {
+ NoteCache.Delete(key)
+ break
+ }
+ }
+ }
+ }
+ return content
+}
+
+; Start auto-preview on script load
+StartAutoPreview()
+
+ClearDefaultTip(*) => ToolTip()
+
+; ============================================================================
+; 2a-2. STYLED TOOLTIP (Custom GUI)
+; Dark-themed popup with title + content, rounded appearance.
+; ============================================================================
+
+ShowStyledTip(title, content, compact := false) {
+ global StyledTip
+ HideStyledTip()
+
+ ; Truncate long content for tooltip display
+ if StrLen(content) > 500
+ content := SubStr(content, 1, 500) "..."
+
+ tip := Gui("+AlwaysOnTop -Caption +ToolWindow +E0x20", "StyledTip")
+ tip.BackColor := "2D2D30"
+
+ ; Rounded corners (Win11)
+ try DllCall("dwmapi\DwmSetWindowAttribute", "ptr", tip.Hwnd, "int", 33, "int*", 3, "int", 4)
+ ; Border color
+ try DllCall("dwmapi\DwmSetWindowAttribute", "ptr", tip.Hwnd, "int", 34, "int*", 0x00555555, "int", 4)
+
+ if compact {
+ ; --- Compact mode: subtle single-line indicator ---
+ tip.MarginX := 8
+ tip.MarginY := 4
+ tip.SetFont("s8 cAAAAAA Norm", "Segoe UI")
+ maxLen := 80
+ preview := StrReplace(content, "`n", " ยท ")
+ if StrLen(preview) > maxLen
+ preview := SubStr(preview, 1, maxLen) "..."
+ tip.Add("Text", , "๐ " preview)
+ } else {
+ ; --- Full mode: title + separator + content ---
+ tip.MarginX := 12
+ tip.MarginY := 8
+ if title {
+ tip.SetFont("s10 cE0E0E0 Bold", "Segoe UI")
+ tip.Add("Text", "w350", title)
+ tip.Add("Text", "x12 w350 h1 Background555555")
+ }
+ tip.SetFont("s9 cCCCCCC Norm", "Segoe UI")
+ tip.Add("Text", "x12 w350", content)
+ }
+
+ ; Position near mouse, clamped to screen bounds
+ CoordMode("Mouse", "Screen")
+ MouseGetPos(&mx, &my)
+ tipX := mx + 15
+ tipY := my + 15
+
+ ; Get screen work area dimensions
+ monNum := MonitorGetCount()
+ bestMon := 1
+ Loop monNum {
+ MonitorGet(A_Index, &mL, &mT, &mR, &mB)
+ if (mx >= mL && mx < mR && my >= mT && my < mB) {
+ bestMon := A_Index
+ break
+ }
+ }
+ MonitorGetWorkArea(bestMon, &wL, &wT, &wR, &wB)
+
+ tip.Show("AutoSize NoActivate x" tipX " y" tipY)
+
+ ; After showing, get actual size and clamp
+ try {
+ tip.GetPos(, , &tipW, &tipH)
+ if (tipX + tipW > wR)
+ tipX := wR - tipW
+ if (tipY + tipH > wB)
+ tipY := wB - tipH
+ if (tipX < wL)
+ tipX := wL
+ if (tipY < wT)
+ tipY := wT
+ tip.Move(tipX, tipY)
+ }
+
+ StyledTip := tip
+}
+
+HideStyledTip(*) {
+ global StyledTip
+ if StyledTip {
+ try StyledTip.Destroy()
+ StyledTip := 0
+ }
+}
+
+; ============================================================================
+; 2b. NOTE PATH ENCODING
+; Encodes full file path into a safe filename stored centrally.
+; Format: Drive_Path_To_FileName.ext.txt
+; ============================================================================
+
+EncodeNotePath(filePath) {
+ ; Encode path using double-underscore as separator to avoid collisions
+ ; "C:\Users\foo\bar.txt" -> "C__Users__foo__bar.txt.txt"
+ ; Single underscores in original names are preserved, double-underscore = path separator
+ encoded := StrReplace(filePath, ":\", "__")
+ encoded := StrReplace(encoded, "\", "__")
+ encoded := StrReplace(encoded, "/", "__")
+ encoded := StrReplace(encoded, ":", "__")
+ return NOTES_DIR "\" encoded ".txt"
+}
; ============================================================================
; 3. CORE: CREATE NOTE LOGIC
-; - Identifies selected files and resolves system paths.
-; - Manages the hidden ".filenotes" directory structure.
; ============================================================================
CreateNote() {
@@ -83,28 +396,14 @@ CreateNote() {
}
}
- ; Validation: File must exist and not be a note itself
if !targetPath || !FileExist(targetPath) || InStr(targetPath, "\.filenotes\") {
ToolTip("โ Please select a valid file.")
SetTimer(() => ToolTip(), -1500)
return
}
- ; Extract filename WITH extension (important!)
SplitPath(targetPath, &fileName, &fileDir)
- metaDir := fileDir "\.filenotes"
- notePath := metaDir "\" fileName ".txt"
-
- ; Create .filenotes directory if needed
- if !DirExist(metaDir) {
- try {
- DirCreate(metaDir)
- FileSetAttrib("+H", metaDir)
- } catch as err {
- MsgBox("Cannot create notes directory:`n" err.Message, "Error", "Icon!")
- return
- }
- }
+ notePath := EncodeNotePath(targetPath)
; Open in GUI (prevent duplicate windows)
if OpenGuis.Has(notePath) {
@@ -130,7 +429,7 @@ OpenNoteGUI(notePath, displayName) {
; Load existing content or start empty
initialContent := ""
if FileExist(notePath) {
- try initialContent := FileRead(notePath, "UTF-8")
+ try initialContent := FileRead(notePath, "UTF-8-RAW")
}
; Create window with dark theme support
@@ -160,21 +459,25 @@ OpenNoteGUI(notePath, displayName) {
; --- BUTTONS ---
btnSave := noteGui.Add("Button", "vBtnSave w100 h30 Default", "Save")
+ btnDelete := noteGui.Add("Button", "vBtnDelete x+10 w100 h30", "Delete Note")
btnCancel := noteGui.Add("Button", "vBtnCancel x+10 w100 h30", "Cancel")
; Aplica o tema escuro nativo do Windows 11 (Deixa cinza e arredondado)
try DllCall("uxtheme\SetWindowTheme", "ptr", btnSave.Hwnd, "str", "DarkMode_Explorer", "ptr", 0)
+ try DllCall("uxtheme\SetWindowTheme", "ptr", btnDelete.Hwnd, "str", "DarkMode_Explorer", "ptr", 0)
try DllCall("uxtheme\SetWindowTheme", "ptr", btnCancel.Hwnd, "str", "DarkMode_Explorer", "ptr", 0)
; --- EVENTS ---
btnSave.OnEvent("Click", GuiSave.Bind(noteGui, notePath, editCtrl))
+ btnDelete.OnEvent("Click", GuiDeleteNote.Bind(noteGui, notePath))
btnCancel.OnEvent("Click", GuiClose.Bind(noteGui, notePath, editCtrl))
noteGui.OnEvent("Close", GuiClose.Bind(noteGui, notePath, editCtrl))
noteGui.OnEvent("Size", GuiResize)
- ; --- LOCAL HOTKEY: Ctrl+S ---
+ ; --- LOCAL HOTKEYS ---
HotIfWinActive("ahk_id " noteGui.Hwnd)
Hotkey("^s", GuiSave.Bind(noteGui, notePath, editCtrl))
+ Hotkey("^BS", CtrlBackspace.Bind(editCtrl))
HotIf()
; Track window globally
@@ -205,8 +508,11 @@ GuiResize(GuiObj, MinMax, Width, Height) {
; Save Button: bottom-left area with 15px padding
GuiObj["BtnSave"].Move(15, Height - 45, 100, 30)
- ; Cancel Button: next to Save button with 10px gap
- GuiObj["BtnCancel"].Move(125, Height - 45, 100, 30)
+ ; Delete Button
+ GuiObj["BtnDelete"].Move(125, Height - 45, 100, 30)
+
+ ; Cancel Button
+ GuiObj["BtnCancel"].Move(235, Height - 45, 100, 30)
} catch {
; Graceful failure
}
@@ -218,12 +524,23 @@ GuiSave(noteGui, notePath, editCtrl, *) {
GuiDestroy(noteGui, notePath)
}
+GuiDeleteNote(noteGui, notePath, *) {
+ result := MsgBox("Are you sure you want to delete this note?", "Delete Note", "YesNo Icon?")
+ if result = "Yes" {
+ try FileDelete(notePath)
+ if NoteCache.Has(notePath)
+ NoteCache.Delete(notePath)
+ noteGui.IsDirty := false
+ GuiDestroy(noteGui, notePath)
+ }
+}
+
GuiClose(noteGui, notePath, editCtrl, *) {
; Check for unsaved changes
if noteGui.IsDirty {
result := MsgBox("You have unsaved changes. Save before closing?", "Unsaved Changes", "YesNoCancel Icon?")
if result = "Cancel"
- return ; Corrigido: Em AHK v2, apenas 'return' sem destruir a janela jรก previne o fechamento aqui
+ return
if result = "Yes"
SaveNoteAtomic(notePath, editCtrl.Value)
}
@@ -234,6 +551,7 @@ GuiDestroy(noteGui, notePath) {
try {
HotIfWinActive("ahk_id " noteGui.Hwnd)
Hotkey("^s", "Off")
+ Hotkey("^BS", "Off")
HotIf()
}
@@ -242,6 +560,16 @@ GuiDestroy(noteGui, notePath) {
}
+; ============================================================================
+; 4b. CTRL+BACKSPACE WORD DELETION
+; Mimics Word/standard editor behavior: delete previous word.
+; ============================================================================
+
+CtrlBackspace(editCtrl, *) {
+ ; Select previous word then delete โ simpler approach avoids timing issues
+ Send("^+{Left}{Del}")
+}
+
; ============================================================================
; 5. ATOMIC SAVE (Data Integrity)
; - Strategy: Write to .tmp -> Verify -> Replace original.
@@ -279,7 +607,10 @@ SaveNoteAtomic(notePath, content) {
; - Minimizes Disk I/O and CPU usage during navigation.
; ============================================================================
-ClearPreview() => ToolTip()
+ClearPreview() {
+ HideStyledTip()
+ ToolTip()
+}
PreviewStart() {
global PreviewState
@@ -297,7 +628,7 @@ PreviewStop() {
PreviewState["Active"] := false
PreviewState["LastPath"] := ""
SetTimer(PreviewTick, 0)
- SetTimer(ClearPreview, -250) ; 1 sec delay to clear the tooltip
+ SetTimer(ClearPreview, -250) ; 250ms delay to clear the tooltip
}
PreviewTick() {
@@ -318,6 +649,7 @@ PreviewTick() {
shellWin := GetExplorerWindow()
if !shellWin {
+ HideStyledTip()
ToolTip()
return
}
@@ -330,12 +662,13 @@ PreviewTick() {
}
if !focusedPath || InStr(focusedPath, "\.filenotes\") {
+ HideStyledTip()
ToolTip()
return
}
SplitPath(focusedPath, &fileName, &fileDir)
- notePath := fileDir "\.filenotes\" fileName ".txt"
+ notePath := EncodeNotePath(focusedPath)
if notePath = PreviewState["LastPath"]
return
@@ -343,46 +676,23 @@ PreviewTick() {
PreviewState["LastPath"] := notePath
if FileExist(notePath) {
- contentToDisplay := ""
- currentFileTime := ""
- try currentFileTime := FileGetTime(notePath, "M")
-
- ; CACHE LOOKUP
- if NoteCache.Has(notePath) {
- cachedData := NoteCache[notePath]
- if currentFileTime = cachedData.FileTime && (A_TickCount - cachedData.AccessTime) < CACHE_MAX_AGE {
- contentToDisplay := cachedData.Content
- cachedData.AccessTime := A_TickCount
- } else {
- NoteCache.Delete(notePath)
- }
+ contentToDisplay := ReadNoteContent(notePath)
+ if contentToDisplay {
+ if (STYLE_MANUAL = "styled")
+ ShowStyledTip("๐ " fileName, contentToDisplay)
+ else
+ ToolTip("๐ " fileName "`nโโโโโโโโโโโโโโโโโโโโ`n" contentToDisplay)
+ } else {
+ if (STYLE_MANUAL = "styled")
+ ShowStyledTip("", "(Empty description)")
+ else
+ ToolTip("(Empty description)")
}
-
- ; DISK READ
- if !contentToDisplay {
- try {
- contentToDisplay := FileRead(notePath, "m4000 UTF-8")
- if contentToDisplay {
- NoteCache[notePath] := {
- Content: contentToDisplay,
- AccessTime: A_TickCount,
- FileTime: currentFileTime
- }
-
- ; Simple FIFO eviction
- if NoteCache.Count > CACHE_MAX_SIZE {
- for key in NoteCache {
- NoteCache.Delete(key)
- break
- }
- }
- }
- }
- }
-
- ToolTip(contentToDisplay ? contentToDisplay : "(Empty description)")
} else {
- ToolTip("(No description)")
+ if (STYLE_MANUAL = "styled")
+ ShowStyledTip("", "(No description)")
+ else
+ ToolTip("(No description)")
}
} finally {
_inProgress := false
@@ -440,6 +750,122 @@ GetExplorerWindow() {
}
+; ============================================================================
+; 8. SETTINGS GUI (Hotkey Configuration)
+; - Allows users to change hotkeys via a visual interface.
+; - Saves configuration to config.ini next to the script.
+; ============================================================================
+
+OpenSettingsGUI() {
+ static settingsOpen := false
+ if settingsOpen
+ return
+ settingsOpen := true
+
+ sGui := Gui("+OwnDialogs", "FileExplorerNotes - Settings")
+ sGui.MarginX := 15
+ sGui.MarginY := 10
+ sGui.BackColor := COLOR_BG
+
+ ; Win11 Dark Title Bar
+ try DllCall("dwmapi\DwmSetWindowAttribute", "ptr", sGui.Hwnd, "int", 20, "int*", 1, "int", 4)
+ try DllCall("dwmapi\DwmSetWindowAttribute", "ptr", sGui.Hwnd, "int", 35, "int*", 0x00000000, "int", 4)
+
+ sGui.SetFont("s10 c" COLOR_TEXT, "Segoe UI")
+
+ sGui.Add("Text", , "Hotkey Syntax: ^ = Ctrl | ! = Alt | + = Shift | # = Win")
+ sGui.Add("Text", , "Example: ^+d = Ctrl+Shift+D")
+ sGui.Add("Text", "y+15", "")
+
+ sGui.Add("Text", , "Create/Edit Note:")
+ editCreate := sGui.Add("Edit", "vHkCreate w200 Background" COLOR_EDIT " c" COLOR_TEXT, HK_CREATE)
+ try DllCall("uxtheme\SetWindowTheme", "ptr", editCreate.Hwnd, "str", "DarkMode_CFD", "ptr", 0)
+
+ sGui.Add("Text", "y+10", "Preview Note (hold):")
+ editPreview := sGui.Add("Edit", "vHkPreview w200 Background" COLOR_EDIT " c" COLOR_TEXT, HK_PREVIEW)
+ try DllCall("uxtheme\SetWindowTheme", "ptr", editPreview.Hwnd, "str", "DarkMode_CFD", "ptr", 0)
+
+ sGui.Add("Text", "y+10", "Settings Hotkey:")
+ editSettings := sGui.Add("Edit", "vHkSettings w200 Background" COLOR_EDIT " c" COLOR_TEXT, HK_SETTINGS)
+ try DllCall("uxtheme\SetWindowTheme", "ptr", editSettings.Hwnd, "str", "DarkMode_CFD", "ptr", 0)
+
+ ; --- Auto-Preview Section ---
+ sGui.Add("Text", "x15 y+20", "โโโโโโโ Auto-Preview โโโโโโโ")
+
+ sGui.Add("Text", "y+10", "Enabled:")
+ chkAutoPreview := sGui.Add("Checkbox", "vAutoPreviewOn c" COLOR_TEXT " Checked" AUTO_PREVIEW_ENABLED)
+ try DllCall("uxtheme\SetWindowTheme", "ptr", chkAutoPreview.Hwnd, "str", "DarkMode_Explorer", "ptr", 0)
+
+ sGui.Add("Text", "y+10", "Display Duration (ms):")
+ editDuration := sGui.Add("Edit", "vAutoPreviewDur w200 Background" COLOR_EDIT " c" COLOR_TEXT, AUTO_PREVIEW_DURATION)
+ try DllCall("uxtheme\SetWindowTheme", "ptr", editDuration.Hwnd, "str", "DarkMode_CFD", "ptr", 0)
+
+ ; --- Tooltip Style Section ---
+ sGui.Add("Text", "x15 y+20", "โโโโโโโ Tooltip Style โโโโโโโ")
+
+ sGui.Add("Text", "y+10", "Auto-Preview Style:")
+ ddAutoStyle := sGui.Add("DropDownList", "vStyleAuto w200 Background" COLOR_EDIT " c" COLOR_TEXT, ["styled", "default"])
+ ddAutoStyle.Text := STYLE_AUTO
+ try DllCall("uxtheme\SetWindowTheme", "ptr", ddAutoStyle.Hwnd, "str", "DarkMode_CFD", "ptr", 0)
+
+ sGui.Add("Text", "y+10", "Manual Preview Style (Ctrl+Q):")
+ ddManualStyle := sGui.Add("DropDownList", "vStyleManual w200 Background" COLOR_EDIT " c" COLOR_TEXT, ["styled", "default"])
+ ddManualStyle.Text := STYLE_MANUAL
+ try DllCall("uxtheme\SetWindowTheme", "ptr", ddManualStyle.Hwnd, "str", "DarkMode_CFD", "ptr", 0)
+
+ sGui.Add("Text", "y+15", "")
+
+ btnApply := sGui.Add("Button", "w100 h30 Default", "Save && Reload")
+ try DllCall("uxtheme\SetWindowTheme", "ptr", btnApply.Hwnd, "str", "DarkMode_Explorer", "ptr", 0)
+
+ btnFolder := sGui.Add("Button", "x+10 w100 h30", "Notes Folder")
+ try DllCall("uxtheme\SetWindowTheme", "ptr", btnFolder.Hwnd, "str", "DarkMode_Explorer", "ptr", 0)
+
+ btnClose := sGui.Add("Button", "x+10 w100 h30", "Cancel")
+ try DllCall("uxtheme\SetWindowTheme", "ptr", btnClose.Hwnd, "str", "DarkMode_Explorer", "ptr", 0)
+
+ btnApply.OnEvent("Click", SettingsSave.Bind(sGui))
+ btnFolder.OnEvent("Click", (*) => Run(NOTES_DIR))
+ btnClose.OnEvent("Click", (*) => (settingsOpen := false, sGui.Destroy()))
+ sGui.OnEvent("Close", (*) => (settingsOpen := false, sGui.Destroy()))
+
+ sGui.Show("AutoSize")
+}
+
+SettingsSave(sGui, *) {
+ global HK_CREATE, HK_PREVIEW, HK_SETTINGS
+
+ newCreate := sGui["HkCreate"].Value
+ newPreview := sGui["HkPreview"].Value
+ newSettings := sGui["HkSettings"].Value
+ newAutoEnabled := sGui["AutoPreviewOn"].Value
+ newAutoDuration := sGui["AutoPreviewDur"].Value
+ newStyleAuto := sGui["StyleAuto"].Text
+ newStyleManual := sGui["StyleManual"].Text
+
+ if (newCreate = "" || newPreview = "" || newSettings = "") {
+ MsgBox("Hotkeys cannot be empty.", "Error", "Icon!")
+ return
+ }
+
+ if !IsInteger(newAutoDuration) || Integer(newAutoDuration) < 500 {
+ MsgBox("Duration must be a number >= 500 ms.", "Error", "Icon!")
+ return
+ }
+
+ SaveConfig("Hotkeys", "CreateNote", newCreate)
+ SaveConfig("Hotkeys", "Preview", newPreview)
+ SaveConfig("Hotkeys", "Settings", newSettings)
+ SaveConfig("AutoPreview", "Enabled", newAutoEnabled)
+ SaveConfig("AutoPreview", "Duration", newAutoDuration)
+ SaveConfig("Style", "AutoPreview", newStyleAuto)
+ SaveConfig("Style", "ManualPreview", newStyleManual)
+
+ sGui.Destroy()
+ Reload()
+}
+
+
; ============================================================================
; ๐ USER GUIDE & REFERENCE
; ============================================================================
diff --git a/config.ini b/config.ini
new file mode 100644
index 0000000000000000000000000000000000000000..6c0d77abf225a6aa2c3341a23cc4dfb4908ba7c2
GIT binary patch
literal 298
zcmZvXJqyA>5JX=s_)BbzV0nf3fsG=h3<{B)5|j(ZM9H65$2}|pveoR|o1J^VGS*Zy
zT<~<<*)wFooLV~9-m^8|<2W#)Fn?$MgHry}oSW@a=|)o$I4dnOD-tH=XUu5jSM(F&
z)upJMBUhyqViRK)B5LbWiVL=%GS+;XW~9pNjEO1#FE}N7PReQZwlQ`i6{K@*`hA?b
I|5D?RKf_itQUCw|
literal 0
HcmV?d00001
diff --git a/desktop.ini b/desktop.ini
new file mode 100644
index 0000000000000000000000000000000000000000..83cca65673eb6280266d707f0af429ef9d5b0295
GIT binary patch
literal 182
zcmX|)O$z~G6osF)@=r8{Qk0dCvKi%FSYRPunPNs>ia(EMW}(}y=bX;H=lj`^5jYdM
zI1_hIau$@FsMyh_r8>wZD|1PDa@UEBy%@1&Z6asNQVQz8+uXy%l|DV4^zW#3#
Date: Fri, 24 Apr 2026 11:13:26 +0200
Subject: [PATCH 2/4] Update README.md
---
README.md | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/README.md b/README.md
index 4db60d9..3b54e30 100644
--- a/README.md
+++ b/README.md
@@ -73,3 +73,30 @@ Follow these steps to get **FileExplorerNotes** running on your system:
This project is licensed under the **MIT License** - meaning it's free for everyone, forever.
*Stop guessing. Start committing context to your files.*
+
+## โ๏ธ License
+This project is licensed under the **MIT License** - meaning it's free for everyone, forever.
+
+*Stop guessing. Start committing context to your files.*
+
+---
+
+## ๐ v3.0 Enhancements (community fork by mario-dedalus)
+
+### Centralized Notes Storage
+Notes are no longer scattered across every folder. All notes are stored in a single hidden `.filenotes` folder next to the script, encoded by full file path. This makes backup, sync, and management trivial.
+
+### Auto-Preview
+The script now automatically shows a tooltip when you focus a file that has a note โ no hotkey needed. The tooltip dismisses itself after a configurable duration (default: 3 seconds).
+
+### Styled Tooltips
+Replaced the plain native `ToolTip()` with a custom dark-themed popup (rounded corners, Win11 DWM styling). Switchable back to the native tooltip per-mode via settings.
+
+### Settings GUI & Configurable Hotkeys
+All hotkeys and auto-preview options are configurable through a built-in settings window (tray menu โ Settings), saved to `config.ini`. No more editing the script to change a shortcut.
+
+### Delete Note
+Added a **Delete Note** button in the editor with a confirmation dialog.
+
+### Tray Menu
+Custom tray menu with quick access to Settings, the Notes folder, script editing, reload, and exit.
From 502f627d941a39cc367a8ea2e08aa9ebad470a0d Mon Sep 17 00:00:00 2001
From: Mario Abbate <89916197+mario-dedalus@users.noreply.github.com>
Date: Fri, 24 Apr 2026 11:14:16 +0200
Subject: [PATCH 3/4] Remove duplicate license information
Removed duplicate license section from README.
---
README.md | 5 -----
1 file changed, 5 deletions(-)
diff --git a/README.md b/README.md
index 3b54e30..2697601 100644
--- a/README.md
+++ b/README.md
@@ -74,11 +74,6 @@ This project is licensed under the **MIT License** - meaning it's free for every
*Stop guessing. Start committing context to your files.*
-## โ๏ธ License
-This project is licensed under the **MIT License** - meaning it's free for everyone, forever.
-
-*Stop guessing. Start committing context to your files.*
-
---
## ๐ v3.0 Enhancements (community fork by mario-dedalus)
From e9dfe4125302000ae956095f26270f7d8659b2af Mon Sep 17 00:00:00 2001
From: Mario Abbate <89916197+mario-dedalus@users.noreply.github.com>
Date: Fri, 24 Apr 2026 12:59:48 +0200
Subject: [PATCH 4/4] removing test data
---
...erminology management__tb_term_selector.py.txt | 9 ---------
config.ini | Bin 298 -> 0 bytes
desktop.ini | Bin 182 -> 0 bytes
3 files changed, 9 deletions(-)
delete mode 100644 .filenotes/C__Users__aqbge__OneDrive - Dedalus S.p.A__Desktop__Wichtige Dateien__Skripte__Terminology management__tb_term_selector.py.txt
delete mode 100644 config.ini
delete mode 100644 desktop.ini
diff --git a/.filenotes/C__Users__aqbge__OneDrive - Dedalus S.p.A__Desktop__Wichtige Dateien__Skripte__Terminology management__tb_term_selector.py.txt b/.filenotes/C__Users__aqbge__OneDrive - Dedalus S.p.A__Desktop__Wichtige Dateien__Skripte__Terminology management__tb_term_selector.py.txt
deleted file mode 100644
index 114bcf6..0000000
--- a/.filenotes/C__Users__aqbge__OneDrive - Dedalus S.p.A__Desktop__Wichtige Dateien__Skripte__Terminology management__tb_term_selector.py.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-Hallo,
-
-das ist ein Test.
-
-
-Du Mandala.
-
-
-Halidro!
\ No newline at end of file
diff --git a/config.ini b/config.ini
deleted file mode 100644
index 6c0d77abf225a6aa2c3341a23cc4dfb4908ba7c2..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 298
zcmZvXJqyA>5JX=s_)BbzV0nf3fsG=h3<{B)5|j(ZM9H65$2}|pveoR|o1J^VGS*Zy
zT<~<<*)wFooLV~9-m^8|<2W#)Fn?$MgHry}oSW@a=|)o$I4dnOD-tH=XUu5jSM(F&
z)upJMBUhyqViRK)B5LbWiVL=%GS+;XW~9pNjEO1#FE}N7PReQZwlQ`i6{K@*`hA?b
I|5D?RKf_itQUCw|
diff --git a/desktop.ini b/desktop.ini
deleted file mode 100644
index 83cca65673eb6280266d707f0af429ef9d5b0295..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 182
zcmX|)O$z~G6osF)@=r8{Qk0dCvKi%FSYRPunPNs>ia(EMW}(}y=bX;H=lj`^5jYdM
zI1_hIau$@FsMyh_r8>wZD|1PDa@UEBy%@1&Z6asNQVQz8+uXy%l|DV4^zW#3#