Features and Localization Updates for 1.5.2
Enhances user experience with increased contrast option for titlebar buttons. Adds localization option for the PDF preview page, improving accessibility for international users. Includes localization option and upgrade message for the InnoSetup installer, ensuring a smoother and more informative installation process.
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -45,4 +45,5 @@ extra/*.dll
|
|||||||
|
|
||||||
|
|
||||||
*.eml
|
*.eml
|
||||||
*.msg
|
*.msg
|
||||||
|
frontend/bun.lock
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
[EMLy]
|
[EMLy]
|
||||||
SDK_DECODER_SEMVER = 1.3.2
|
SDK_DECODER_SEMVER = 1.3.2
|
||||||
SDK_DECODER_RELEASE_CHANNEL = stable
|
SDK_DECODER_RELEASE_CHANNEL = stable
|
||||||
GUI_SEMVER = 1.5.0
|
GUI_SEMVER = 1.5.2
|
||||||
GUI_RELEASE_CHANNEL = beta
|
GUI_RELEASE_CHANNEL = beta
|
||||||
LANGUAGE = it
|
LANGUAGE = it
|
||||||
UPDATE_CHECK_ENABLED = false
|
UPDATE_CHECK_ENABLED = false
|
||||||
|
|||||||
6
frontend/.gitignore
vendored
6
frontend/.gitignore
vendored
@@ -27,4 +27,8 @@ src/lib/paraglide
|
|||||||
project.inlang/cache/
|
project.inlang/cache/
|
||||||
|
|
||||||
# Wails
|
# Wails
|
||||||
/src/lib/wailsjs
|
/src/lib/wailsjs
|
||||||
|
|
||||||
|
|
||||||
|
bun.lock
|
||||||
|
bun.lockb
|
||||||
@@ -201,5 +201,19 @@
|
|||||||
"settings_danger_update_checker_info": "Info: When enabled, the app will check for updates from your configured network share. Disable this if you manage updates manually or don't have network access.",
|
"settings_danger_update_checker_info": "Info: When enabled, the app will check for updates from your configured network share. Disable this if you manage updates manually or don't have network access.",
|
||||||
"settings_reduce_motion_label": "Reduce Motion",
|
"settings_reduce_motion_label": "Reduce Motion",
|
||||||
"settings_reduce_motion_hint": "Disable transition animations for interface elements like the sidebar.",
|
"settings_reduce_motion_hint": "Disable transition animations for interface elements like the sidebar.",
|
||||||
"settings_reduce_motion_info": "Info: When enabled, animations such as the sidebar slide transition will be removed for a snappier feel or to reduce visual distractions."
|
"settings_reduce_motion_info": "Info: When enabled, animations such as the sidebar slide transition will be removed for a snappier feel or to reduce visual distractions.",
|
||||||
|
"settings_window_buttons_contrast_label": "Increase window buttons contrast",
|
||||||
|
"settings_window_buttons_contrast_hint": "Makes the window control buttons (minimize, maximize, close) more visible by increasing their contrast.",
|
||||||
|
"pdf_viewer_title": "PDF Viewer",
|
||||||
|
"pdf_loading": "Loading PDF...",
|
||||||
|
"pdf_zoom_in": "Zoom In",
|
||||||
|
"pdf_zoom_out": "Zoom Out",
|
||||||
|
"pdf_rotate_left": "Rotate Left",
|
||||||
|
"pdf_rotate_right": "Rotate Right",
|
||||||
|
"pdf_fit_width": "Fit to Width",
|
||||||
|
"pdf_error_no_data": "No PDF data provided",
|
||||||
|
"pdf_error_no_data_desc": "No PDF data provided. Please open this window from the main EMLy application.",
|
||||||
|
"pdf_error_timeout": "Timeout loading PDF. The worker might have failed to initialize.",
|
||||||
|
"pdf_error_parsing": "Error parsing PDF: ",
|
||||||
|
"pdf_error_rendering": "Error rendering page: "
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -201,5 +201,19 @@
|
|||||||
"settings_danger_update_checker_info": "Info: Quando abilitato, l'app controllerà gli aggiornamenti dal percorso di rete configurato. Disabilitalo se gestisci gli aggiornamenti manualmente o non hai accesso alla rete.",
|
"settings_danger_update_checker_info": "Info: Quando abilitato, l'app controllerà gli aggiornamenti dal percorso di rete configurato. Disabilitalo se gestisci gli aggiornamenti manualmente o non hai accesso alla rete.",
|
||||||
"settings_reduce_motion_label": "Riduci Movimento",
|
"settings_reduce_motion_label": "Riduci Movimento",
|
||||||
"settings_reduce_motion_hint": "Disabilita le animazioni di transizione per gli elementi dell'interfaccia come la barra laterale.",
|
"settings_reduce_motion_hint": "Disabilita le animazioni di transizione per gli elementi dell'interfaccia come la barra laterale.",
|
||||||
"settings_reduce_motion_info": "Info: Quando abilitato, le animazioni come la transizione della barra laterale verranno rimosse per un'esperienza più reattiva o per ridurre le distrazioni visive."
|
"settings_reduce_motion_info": "Info: Quando abilitato, le animazioni come la transizione della barra laterale verranno rimosse per un'esperienza più reattiva o per ridurre le distrazioni visive.",
|
||||||
|
"settings_window_buttons_contrast_label": "Aumenta contrasto pulsanti finestra",
|
||||||
|
"settings_window_buttons_contrast_hint": "Rende i pulsanti di controllo della finestra (minimizza, massimizza, chiudi) più visibili aumentando il loro contrasto.",
|
||||||
|
"pdf_viewer_title": "Visualizzatore PDF",
|
||||||
|
"pdf_loading": "Caricamento PDF...",
|
||||||
|
"pdf_zoom_in": "Ingrandisci",
|
||||||
|
"pdf_zoom_out": "Riduci",
|
||||||
|
"pdf_rotate_left": "Ruota a sinistra",
|
||||||
|
"pdf_rotate_right": "Ruota a destra",
|
||||||
|
"pdf_fit_width": "Adatta alla larghezza",
|
||||||
|
"pdf_error_no_data": "Nessun dato PDF fornito",
|
||||||
|
"pdf_error_no_data_desc": "Nessun dato PDF fornito. Apri questa finestra dall'applicazione principale EMLy.",
|
||||||
|
"pdf_error_timeout": "Timeout caricamento PDF. Il worker potrebbe non essersi inizializzato correttamente.",
|
||||||
|
"pdf_error_parsing": "Errore nel parsing del PDF: ",
|
||||||
|
"pdf_error_rendering": "Errore nel rendering della pagina: "
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ const defaults: EMLy_GUI_Settings = {
|
|||||||
musicInspirationEnabled: false,
|
musicInspirationEnabled: false,
|
||||||
reduceMotion: false,
|
reduceMotion: false,
|
||||||
theme: "dark",
|
theme: "dark",
|
||||||
|
increaseWindowButtonsContrast: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
class SettingsStore {
|
class SettingsStore {
|
||||||
|
|||||||
1
frontend/src/lib/types.d.ts
vendored
1
frontend/src/lib/types.d.ts
vendored
@@ -13,6 +13,7 @@ interface EMLy_GUI_Settings {
|
|||||||
musicInspirationEnabled?: boolean;
|
musicInspirationEnabled?: boolean;
|
||||||
reduceMotion?: boolean;
|
reduceMotion?: boolean;
|
||||||
theme?: "light" | "dark";
|
theme?: "light" | "dark";
|
||||||
|
increaseWindowButtonsContrast?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
type SupportedLanguages = "en" | "it";
|
type SupportedLanguages = "en" | "it";
|
||||||
|
|||||||
@@ -304,7 +304,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="controls">
|
<div class="controls" class:high-contrast={settingsStore.settings.increaseWindowButtonsContrast}>
|
||||||
<button class="btn" onclick={minimize}>─</button>
|
<button class="btn" onclick={minimize}>─</button>
|
||||||
|
|
||||||
<button class="btn" onclick={toggleMaximize}>
|
<button class="btn" onclick={toggleMaximize}>
|
||||||
@@ -694,6 +694,10 @@
|
|||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.controls.high-contrast {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
.btn {
|
.btn {
|
||||||
width: 46px;
|
width: 46px;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|||||||
@@ -43,6 +43,7 @@
|
|||||||
enableUpdateChecker: false,
|
enableUpdateChecker: false,
|
||||||
reduceMotion: false,
|
reduceMotion: false,
|
||||||
theme: "dark",
|
theme: "dark",
|
||||||
|
increaseWindowButtonsContrast: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
async function setLanguage(
|
async function setLanguage(
|
||||||
@@ -80,6 +81,7 @@
|
|||||||
: (s.enableUpdateChecker ?? defaults.enableUpdateChecker ?? true),
|
: (s.enableUpdateChecker ?? defaults.enableUpdateChecker ?? true),
|
||||||
reduceMotion: s.reduceMotion ?? defaults.reduceMotion ?? false,
|
reduceMotion: s.reduceMotion ?? defaults.reduceMotion ?? false,
|
||||||
theme: s.theme || defaults.theme || "light",
|
theme: s.theme || defaults.theme || "light",
|
||||||
|
increaseWindowButtonsContrast: s.increaseWindowButtonsContrast ?? defaults.increaseWindowButtonsContrast ?? false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,6 +95,7 @@
|
|||||||
!!a.enableUpdateChecker === !!b.enableUpdateChecker &&
|
!!a.enableUpdateChecker === !!b.enableUpdateChecker &&
|
||||||
!!a.reduceMotion === !!b.reduceMotion &&
|
!!a.reduceMotion === !!b.reduceMotion &&
|
||||||
(a.theme ?? "light") === (b.theme ?? "light") &&
|
(a.theme ?? "light") === (b.theme ?? "light") &&
|
||||||
|
!!a.increaseWindowButtonsContrast === !!b.increaseWindowButtonsContrast &&
|
||||||
JSON.stringify(a.previewFileSupportedTypes?.sort()) ===
|
JSON.stringify(a.previewFileSupportedTypes?.sort()) ===
|
||||||
JSON.stringify(b.previewFileSupportedTypes?.sort())
|
JSON.stringify(b.previewFileSupportedTypes?.sort())
|
||||||
);
|
);
|
||||||
@@ -467,6 +470,45 @@
|
|||||||
<p class="text-xs text-muted-foreground mt-2">
|
<p class="text-xs text-muted-foreground mt-2">
|
||||||
{m.settings_reduce_motion_info()}
|
{m.settings_reduce_motion_info()}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<Separator />
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="flex items-center justify-between gap-4 rounded-lg border bg-card p-4"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<div class="font-medium">
|
||||||
|
{m.settings_window_buttons_contrast_label()}
|
||||||
|
</div>
|
||||||
|
<div class="text-sm text-muted-foreground">
|
||||||
|
{m.settings_window_buttons_contrast_hint()}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Switch
|
||||||
|
bind:checked={form.increaseWindowButtonsContrast}
|
||||||
|
class="cursor-pointer hover:cursor-pointer"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="flex items-center justify-between gap-4 rounded-lg border bg-card p-4"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<div class="font-medium">
|
||||||
|
{m.settings_email_dark_viewer_label()}
|
||||||
|
</div>
|
||||||
|
<div class="text-sm text-muted-foreground">
|
||||||
|
{m.settings_email_dark_viewer_hint()}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Switch
|
||||||
|
bind:checked={form.useDarkEmailViewer}
|
||||||
|
class="cursor-pointer hover:cursor-pointer"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<p class="text-xs text-muted-foreground mt-2">
|
||||||
|
{m.settings_email_dark_viewer_info()}
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</Card.Content>
|
</Card.Content>
|
||||||
</Card.Root>
|
</Card.Root>
|
||||||
@@ -495,7 +537,7 @@
|
|||||||
{m.settings_export_button()}
|
{m.settings_export_button()}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<Separator />
|
|
||||||
<div
|
<div
|
||||||
class="flex items-center justify-between gap-4 rounded-lg border bg-card p-4"
|
class="flex items-center justify-between gap-4 rounded-lg border bg-card p-4"
|
||||||
>
|
>
|
||||||
@@ -640,29 +682,6 @@
|
|||||||
{m.settings_preview_pdf_builtin_info()}
|
{m.settings_preview_pdf_builtin_info()}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<Separator />
|
|
||||||
|
|
||||||
<div class="space-y-3">
|
|
||||||
<div
|
|
||||||
class="flex items-center justify-between gap-4 rounded-lg border bg-card p-4"
|
|
||||||
>
|
|
||||||
<div>
|
|
||||||
<div class="font-medium">
|
|
||||||
{m.settings_email_dark_viewer_label()}
|
|
||||||
</div>
|
|
||||||
<div class="text-sm text-muted-foreground">
|
|
||||||
{m.settings_email_dark_viewer_hint()}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<Switch
|
|
||||||
bind:checked={form.useDarkEmailViewer}
|
|
||||||
class="cursor-pointer hover:cursor-pointer"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<p class="text-xs text-muted-foreground mt-2">
|
|
||||||
{m.settings_email_dark_viewer_info()}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</Card.Content>
|
</Card.Content>
|
||||||
</Card.Root>
|
</Card.Root>
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
Quit,
|
Quit,
|
||||||
} from "$lib/wailsjs/runtime/runtime";
|
} from "$lib/wailsjs/runtime/runtime";
|
||||||
import type { LayoutProps } from "./$types";
|
import type { LayoutProps } from "./$types";
|
||||||
|
import { settingsStore } from "$lib/stores/settings.svelte.js";
|
||||||
|
|
||||||
let { data, children }: LayoutProps = $props();
|
let { data, children }: LayoutProps = $props();
|
||||||
|
|
||||||
@@ -57,7 +58,7 @@
|
|||||||
>
|
>
|
||||||
<div class="title">EMLy PDF Viewer</div>
|
<div class="title">EMLy PDF Viewer</div>
|
||||||
|
|
||||||
<div class="controls">
|
<div class="controls" class:high-contrast={settingsStore.settings.increaseWindowButtonsContrast}>
|
||||||
<button class="btn" onclick={minimize}>─</button>
|
<button class="btn" onclick={minimize}>─</button>
|
||||||
<button class="btn" onclick={toggleMaximize}>
|
<button class="btn" onclick={toggleMaximize}>
|
||||||
{#if isMaximized}
|
{#if isMaximized}
|
||||||
@@ -120,6 +121,10 @@
|
|||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.controls.high-contrast {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
.btn {
|
.btn {
|
||||||
width: 46px;
|
width: 46px;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
} from "@lucide/svelte";
|
} from "@lucide/svelte";
|
||||||
import { sidebarOpen } from "$lib/stores/app";
|
import { sidebarOpen } from "$lib/stores/app";
|
||||||
import { toast } from "svelte-sonner";
|
import { toast } from "svelte-sonner";
|
||||||
|
import * as m from "$lib/paraglide/messages.js";
|
||||||
import * as pdfjsLib from "pdfjs-dist";
|
import * as pdfjsLib from "pdfjs-dist";
|
||||||
import pdfWorker from "pdfjs-dist/build/pdf.worker.min.mjs?url";
|
import pdfWorker from "pdfjs-dist/build/pdf.worker.min.mjs?url";
|
||||||
|
|
||||||
@@ -63,9 +64,8 @@
|
|||||||
|
|
||||||
await loadPDF();
|
await loadPDF();
|
||||||
} else {
|
} else {
|
||||||
toast.error("No PDF data provided");
|
toast.error(m.pdf_error_no_data());
|
||||||
error =
|
error = m.pdf_error_no_data_desc();
|
||||||
"No PDF data provided. Please open this window from the main EMLy application.";
|
|
||||||
loading = false;
|
loading = false;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -81,8 +81,7 @@
|
|||||||
const timeout = setTimeout(() => {
|
const timeout = setTimeout(() => {
|
||||||
if (loading) {
|
if (loading) {
|
||||||
loading = false;
|
loading = false;
|
||||||
error =
|
error = m.pdf_error_timeout();
|
||||||
"Timeout loading PDF. The worker might have failed to initialize.";
|
|
||||||
toast.error(error);
|
toast.error(error);
|
||||||
}
|
}
|
||||||
}, 10000);
|
}, 10000);
|
||||||
@@ -96,7 +95,7 @@
|
|||||||
loading = false;
|
loading = false;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
error = "Error parsing PDF: " + e;
|
error = m.pdf_error_parsing() + e;
|
||||||
loading = false;
|
loading = false;
|
||||||
} finally {
|
} finally {
|
||||||
clearTimeout(timeout);
|
clearTimeout(timeout);
|
||||||
@@ -135,7 +134,7 @@
|
|||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
if (e.name !== "RenderingCancelledException") {
|
if (e.name !== "RenderingCancelledException") {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
toast.error("Error rendering page: " + e.message);
|
toast.error(m.pdf_error_rendering() + e.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -189,7 +188,7 @@
|
|||||||
{#if loading}
|
{#if loading}
|
||||||
<div class="loading-overlay">
|
<div class="loading-overlay">
|
||||||
<div class="spinner"></div>
|
<div class="spinner"></div>
|
||||||
<div>Loading PDF...</div>
|
<div>{m.pdf_loading()}</div>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
@@ -200,24 +199,24 @@
|
|||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<div class="toolbar">
|
<div class="toolbar">
|
||||||
<h1 class="title" title={filename}>{filename || "Image Viewer"}</h1>
|
<h1 class="title" title={filename}>{filename || m.pdf_viewer_title()}</h1>
|
||||||
|
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<button class="btn" onclick={() => zoom(0.1)} title="Zoom In">
|
<button class="btn" onclick={() => zoom(0.1)} title={m.pdf_zoom_in()}>
|
||||||
<ZoomIn size="16" />
|
<ZoomIn size="16" />
|
||||||
</button>
|
</button>
|
||||||
<button class="btn" onclick={() => zoom(-0.1)} title="Zoom Out">
|
<button class="btn" onclick={() => zoom(-0.1)} title={m.pdf_zoom_out()}>
|
||||||
<ZoomOut size="16" />
|
<ZoomOut size="16" />
|
||||||
</button>
|
</button>
|
||||||
<div class="separator"></div>
|
<div class="separator"></div>
|
||||||
<button class="btn" onclick={() => rotate(-90)} title="Rotate Left">
|
<button class="btn" onclick={() => rotate(-90)} title={m.pdf_rotate_left()}>
|
||||||
<RotateCcw size="16" />
|
<RotateCcw size="16" />
|
||||||
</button>
|
</button>
|
||||||
<button class="btn" onclick={() => rotate(90)} title="Rotate Right">
|
<button class="btn" onclick={() => rotate(90)} title={m.pdf_rotate_right()}>
|
||||||
<RotateCw size="16" />
|
<RotateCw size="16" />
|
||||||
</button>
|
</button>
|
||||||
<div class="separator"></div>
|
<div class="separator"></div>
|
||||||
<button class="btn" onclick={fitToWidth} title="Reset">
|
<button class="btn" onclick={fitToWidth} title={m.pdf_fit_width()}>
|
||||||
<AlignHorizontalSpaceAround size="16" />
|
<AlignHorizontalSpaceAround size="16" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,6 +1,23 @@
|
|||||||
#define ApplicationName 'EMLy'
|
#define ApplicationName 'EMLy'
|
||||||
#define ApplicationVersion GetVersionNumbersString('EMLy.exe')
|
#define ApplicationVersion GetVersionNumbersString('EMLy.exe')
|
||||||
#define ApplicationVersion '1.5.0'
|
#define ApplicationVersion '1.5.2'
|
||||||
|
|
||||||
|
[Languages]
|
||||||
|
Name: "english"; MessagesFile: "compiler:Default.isl"
|
||||||
|
Name: "italian"; MessagesFile: "compiler:Languages\Italian.isl"
|
||||||
|
|
||||||
|
[CustomMessages]
|
||||||
|
; English messages
|
||||||
|
english.UpgradeDetected=A previous version of {#ApplicationName} (v%1) has been detected.
|
||||||
|
english.UpgradeMessage=This installer will upgrade your installation to version {#ApplicationVersion}.%n%nYour settings and preferences will be preserved.%n%nDo you want to continue?
|
||||||
|
english.FreshInstall=Welcome to {#ApplicationName} {#ApplicationVersion} Setup
|
||||||
|
english.FreshInstallMessage=This will install {#ApplicationName} on your computer.
|
||||||
|
|
||||||
|
; Italian messages
|
||||||
|
italian.UpgradeDetected=È stata rilevata una versione precedente di {#ApplicationName} (v%1).
|
||||||
|
italian.UpgradeMessage=Questo installer aggiornerà la tua installazione alla versione {#ApplicationVersion}.%n%nLe tue impostazioni e preferenze saranno preservate.%n%nVuoi continuare?
|
||||||
|
italian.FreshInstall=Benvenuto nell'installazione di {#ApplicationName} {#ApplicationVersion}
|
||||||
|
italian.FreshInstallMessage=Questo installerà {#ApplicationName} sul tuo computer.
|
||||||
|
|
||||||
[Setup]
|
[Setup]
|
||||||
AppName={#ApplicationName}
|
AppName={#ApplicationName}
|
||||||
@@ -59,6 +76,65 @@ Root: HKA; Subkey: "Software\Classes\{#ApplicationName}.MSG\shell\open"; ValueTy
|
|||||||
Name: "{autoprograms}\{#ApplicationName}"; Filename: "{app}\{#ApplicationName}.exe"
|
Name: "{autoprograms}\{#ApplicationName}"; Filename: "{app}\{#ApplicationName}.exe"
|
||||||
|
|
||||||
[Code]
|
[Code]
|
||||||
|
var
|
||||||
|
PreviousVersion: String;
|
||||||
|
IsUpgrade: Boolean;
|
||||||
|
|
||||||
|
// Check if a previous version is installed
|
||||||
|
function GetPreviousVersion(): String;
|
||||||
|
var
|
||||||
|
RegPath: String;
|
||||||
|
Version: String;
|
||||||
|
begin
|
||||||
|
Result := '';
|
||||||
|
|
||||||
|
// Check HKLM (system-wide installation)
|
||||||
|
RegPath := 'Software\Microsoft\Windows\CurrentVersion\Uninstall\{#ApplicationName}_is1';
|
||||||
|
if RegQueryStringValue(HKLM, RegPath, 'DisplayVersion', Version) then
|
||||||
|
begin
|
||||||
|
Result := Version;
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
// Check HKCU (user installation)
|
||||||
|
if RegQueryStringValue(HKCU, RegPath, 'DisplayVersion', Version) then
|
||||||
|
begin
|
||||||
|
Result := Version;
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
// Initialize setup and detect upgrade
|
||||||
|
function InitializeSetup(): Boolean;
|
||||||
|
var
|
||||||
|
Message: String;
|
||||||
|
begin
|
||||||
|
Result := True;
|
||||||
|
PreviousVersion := GetPreviousVersion();
|
||||||
|
IsUpgrade := (PreviousVersion <> '');
|
||||||
|
|
||||||
|
if IsUpgrade then
|
||||||
|
begin
|
||||||
|
// Show upgrade message
|
||||||
|
Message := FmtMessage(CustomMessage('UpgradeDetected'), [PreviousVersion]) + #13#10#13#10 +
|
||||||
|
CustomMessage('UpgradeMessage');
|
||||||
|
|
||||||
|
if MsgBox(Message, mbInformation, MB_YESNO) = IDNO then
|
||||||
|
begin
|
||||||
|
Result := False;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
// Show appropriate welcome message
|
||||||
|
procedure InitializeWizard();
|
||||||
|
begin
|
||||||
|
if not IsUpgrade then
|
||||||
|
begin
|
||||||
|
WizardForm.WelcomeLabel2.Caption := CustomMessage('FreshInstallMessage');
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
// Override default directory based on installation mode
|
// Override default directory based on installation mode
|
||||||
function GetDefaultDirName(Param: string): string;
|
function GetDefaultDirName(Param: string): string;
|
||||||
begin
|
begin
|
||||||
|
|||||||
Reference in New Issue
Block a user