diff --git a/App.config b/App.config
index a362e17..4071362 100644
--- a/App.config
+++ b/App.config
@@ -23,11 +23,11 @@
-
+
-
+
@@ -35,7 +35,7 @@
-
+
@@ -49,6 +49,14 @@
+
+
+
+
+
+
+
+
diff --git a/FrmMainApp.cs b/FrmMainApp.cs
index aea4a50..b66169e 100644
--- a/FrmMainApp.cs
+++ b/FrmMainApp.cs
@@ -12,6 +12,7 @@
using System.Text.Json;
using System.Threading.Tasks;
using System.Windows.Forms;
+using AutoUpdaterDotNET;
using geoTagNinja;
using GeoTagNinja.Helpers;
using GeoTagNinja.Model;
@@ -342,10 +343,31 @@ private async void FrmMainApp_Load(object sender,
Request_Map_NavigateGo();
await HelperAPIVersionCheckers.CheckForNewVersions();
+ LaunchAutoUpdater();
Logger.Info(message: "OnLoad: Done.");
}
+ ///
+ /// This fires up the autoupdater
+ ///
+ private static void LaunchAutoUpdater()
+ {
+ HelperNonStatic updateHelper = new();
+ // AutoUpdater.InstalledVersion = new Version(version: "1.2"); // here for testing only.
+
+ AutoUpdater.Synchronous =
+ true; // needs to be true otherwise the single pipe instance crashes. (well, I think _that_ crashes, something does.)
+ AutoUpdater.ParseUpdateInfoEvent +=
+ updateHelper.AutoUpdaterOnParseUpdateInfoEvent;
+ AutoUpdater.CheckForUpdateEvent += updateHelper.AutoUpdaterOnCheckForUpdateEvent;
+
+ string updateJsonPath =
+ Path.Combine(path1: HelperVariables.UserDataFolderPath,
+ path2: "updateJsonData.json");
+ AutoUpdater.Start(appCast: Path.Combine(updateJsonPath));
+ }
+
///
/// When the app closes we want to make sure there's nothing in the write-queue.
@@ -751,16 +773,15 @@ void ShowLocToMapDialog()
// via https://stackoverflow.com/a/17385937/3968494
List getLocToMapDialogChoice =
- DialogWithCheckBox.DisplayAndReturnList(
+ DialogWithOrWithoutCheckBox.DisplayAndReturnList(
labelText: HelperDataLanguageTZ.DataReadDTObjectText(
objectType: ControlType.Label,
objectName: "lbl_QuestionAddToponomy"
),
caption: GenericGetMessageBoxCaption(
captionType: MessageBoxCaption.Question.ToString()),
- checkboxesDictionary: checkboxDictionary,
buttonsDictionary: buttonsDictionary,
- orientation: "Horizontal");
+ orientation: "Horizontal", checkboxesDictionary: checkboxDictionary);
_showLocToMapDialogChoice = getLocToMapDialogChoice.Contains(item: "yes");
_rememberLocToMapDialogChoice =
@@ -1462,7 +1483,6 @@ private async Task InitialiseWebView()
#endregion
-
#region File
///
@@ -1568,7 +1588,6 @@ private void tmi_File_Quit_Click(object sender,
#endregion
-
#region FrmMainApp's TaskBar Stuff
///
@@ -2238,14 +2257,14 @@ private void lvw_FileList_UpdateTagsFromWeb(string strGpsLatitude,
// ReSharper disable once InconsistentNaming
List APIHandlingChoice =
- DialogWithCheckBox.DisplayAndReturnList(
+ DialogWithOrWithoutCheckBox.DisplayAndReturnList(
labelText: GenericGetMessageBoxText(
messageBoxName: "mbx_FrmMainApp_QuestionNoRowsFromAPI"),
caption: GenericGetMessageBoxCaption(
captionType: MessageBoxCaption.Question.ToString()),
- checkboxesDictionary: checkboxDictionary,
buttonsDictionary: buttonsDictionary,
- orientation: "Horizontal");
+ orientation: "Horizontal",
+ checkboxesDictionary: checkboxDictionary);
if (APIHandlingChoice.Contains(value: "yes"))
{
diff --git a/FrmSettings.cs b/FrmSettings.cs
index 8bf0c34..9a0ab76 100644
--- a/FrmSettings.cs
+++ b/FrmSettings.cs
@@ -1126,8 +1126,7 @@ private void dgv_CustomRules_RowValidating(object sender,
"mbx_FrmSettings_dgv_CustomRules_CustomOutcomeCannotBeEmpty"),
caption: HelperControlAndMessageBoxHandling
.GenericGetMessageBoxCaption(
- captionType: HelperControlAndMessageBoxHandling
- .MessageBoxCaption.Information.ToString()),
+ captionType: HelperControlAndMessageBoxHandling.MessageBoxCaption.Information.ToString()),
buttons: MessageBoxButtons.OK,
icon: MessageBoxIcon.Warning);
customMessageBox.ShowDialog();
@@ -1187,15 +1186,15 @@ private void btn_ExportSettings_Click(object sender,
Dictionary buttonsDictionary = GetButtonsDictionary();
// ReSharper disable once InconsistentNaming
- List ItemsToExport = DialogWithCheckBox.DisplayAndReturnList(
+ List ItemsToExport = DialogWithOrWithoutCheckBox.DisplayAndReturnList(
labelText: HelperControlAndMessageBoxHandling.GenericGetMessageBoxText(
messageBoxName: "mbx_FrmSettings_QuestionWhatToExport"),
caption: HelperControlAndMessageBoxHandling.GenericGetMessageBoxCaption(
captionType: HelperControlAndMessageBoxHandling.MessageBoxCaption.Question
- .ToString()),
- checkboxesDictionary: checkboxDictionary,
+ .ToString()),
buttonsDictionary: buttonsDictionary,
- orientation: "Vertical");
+ orientation: "Vertical",
+ checkboxesDictionary: checkboxDictionary);
// ignore the whole thing if "no" is part of the output
// probably impossible that _neither_ of them are in the list but in case i missed something...
@@ -1234,8 +1233,7 @@ private void btn_ExportSettings_Click(object sender,
ex.Message,
caption: HelperControlAndMessageBoxHandling
.GenericGetMessageBoxCaption(
- captionType: HelperControlAndMessageBoxHandling
- .MessageBoxCaption.Error.ToString()),
+ captionType: HelperControlAndMessageBoxHandling.MessageBoxCaption.Error.ToString()),
buttons: MessageBoxButtons.OK,
icon: MessageBoxIcon.Error);
customMessageBox.ShowDialog();
@@ -1267,15 +1265,15 @@ private void btn_ImportSettings_Click(object sender,
Dictionary buttonsDictionary = GetButtonsDictionary();
// ReSharper disable once InconsistentNaming
- List ItemsToImport = DialogWithCheckBox.DisplayAndReturnList(
+ List ItemsToImport = DialogWithOrWithoutCheckBox.DisplayAndReturnList(
labelText: HelperControlAndMessageBoxHandling.GenericGetMessageBoxText(
messageBoxName: "mbx_FrmSettings_QuestionWhatToImport"),
caption: HelperControlAndMessageBoxHandling.GenericGetMessageBoxCaption(
captionType: HelperControlAndMessageBoxHandling.MessageBoxCaption
.Question.ToString()),
- checkboxesDictionary: checkboxDictionary,
buttonsDictionary: buttonsDictionary,
- orientation: "Vertical");
+ orientation: "Vertical",
+ checkboxesDictionary: checkboxDictionary);
// ignore the whole thing if "no" is part of the output
// probably impossible that _neither_ of them are in the list but in case i missed something...
@@ -1339,14 +1337,17 @@ private void PromptUserToRestartApp()
};
// ReSharper disable once InconsistentNaming
- List displayAndReturnList = DialogWithoutCheckBox.DisplayAndReturnList(
- labelText: HelperControlAndMessageBoxHandling.GenericGetMessageBoxText(
- messageBoxName: "mbx_FrmSettings_PleaseRestartApp"),
- caption: HelperControlAndMessageBoxHandling.GenericGetMessageBoxCaption(
- captionType: HelperControlAndMessageBoxHandling.MessageBoxCaption.Question
- .ToString()),
- buttonsDictionary: buttonsDictionary,
- orientation: "Horizontal");
+ List displayAndReturnList =
+ DialogWithOrWithoutCheckBox.DisplayAndReturnList(
+ labelText: HelperControlAndMessageBoxHandling.GenericGetMessageBoxText(
+ messageBoxName: "mbx_FrmSettings_PleaseRestartApp"),
+ caption: HelperControlAndMessageBoxHandling.GenericGetMessageBoxCaption(
+ captionType: HelperControlAndMessageBoxHandling.MessageBoxCaption
+ .Question
+ .ToString()),
+ buttonsDictionary: buttonsDictionary,
+ orientation: "Horizontal",
+ checkboxesDictionary: new Dictionary());
// basically this triggers an error in debug mode but works ok in prod.
#if !DEBUG
diff --git a/GeoTagNinja.csproj b/GeoTagNinja.csproj
index a0dd3f6..2dc5658 100644
--- a/GeoTagNinja.csproj
+++ b/GeoTagNinja.csproj
@@ -28,7 +28,7 @@
latest
- AnyCPU
+ x64
true
full
false
@@ -37,7 +37,7 @@
prompt
4
preview
- true
+ false
AnyCPU
@@ -62,6 +62,9 @@
app.manifest
+
+ packages\Autoupdater.NET.Official.1.8.5\lib\net45\AutoUpdater.NET.dll
+
packages\CommandLineParser.2.9.1\lib\net461\CommandLine.dll
@@ -80,24 +83,25 @@
packages\Magick.NET.Core.13.3.0\lib\netstandard20\Magick.NET.Core.dll
-
- packages\Microsoft.Bcl.AsyncInterfaces.7.0.0\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll
+
+ packages\Microsoft.Bcl.AsyncInterfaces.8.0.0\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll
packages\Microsoft.Bcl.HashCode.1.1.1\lib\net461\Microsoft.Bcl.HashCode.dll
-
- packages\Microsoft.Data.Sqlite.Core.7.0.10\lib\netstandard2.0\Microsoft.Data.Sqlite.dll
+
+
+ packages\Microsoft.Data.Sqlite.Core.8.0.4\lib\netstandard2.0\Microsoft.Data.Sqlite.dll
-
- packages\Microsoft.Web.WebView2.1.0.1938.49\lib\net45\Microsoft.Web.WebView2.Core.dll
+
+ packages\Microsoft.Web.WebView2.1.0.2478.35\lib\net45\Microsoft.Web.WebView2.Core.dll
-
- packages\Microsoft.Web.WebView2.1.0.1938.49\lib\net45\Microsoft.Web.WebView2.WinForms.dll
+
+ packages\Microsoft.Web.WebView2.1.0.2478.35\lib\net45\Microsoft.Web.WebView2.WinForms.dll
-
- packages\Microsoft.Web.WebView2.1.0.1938.49\lib\net45\Microsoft.Web.WebView2.Wpf.dll
+
+ packages\Microsoft.Web.WebView2.1.0.2478.35\lib\net45\Microsoft.Web.WebView2.Wpf.dll
packages\Microsoft.WindowsAPICodePack.Core.1.1.0\lib\Microsoft.WindowsAPICodePack.dll
@@ -112,18 +116,19 @@
packages\NLog.5.2.3\lib\net46\NLog.dll
+
packages\RestSharp.110.2.0\lib\net471\RestSharp.dll
-
- packages\SQLitePCLRaw.core.2.1.6\lib\netstandard2.0\SQLitePCLRaw.core.dll
+
+ packages\SQLitePCLRaw.core.2.1.8\lib\netstandard2.0\SQLitePCLRaw.core.dll
packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll
-
- packages\System.Collections.Immutable.7.0.0\lib\net462\System.Collections.Immutable.dll
+
+ packages\System.Collections.Immutable.8.0.0\lib\net462\System.Collections.Immutable.dll
@@ -152,14 +157,15 @@
True
True
-
- packages\System.Text.Encoding.CodePages.7.0.0\lib\net462\System.Text.Encoding.CodePages.dll
+
+
+ packages\System.Text.Encoding.CodePages.8.0.0\lib\net462\System.Text.Encoding.CodePages.dll
-
- packages\System.Text.Encodings.Web.7.0.0\lib\net462\System.Text.Encodings.Web.dll
+
+ packages\System.Text.Encodings.Web.8.0.0\lib\net462\System.Text.Encodings.Web.dll
-
- packages\System.Text.Json.7.0.3\lib\net462\System.Text.Json.dll
+
+ packages\System.Text.Json.8.0.3\lib\net462\System.Text.Json.dll
packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll
@@ -173,6 +179,7 @@
+
packages\TimeZoneConverter.6.1.0\lib\net462\TimeZoneConverter.dll
@@ -205,12 +212,12 @@
FrmManageFavourites.cs
+
Form
-
@@ -299,7 +306,7 @@
FileListView.cs
-
+
FrmAboutBox.cs
Designer
@@ -448,7 +455,7 @@
PreserveNewest
- PreserveNewest
+ Always
PreserveNewest
@@ -468,12 +475,12 @@
-
+
-
+
\ No newline at end of file
diff --git a/Helpers/HelperAPIVersionCheckers.cs b/Helpers/HelperAPIVersionCheckers.cs
index 3883c21..05fdb7e 100644
--- a/Helpers/HelperAPIVersionCheckers.cs
+++ b/Helpers/HelperAPIVersionCheckers.cs
@@ -1,5 +1,5 @@
using System;
-using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.IO.Compression;
@@ -138,6 +138,7 @@ private static int API_GenericGetGTNVersionFromWeb()
///
/// Checks for new versions of GTN and ExifTool.
///
+ [SuppressMessage(category: "ReSharper", checkId: "InconsistentNaming")]
internal static async Task CheckForNewVersions()
{
FrmMainApp.Logger.Debug(message: "Starting");
@@ -174,6 +175,7 @@ internal static async Task CheckForNewVersions()
int checkUpdateVal = 604800; //604800 is a week's worth of seconds
#if DEBUG
checkUpdateVal = 86400; // 86400 is a day's worth of seconds
+ //checkUpdateVal = 1;
#endif
if (nowUnixTime > lastCheckUnixTime + checkUpdateVal ||
@@ -220,13 +222,25 @@ await DownloadCurrentExifToolVersion(
// Done w ExifTool and move on to checking GTN stuff
// current version may be something like "0.5.8251.40825"
// Assembly.GetExecutingAssembly().GetName().Version.Build is just "8251"
- // ReSharper disable once InconsistentNaming
+ string currentGTNVersionBuildMajor = Assembly.GetExecutingAssembly()
+ .GetName()
+ .Version.Major
+ .ToString(
+ provider: CultureInfo
+ .InvariantCulture);
+
+ string currentGTNVersionBuildMinor = Assembly.GetExecutingAssembly()
+ .GetName()
+ .Version.Minor
+ .ToString(
+ provider: CultureInfo
+ .InvariantCulture);
+
int currentGTNVersionBuild = Assembly.GetExecutingAssembly()
.GetName()
.Version.Build;
HelperVariables.OperationAPIReturnedOKResponse = true;
- // ReSharper disable once InconsistentNaming
int newestOnlineGTNVersion = 0;
try
{
@@ -237,30 +251,10 @@ await DownloadCurrentExifToolVersion(
// ignore
}
- if (newestOnlineGTNVersion > currentGTNVersionBuild)
- {
- CustomMessageBox customMessageBox = new(
- text: HelperControlAndMessageBoxHandling.GenericGetMessageBoxText(
- messageBoxName:
- "mbx_FrmMainApp_InfoNewGTNVersionExists") +
- newestOnlineGTNVersion,
- caption: HelperControlAndMessageBoxHandling
- .GenericGetMessageBoxCaption(
- captionType: HelperControlAndMessageBoxHandling.MessageBoxCaption.Warning.ToString()),
- buttons: MessageBoxButtons.YesNo,
- icon: MessageBoxIcon.Asterisk)
- ;
- DialogResult dialogResult = customMessageBox.ShowDialog();
- if (dialogResult == DialogResult.Yes)
- {
- Process.Start(
- fileName:
- "https://github.com/nemethviktor/GeoTagNinja/releases/download/b" +
- newestOnlineGTNVersion.ToString(
- provider: CultureInfo.InvariantCulture) +
- "/GeoTagNinja_Setup.msi");
- }
- }
+ CreateJsonForUpdate(localMajor: currentGTNVersionBuildMajor,
+ localMinor: currentGTNVersionBuildMinor,
+ remoteBuild: newestOnlineGTNVersion.ToString(
+ provider: CultureInfo.InvariantCulture));
// write back to SQL
HelperDataApplicationSettings.DataWriteSQLiteSettings(
@@ -303,4 +297,35 @@ private static async Task DownloadCurrentExifToolVersion(string version)
// ignore
}
}
+
+ private static void CreateJsonForUpdate(string localMajor,
+ string localMinor,
+ string remoteBuild)
+ {
+ // Create JSON object
+ var jsonObject = new
+ {
+ // don't care/can't query remote major and minor
+ version = $"{localMajor}.{localMinor}.{remoteBuild}.0",
+ url =
+ $"https://github.com/nemethviktor/GeoTagNinja/releases/download/b{remoteBuild}/GeoTagNinja_Setup.msi",
+ changelog =
+ $"https://github.com/nemethviktor/GeoTagNinja/blob/b{remoteBuild}/changelog.md"
+ };
+
+ string jsonContent =
+ JsonConvert.SerializeObject(value: jsonObject,
+ formatting: Formatting.Indented);
+
+ string updateJsonPath =
+ Path.Combine(path1: HelperVariables.UserDataFolderPath,
+ path2: "updateJsonData.json");
+
+ if (File.Exists(path: updateJsonPath))
+ {
+ File.Delete(path: updateJsonPath);
+ }
+
+ File.WriteAllText(path: updateJsonPath, contents: jsonContent);
+ }
}
\ No newline at end of file
diff --git a/Helpers/HelperExifExifToolOperator.cs b/Helpers/HelperExifExifToolOperator.cs
index 58be1b4..a2ca729 100644
--- a/Helpers/HelperExifExifToolOperator.cs
+++ b/Helpers/HelperExifExifToolOperator.cs
@@ -150,7 +150,7 @@ await Task.Run(action: () =>
{
RemoveDirElementFromDe3AndCopyDataToOriginal(
dirElemToDrop: dirElemFileToDrop,
- frmMainAppInstance);
+ frmMainAppInstance: frmMainAppInstance);
}
if (Path.GetExtension(path: fileNameWithoutPath) ==
@@ -175,7 +175,7 @@ await Task.Run(action: () =>
{
RemoveDirElementFromDe3AndCopyDataToOriginal(
dirElemToDrop: dirElemFileToDrop,
- frmMainAppInstance);
+ frmMainAppInstance: frmMainAppInstance);
if (!processOriginalFile && writeXmpSideCar)
{
string pathOfFile =
@@ -190,6 +190,7 @@ await Task.Run(action: () =>
pathOfFile);
RemoveDirElementFromDe3AndCopyDataToOriginal(
dirElemToDrop: dirElemFileToDrop,
+ frmMainAppInstance:
frmMainAppInstance);
}
}
@@ -210,7 +211,8 @@ await Task.Run(action: () =>
length: fileNameWithoutPath.LastIndexOf(
value: '.'))))
{
- bool pathIsLikelyUTF = fileNameWithPath.Any(c => c > 127);
+ bool pathIsLikelyUTF =
+ fileNameWithPath.Any(predicate: c => c > 127);
MessageBox.Show(text: data.Data +
(pathIsLikelyUTF
? Environment.NewLine +
@@ -238,13 +240,14 @@ await Task.Run(action: () =>
prcExifTool.OutputDataReceived += (_,
data) =>
{
- if (data.Data != null && data.Data.Length > 0)
+ if (data.Data != null &&
+ data.Data.Length > 0)
{
- HelperVariables._sOutputMsg +=
+ HelperVariables._sOutputAndErrorMsg +=
data.Data.ToString() + Environment.NewLine;
}
- decimal.TryParse(s: HelperVariables._sOutputMsg
+ decimal.TryParse(s: HelperVariables._sOutputAndErrorMsg
.Replace(oldValue: "\r", newValue: "")
.Replace(oldValue: "\n", newValue: ""),
provider: CultureInfo.InvariantCulture,
@@ -259,20 +262,46 @@ await Task.Run(action: () =>
prcExifTool.OutputDataReceived += (_,
data) =>
{
- if (data.Data != null && data.Data.Length > 0)
+ if (data.Data is
+ {
+ Length: > 0
+ } &&
+ // this piece of info is irrelevant and confusing to the user
+ !data.Data.ToString()
+ .EndsWith(
+ value:
+ ".xmp does not exist") &&
+ // this piece of info is irrelevant and confusing to the user
+ !data.Data.ToString()
+ .EndsWith(
+ value:
+ "is not defined")
+ )
{
- HelperVariables._sOutputMsg +=
+ HelperVariables._sOutputAndErrorMsg +=
data.Data.ToString() + Environment.NewLine;
}
};
+ prcExifTool.ErrorDataReceived += (_,
+ data) =>
+ {
+ if (data.Data != null &&
+ data.Data.Length > 0)
+ {
+ HelperVariables._sOutputAndErrorMsg += "ERROR: " +
+ data.Data.ToString() +
+ Environment.NewLine;
+ }
+ };
break;
default:
prcExifTool.OutputDataReceived += (_,
data) =>
{
- if (data.Data != null && data.Data.Length > 0)
+ if (data.Data != null &&
+ data.Data.Length > 0)
{
- HelperVariables._sOutputMsg +=
+ HelperVariables._sOutputAndErrorMsg +=
data.Data.ToString() + Environment.NewLine;
}
};
@@ -280,11 +309,12 @@ await Task.Run(action: () =>
prcExifTool.ErrorDataReceived += (_,
data) =>
{
- if (data.Data != null && data.Data.Length > 0)
+ if (data.Data != null &&
+ data.Data.Length > 0)
{
- HelperVariables._sOutputMsg += "ERROR: " +
- data.Data.ToString() +
- Environment.NewLine;
+ HelperVariables._sOutputAndErrorMsg += "ERROR: " +
+ data.Data.ToString() +
+ Environment.NewLine;
}
};
break;
diff --git a/Helpers/HelperExifReadGetImagePreviews.cs b/Helpers/HelperExifReadGetImagePreviews.cs
index cd28db5..d15dd56 100644
--- a/Helpers/HelperExifReadGetImagePreviews.cs
+++ b/Helpers/HelperExifReadGetImagePreviews.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Text;
@@ -125,13 +126,19 @@ internal static async Task GenericCreateImagePreview(string fileNameWithPath,
try
{
- if (fi.Extension.ToLower() == ".heic" ||
- fi.Extension.ToLower() == ".heif")
+ List magickExtensionList =
+ [
+ ".heic",
+ ".heif",
+ ".webp"
+ ];
+
+ if (magickExtensionList.Contains(item: fi.Extension.ToLower()))
{
// actually the reason i'm not using this for _every_ file is that it's just f...ing slow with NEF files(which is what I have plenty of), so it's prohibitive to run on RAW files.
- // since i don't have a better way to deal with HEIC files atm this is as good as it gets.
- ConvertHeicToJpeg(heicPath: fileNameWithPath,
- jpegPath: generatedFileName);
+ // since i don't have a better way to deal with HEIC/WEBP files atm this is as good as it gets.
+ UseMagickImageToGeneratePreview(originalImagePath: fileNameWithPath,
+ jpegPath: generatedFileName);
}
else
{
@@ -200,20 +207,19 @@ internal static async Task GenericCreateImagePreview(string fileNameWithPath,
}
///
- /// Takes a HEIC file and dumps a JPG. Uses MagickImage. See comment above as to why this isn't being used for all RAW
+ /// Takes a HEIC/WebP/etc file and dumps a JPG. Uses MagickImage. See comment above as to why this isn't being used for
+ /// all RAW
/// files. (Too slow).
///
- ///
+ ///
///
- public static void ConvertHeicToJpeg(string heicPath,
- string jpegPath)
+ private static void UseMagickImageToGeneratePreview(string originalImagePath,
+ string jpegPath)
{
- using (MagickImage image = new(fileName: heicPath))
- {
- // The AutoOrient() method adjusts the image to respect its orientation.
- image.AutoOrient();
- // Save the image as a JPEG.
- image.Write(fileName: jpegPath);
- }
+ using MagickImage image = new(fileName: originalImagePath);
+ // The AutoOrient() method adjusts the image to respect its orientation.
+ image.AutoOrient();
+ // Save the image as a JPEG.
+ image.Write(fileName: jpegPath);
}
}
\ No newline at end of file
diff --git a/Helpers/HelperExifReadTrackData.cs b/Helpers/HelperExifReadTrackData.cs
index d629ad4..dce65ae 100644
--- a/Helpers/HelperExifReadTrackData.cs
+++ b/Helpers/HelperExifReadTrackData.cs
@@ -44,8 +44,8 @@ internal static async Task ExifGetTrackSyncData(string trackFileLocationType,
string language,
int timeShiftSeconds = 0)
{
- HelperVariables._sErrorMsg = "";
- HelperVariables._sOutputMsg = "";
+ //HelperVariables._sErrorMsg = "";
+ HelperVariables._sOutputAndErrorMsg = "";
FrmMainApp frmMainAppInstance =
(FrmMainApp)Application.OpenForms[name: "FrmMainApp"];
@@ -429,11 +429,13 @@ await FileListViewReadWrite
TextBox tbxText = new();
tbxText.Size = new Size(width: 700, height: 400);
- tbxText.Text = HelperVariables._sOutputMsg;
+ tbxText.Text = HelperVariables._sOutputAndErrorMsg;
tbxText.ScrollBars = ScrollBars.Vertical;
tbxText.Multiline = true;
tbxText.WordWrap = true;
tbxText.ReadOnly = true;
+ tbxText.SelectionStart = 1;
+ tbxText.SelectionLength = 0;
panel.SetFlowBreak(control: tbxText, value: true);
panel.Controls.Add(value: tbxText);
@@ -458,6 +460,11 @@ await FileListViewReadWrite
reportBox.ShowInTaskbar = false;
reportBox.StartPosition = FormStartPosition.CenterScreen;
+ HelperControlThemeManager.SetThemeColour(
+ themeColour: HelperVariables.UserSettingUseDarkMode
+ ? ThemeColour.Dark
+ : ThemeColour.Light,
+ parentControl: reportBox);
reportBox.ShowDialog();
}
}
diff --git a/Helpers/HelperExifWriteTrackDataToSideCar.cs b/Helpers/HelperExifWriteTrackDataToSideCar.cs
index b38d3fc..302f17d 100644
--- a/Helpers/HelperExifWriteTrackDataToSideCar.cs
+++ b/Helpers/HelperExifWriteTrackDataToSideCar.cs
@@ -43,7 +43,7 @@ internal static async Task ExifWriteTrackDataToSideCar(List trackFileLis
Debug.Assert(condition: frmMainAppInstance != null, message: nameof(frmMainAppInstance) + " != null");
string exifArgsForOriginalFile = "";
- // as per https://exiftool.org/forum/index.php?msg=78652 the logic needs to be
+ // as per https://exiftool.org/forum/index.php?msg=78652 + https://exiftool.org/forum/index.php?topic=16011.new#new the logic needs to be
/*
-geotag=D:\temp3\2023-02-27.gpx
-geotag=D:\temp3\2023-02-28.gpx
@@ -54,7 +54,7 @@ internal static async Task ExifWriteTrackDataToSideCar(List trackFileLis
GeoMaxExtSecs=1800
D:\temp3\_2280104.ORF
D:\temp3\_2280105.ORF
- -v2
+ -v3
-srcfile
C:\Users\nemet\AppData\Roaming\GeoTagNinja\tmpLocFiles\%F.xmp
@@ -97,8 +97,8 @@ internal static async Task ExifWriteTrackDataToSideCar(List trackFileLis
exifArgsForOriginalFile += imageFilePath + Environment.NewLine;
}
- // -v2
- exifArgsForOriginalFile += "-v2" + Environment.NewLine;
+ // -v3
+ exifArgsForOriginalFile += "-v3" + Environment.NewLine;
// -srcfile
exifArgsForOriginalFile += "-srcfile" + Environment.NewLine;
// C:\Users\nemet\AppData\Roaming\GeoTagNinja\tmpLocFiles\%F.xmp
diff --git a/Helpers/HelperGenericAncillaryListsArrays.cs b/Helpers/HelperGenericAncillaryListsArrays.cs
index 80d433b..467eb93 100644
--- a/Helpers/HelperGenericAncillaryListsArrays.cs
+++ b/Helpers/HelperGenericAncillaryListsArrays.cs
@@ -638,51 +638,11 @@ Code TimeZone STD DST
CA Canada/Pacific −08:00 −07:00
CA Canada/Saskatchewan −06:00 −06:00
CA Canada/Yukon −07:00 −07:00
- CET +01:00 +02:00
CL Chile/Continental −04:00 −03:00
CL Chile/EasterIsland −06:00 −05:00
- CST6CDT −06:00 −05:00
CU Cuba −05:00 −04:00
- EET +02:00 +03:00
EG Egypt +02:00 +03:00
IE Eire +01:00 +00:00
- EST −05:00 −05:00
- EST5EDT −05:00 −04:00
- Etc/GMT +00:00 +00:00
- Etc/GMT+0 +00:00 +00:00
- Etc/GMT+1 −01:00 −01:00
- Etc/GMT+10 −10:00 −10:00
- Etc/GMT+11 −11:00 −11:00
- Etc/GMT+12 −12:00 −12:00
- Etc/GMT+2 −02:00 −02:00
- Etc/GMT+3 −03:00 −03:00
- Etc/GMT+4 −04:00 −04:00
- Etc/GMT+5 −05:00 −05:00
- Etc/GMT+6 −06:00 −06:00
- Etc/GMT+7 −07:00 −07:00
- Etc/GMT+8 −08:00 −08:00
- Etc/GMT+9 −09:00 −09:00
- Etc/GMT-0 +00:00 +00:00
- Etc/GMT-1 +01:00 +01:00
- Etc/GMT-10 +10:00 +10:00
- Etc/GMT-11 +11:00 +11:00
- Etc/GMT-12 +12:00 +12:00
- Etc/GMT-13 +13:00 +13:00
- Etc/GMT-14 +14:00 +14:00
- Etc/GMT-2 +02:00 +02:00
- Etc/GMT-3 +03:00 +03:00
- Etc/GMT-4 +04:00 +04:00
- Etc/GMT-5 +05:00 +05:00
- Etc/GMT-6 +06:00 +06:00
- Etc/GMT-7 +07:00 +07:00
- Etc/GMT-8 +08:00 +08:00
- Etc/GMT-9 +09:00 +09:00
- Etc/GMT0 +00:00 +00:00
- Etc/Greenwich +00:00 +00:00
- Etc/UCT +00:00 +00:00
- Etc/Universal +00:00 +00:00
- Etc/UTC +00:00 +00:00
- Etc/Zulu +00:00 +00:00
NL Europe/Amsterdam +01:00 +02:00
AD Europe/Andorra +01:00 +02:00
RU Europe/Astrakhan +04:00 +04:00
@@ -747,16 +707,9 @@ Code TimeZone STD DST
HR Europe/Zagreb +01:00 +02:00
UA Europe/Zaporozhye +02:00 +03:00
CH, DE, LI Europe/Zurich +01:00 +02:00
- Factory +00:00 +00:00
GB GB +00:00 +01:00
GB GB-Eire +00:00 +01:00
- GMT +00:00 +00:00
- GMT+0 +00:00 +00:00
- GMT-0 +00:00 +00:00
- GMT0 +00:00 +00:00
- Greenwich +00:00 +00:00
HK Hongkong +08:00 +08:00
- HST −10:00 −10:00
IS Iceland +00:00 +00:00
MG Indian/Antananarivo +03:00 +03:00
IO Indian/Chagos +06:00 +06:00
@@ -775,12 +728,9 @@ Code TimeZone STD DST
JP Japan +09:00 +09:00
MH Kwajalein +12:00 +12:00
LY Libya +02:00 +02:00
- MET +01:00 +02:00
MX Mexico/BajaNorte −08:00 −07:00
MX Mexico/BajaSur −07:00 −07:00
MX Mexico/General −06:00 −06:00
- MST −07:00 −07:00
- MST7MDT −07:00 −06:00
US Navajo −07:00 −06:00
NZ NZ +12:00 +13:00
NZ NZ-CHAT +12:45 +13:45
@@ -828,16 +778,6 @@ Code TimeZone STD DST
UM Pacific/Wake +12:00 +12:00
WF Pacific/Wallis +12:00 +12:00
FM Pacific/Yap +10:00 +10:00
- PL Poland +01:00 +02:00
- PT Portugal +00:00 +01:00
- CN PRC +08:00 +08:00
- PST8PDT −08:00 −07:00
- TW ROC +08:00 +08:00
- KR ROK +09:00 +09:00
- SG Singapore +08:00 +08:00
- TR Turkey +03:00 +03:00
- UCT +00:00 +00:00
- Universal +00:00 +00:00
US US/Alaska −09:00 −08:00
US US/Aleutian −10:00 −09:00
US US/Arizona −07:00 −07:00
@@ -850,10 +790,6 @@ Code TimeZone STD DST
US US/Mountain −07:00 −06:00
US US/Pacific −08:00 −07:00
AS US/Samoa −11:00 −11:00
- UTC +00:00 +00:00
- RU W-SU +03:00 +03:00
- WET +00:00 +01:00
- Zulu +00:00 +00:00
""";
@@ -1124,6 +1060,7 @@ internal static string[] AllCompatibleExtensions()
"orf Olympus RAW Format (TIFF-based)",
"ori Olympus RAW Format (TIFF-based)",
"pef Pentax (RAW) Electronic Format (TIFF-based)",
+ "png Portable Network Graphics",
"raf FujiFilm RAW Format",
"raw Kyocera Contax N Digital RAW",
"rw2 Panasonic RAW 2 (TIFF-based)",
@@ -1133,7 +1070,8 @@ internal static string[] AllCompatibleExtensions()
"thm Thumbnail image (JPEG)",
"tif QuickTime Image File",
"tiff Tagged Image File Format",
- "wdp Windows HD Photo / Media Photo / JPEG XR (TIFF-based)",
+ "wdp Windows HD Photo / Media Photo / JPEG XR (TIFF-based)",
+ "webp WebP Image File",
"x3f Sigma/Foveon RAW"
};
return result;
@@ -1153,7 +1091,8 @@ internal static string[] FileExtensionsThatUseXMP()
.Contains(value: "tiff"))
{
retList.Add(item: extension.Split('\t')
- .FirstOrDefault());
+ .FirstOrDefault()
+ ?.Trim());
}
}
@@ -1178,7 +1117,8 @@ internal static string[] AllCompatibleExtensionsExt()
{
allowedExtensions[i] = allowedExtensions[i]
.Split('\t')
- .FirstOrDefault();
+ .FirstOrDefault()
+ ?.Trim();
}
return allowedExtensions;
diff --git a/Helpers/HelperGenericAppStartup.cs b/Helpers/HelperGenericAppStartup.cs
index 7672a9c..297a3a1 100644
--- a/Helpers/HelperGenericAppStartup.cs
+++ b/Helpers/HelperGenericAppStartup.cs
@@ -318,7 +318,9 @@ public static void AppStartupCheckWebView2()
try
{
string webView2Version = "";
- webView2Version = CoreWebView2Environment.GetAvailableBrowserVersionString();
+ webView2Version =
+ CoreWebView2Environment.GetAvailableBrowserVersionString(
+ browserExecutableFolder: null);
FrmMainApp.Logger.Trace(message: "Check webView2 version is: " + webView2Version);
}
catch (Exception ex)
diff --git a/Helpers/HelperNonStatic.AutoUpdater.cs b/Helpers/HelperNonStatic.AutoUpdater.cs
new file mode 100644
index 0000000..302ceab
--- /dev/null
+++ b/Helpers/HelperNonStatic.AutoUpdater.cs
@@ -0,0 +1,92 @@
+using System;
+using System.Windows.Forms;
+using AutoUpdaterDotNET;
+using Newtonsoft.Json;
+
+namespace GeoTagNinja.Helpers;
+
+internal partial class HelperNonStatic
+{
+ internal void AutoUpdaterOnParseUpdateInfoEvent(ParseUpdateInfoEventArgs args)
+ {
+ dynamic json = JsonConvert.DeserializeObject(value: args.RemoteData);
+ args.UpdateInfo = new UpdateInfoEventArgs
+ {
+ CurrentVersion = json.version,
+ ChangelogURL = json.changelog,
+ DownloadURL = json.url
+ };
+ }
+
+ internal void AutoUpdaterOnCheckForUpdateEvent(UpdateInfoEventArgs args)
+ {
+ if (args.Error == null)
+ {
+ if (args.IsUpdateAvailable)
+ {
+ DialogResult dialogResult;
+ //if (args.Mandatory.Value)
+ //{
+ // dialogResult =
+ // MessageBox.Show(
+ // text:
+ // $@"There is new version {args.CurrentVersion} available. You are using version {args.InstalledVersion}. This is required update. Press Ok to begin updating the application.",
+ // caption: @"Update Available",
+ // buttons: MessageBoxButtons.OK,
+ // icon: MessageBoxIcon.Information);
+ //}
+ //else
+ {
+ dialogResult =
+ MessageBox.Show(
+ text:
+ $@"There is new version {args.CurrentVersion} available. You are using version {args.InstalledVersion}. Do you want to update the application now?",
+ caption: @"Update Available",
+ buttons: MessageBoxButtons.YesNo,
+ icon: MessageBoxIcon.Information);
+ }
+
+ if (dialogResult.Equals(obj: DialogResult.Yes) ||
+ dialogResult.Equals(obj: DialogResult.OK))
+ {
+ try
+ {
+ if (AutoUpdater.DownloadUpdate(args: args))
+ {
+ Application.Exit();
+ }
+ }
+ catch (Exception exception)
+ {
+ MessageBox.Show(text: exception.Message, caption: exception
+ .GetType()
+ .ToString(), buttons: MessageBoxButtons.OK,
+ icon: MessageBoxIcon.Error);
+ }
+ }
+ }
+ //else
+ //{
+ // MessageBox.Show(
+ // text: @"There is no update available please try again later.",
+ // caption: @"No update available",
+ // buttons: MessageBoxButtons.OK, icon: MessageBoxIcon.Information);
+ //}
+ }
+ //if (args.Error is WebException)
+ //{
+ // MessageBox.Show(
+ // text:
+ // @"There is a problem reaching update server. Please check your internet connection and try again later.",
+ // caption: @"Update Check Failed", buttons: MessageBoxButtons.OK,
+ // icon: MessageBoxIcon.Error);
+ //}
+ //else
+ //{
+ // MessageBox.Show(text: args.Error.Message,
+ // caption: args.Error.GetType()
+ // .ToString(), buttons: MessageBoxButtons.OK,
+ // icon: MessageBoxIcon.Error);
+ //}
+ }
+}
\ No newline at end of file
diff --git a/Helpers/HelperVariables.cs b/Helpers/HelperVariables.cs
index 0dd7c7c..cc69871 100644
--- a/Helpers/HelperVariables.cs
+++ b/Helpers/HelperVariables.cs
@@ -27,8 +27,8 @@ internal static class HelperVariables
internal static bool OperationAPIReturnedOKResponse = true;
internal static bool OperationNowSelectingAllItems = false;
- internal static string _sErrorMsg = "";
- internal static string _sOutputMsg = "";
+ //internal static string _sErrorMsg = "";
+ internal static string _sOutputAndErrorMsg = "";
internal static string HTMLAddMarker;
internal static string HTMLCreatePoints;
internal static HashSet<(string strLat, string strLng)> HsMapMarkers = new();
diff --git a/SQLite.Interop.dll b/SQLite.Interop.dll
index 322eb05..12de96a 100644
Binary files a/SQLite.Interop.dll and b/SQLite.Interop.dll differ
diff --git a/View/DialogAndMessageBoxes/CustomMessageBox.cs b/View/DialogAndMessageBoxes/CustomMessageBox.cs
index 6e0dded..39574e8 100644
--- a/View/DialogAndMessageBoxes/CustomMessageBox.cs
+++ b/View/DialogAndMessageBoxes/CustomMessageBox.cs
@@ -10,6 +10,7 @@ public class CustomMessageBox : Form
{
private Label _lblMessage;
private PictureBox _pictureBox;
+ private const string NAMEANDTEXT = "CustomMessageBox";
///
/// Initializes a new instance of the CustomMessageBox class.
@@ -48,29 +49,48 @@ public CustomMessageBox(string text,
CreateButton(text: "Cancel", result: DialogResult.Cancel);
break;
case MessageBoxButtons.YesNo:
- CreateButton(text: "Yes", result: DialogResult.Yes);
- CreateButton(text: "No", result: DialogResult.No);
+ CreateButton(text: "&Yes", result: DialogResult.Yes);
+ CreateButton(text: "&No", result: DialogResult.No);
break;
case MessageBoxButtons.YesNoCancel:
- CreateButton(text: "Yes", result: DialogResult.Yes);
- CreateButton(text: "No", result: DialogResult.No);
+ CreateButton(text: "&Yes", result: DialogResult.Yes);
+ CreateButton(text: "&No", result: DialogResult.No);
CreateButton(text: "Cancel", result: DialogResult.Cancel);
break;
case MessageBoxButtons.RetryCancel:
- CreateButton(text: "Retry", result: DialogResult.Retry);
+ CreateButton(text: "&Retry", result: DialogResult.Retry);
CreateButton(text: "Cancel", result: DialogResult.Cancel);
break;
case MessageBoxButtons.AbortRetryIgnore:
- CreateButton(text: "Abort", result: DialogResult.Abort);
- CreateButton(text: "Retry", result: DialogResult.Retry);
- CreateButton(text: "Ignore", result: DialogResult.Ignore);
+ CreateButton(text: "&Abort", result: DialogResult.Abort);
+ CreateButton(text: "&Retry", result: DialogResult.Retry);
+ CreateButton(text: "&Ignore", result: DialogResult.Ignore);
break;
default:
- throw new ArgumentOutOfRangeException(paramName: nameof(buttons), actualValue: buttons, message: null);
+ throw new ArgumentOutOfRangeException(paramName: nameof(buttons),
+ actualValue: buttons,
+ message: null);
}
PositionButtons();
// Set icon in PictureBox based on MessageBoxIcon value
+ SetPictureBox(icon: icon);
+ }
+
+ public sealed override string Text
+ {
+ get => base.Text;
+ set => base.Text = value;
+ }
+
+
+ ///
+ /// Sets the picture box (icon) for the Form
+ ///
+ ///
+ ///
+ private void SetPictureBox(MessageBoxIcon icon)
+ {
if (icon == MessageBoxIcon.None)
{
_pictureBox.Image = null;
@@ -109,7 +129,8 @@ public CustomMessageBox(string text,
}
else
{
- throw new ArgumentOutOfRangeException(paramName: nameof(icon), actualValue: icon, message: null);
+ throw new ArgumentOutOfRangeException(paramName: nameof(icon),
+ actualValue: icon, message: null);
}
}
@@ -145,8 +166,8 @@ private void InitializeComponent()
AutoScaleDimensions = new SizeF(width: 6F, height: 13F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(width: 284, height: 261);
- Name = "CustomMessageBox";
- Text = "CustomMessageBox";
+ Name = NAMEANDTEXT;
+ Text = NAMEANDTEXT;
// Set additional properties
FormBorderStyle = FormBorderStyle.FixedDialog;
MaximizeBox = false;
@@ -173,6 +194,17 @@ private void CreateButton(string text,
button.Click += (sender,
e) => DialogResult = result;
button.Size = new Size(width: ButtonWidth, height: ButtonHeight);
+ button.UseMnemonic = true;
+ if (result == DialogResult.OK)
+ {
+ AcceptButton = button;
+ }
+
+ else if (result == DialogResult.Cancel)
+ {
+ CancelButton = button;
+ }
+
_buttons.Add(item: button);
_buttonCount++;
}
@@ -183,7 +215,9 @@ private void PositionButtons()
int startX = (Width - totalWidth) / 2;
for (int i = 0; i < _buttonCount; i++)
{
- _buttons[index: i].Location = new Point(x: startX + i * (ButtonWidth + ButtonSpacing), y: Math.Max(val1: _lblMessage.Bottom, val2: _pictureBox.Bottom) + 10);
+ _buttons[index: i].Location = new Point(
+ x: startX + i * (ButtonWidth + ButtonSpacing),
+ y: Math.Max(val1: _lblMessage.Bottom, val2: _pictureBox.Bottom) + 10);
Controls.Add(value: _buttons[index: i]);
}
}
diff --git a/View/DialogAndMessageBoxes/DialogWithCheckBox.cs b/View/DialogAndMessageBoxes/DialogWithOrWithoutCheckBox.cs
similarity index 77%
rename from View/DialogAndMessageBoxes/DialogWithCheckBox.cs
rename to View/DialogAndMessageBoxes/DialogWithOrWithoutCheckBox.cs
index 0d454d4..3defe89 100644
--- a/View/DialogAndMessageBoxes/DialogWithCheckBox.cs
+++ b/View/DialogAndMessageBoxes/DialogWithOrWithoutCheckBox.cs
@@ -6,17 +6,13 @@
namespace GeoTagNinja.View.DialogAndMessageBoxes;
-internal class DialogWithCheckBox
+internal class DialogWithOrWithoutCheckBox
{
///
/// Displays a dialog box with a set of checkboxes and buttons.
///
/// The text to be displayed at the top of the dialog box.
/// The text to be displayed in the title bar of the dialog box.
- ///
- /// A dictionary where each key-value pair represents a checkbox in the dialog. The key
- /// is the text to be displayed next to the checkbox, and the value is the return value when the checkbox is selected.
- ///
///
/// A dictionary where each key-value pair represents a button in the dialog. The key is
/// the text to be displayed on the button, and the value is the return value when the button is clicked.
@@ -25,14 +21,18 @@ internal class DialogWithCheckBox
/// The layout orientation of the checkboxes and buttons in the dialog. Can be either "Vertical"
/// or "Horizontal".
///
+ ///
+ /// A dictionary where each key-value pair represents a checkbox in the dialog. The key
+ /// is the text to be displayed next to the checkbox, and the value is the return value when the checkbox is selected.
+ ///
/// A list of strings representing the return values of the selected checkboxes and clicked button.
internal static List DisplayAndReturnList(string labelText,
string caption,
- Dictionary
- checkboxesDictionary,
Dictionary
buttonsDictionary,
- string orientation)
+ string orientation,
+ Dictionary
+ checkboxesDictionary)
{
List returnChoicesList = new();
Form promptBoxForm = new()
@@ -104,20 +104,29 @@ void AddButtons()
{
KeyValuePair keyValuePair =
buttonsDictionary.ElementAt(index: i);
- Button btn = new();
- btn.Text = keyValuePair.Key;
- switch (keyValuePair.Value.ToLower())
+ string btnText = keyValuePair.Key;
+ Button btn = new()
{
- case "yes":
- case "ok":
- promptBoxForm.AcceptButton = btn;
- acceptButtonReturnText = keyValuePair.Value;
- break;
- case "no":
- case "cancel":
- promptBoxForm.CancelButton = btn;
- cancelButtonReturnText = keyValuePair.Value;
- break;
+ UseMnemonic = true,
+ Text = btnText is "Yes" or "No"
+ ? "&" + btnText
+ : btnText
+ };
+ if (btnText.ToLower()
+ .Contains(value: "yes") ||
+ btnText.ToLower()
+ .Contains(value: "ok"))
+ {
+ promptBoxForm.AcceptButton = btn;
+ acceptButtonReturnText = keyValuePair.Value;
+ }
+ else if (btnText.ToLower()
+ .Contains(value: "no") ||
+ btnText.ToLower()
+ .Contains(value: "cancel"))
+ {
+ promptBoxForm.CancelButton = btn;
+ cancelButtonReturnText = keyValuePair.Value;
}
btn.Click += (s,
@@ -148,21 +157,24 @@ void AddButtons()
void AddCheckBoxes()
{
- // add checkboxes
- for (int i = 0; i < checkboxesDictionary.Count; i++)
+ if (checkboxesDictionary.Count > 0)
{
- KeyValuePair keyValuePair =
- checkboxesDictionary.ElementAt(index: i);
- CheckBox chk = new();
- chk.Text = keyValuePair.Key;
- chk.AutoSize = true;
+ // add checkboxes
+ for (int i = 0; i < checkboxesDictionary.Count; i++)
+ {
+ KeyValuePair keyValuePair =
+ checkboxesDictionary.ElementAt(index: i);
+ CheckBox chk = new();
+ chk.Text = keyValuePair.Key;
+ chk.AutoSize = true;
- flowLayoutPanel.Controls.Add(value: chk);
+ flowLayoutPanel.Controls.Add(value: chk);
- if (i == checkboxesDictionary.Count &&
- orientation == "Vertical")
- {
- flowLayoutPanel.SetFlowBreak(control: chk, value: true);
+ if (i == checkboxesDictionary.Count &&
+ orientation == "Vertical")
+ {
+ flowLayoutPanel.SetFlowBreak(control: chk, value: true);
+ }
}
}
}
diff --git a/View/DialogAndMessageBoxes/DialogWithoutCheckBox.cs b/View/DialogAndMessageBoxes/DialogWithoutCheckBox.cs
deleted file mode 100644
index 171db4f..0000000
--- a/View/DialogAndMessageBoxes/DialogWithoutCheckBox.cs
+++ /dev/null
@@ -1,145 +0,0 @@
-using System.Collections.Generic;
-using System.Drawing;
-using System.Linq;
-using System.Windows.Forms;
-using GeoTagNinja.Helpers;
-
-namespace GeoTagNinja.View.DialogAndMessageBoxes;
-
-internal class DialogWithoutCheckBox
-{
- ///
- /// Displays a dialog box without a checkbox and returns a list of user choices.
- ///
- /// The text to be displayed in the dialog box.
- /// The title of the dialog box.
- ///
- /// A dictionary containing the text and return values of the buttons to be displayed in
- /// the dialog box.
- ///
- /// The orientation of the buttons in the dialog box. Can be either "Vertical" or "Horizontal".
- ///
- /// A list of strings representing the user's choices. The choices are determined by the buttons clicked by the
- /// user.
- ///
- ///
- /// The dialog box is displayed in the center of the screen. The theme of the dialog box is determined by the user's
- /// settings.
- /// If the user closes the dialog box without making a choice, the function returns a list containing the return value
- /// of the "no" or "cancel" button.
- ///
- internal static List DisplayAndReturnList(string labelText,
- string caption,
- Dictionary
- buttonsDictionary,
- string orientation)
- {
- List returnChoicesList = new();
- Form promptBoxForm = new()
- {
- Text = caption,
- ControlBox = false,
- FormBorderStyle = FormBorderStyle.Fixed3D
- };
-
- // Create the FlowLayoutPanel
- FlowLayoutPanel flowLayoutPanel = new();
- // Set the flow direction to top-to-bottom if the orientation is "Vertical"
- if (orientation == "Vertical")
- {
- flowLayoutPanel.FlowDirection = FlowDirection.TopDown;
- }
-
- // apply theme
- HelperControlThemeManager.SetThemeColour(
- themeColour: HelperVariables.UserSettingUseDarkMode
- ? ThemeColour.Dark
- : ThemeColour.Light, parentControl: promptBoxForm);
-
- Label lblText = new();
- lblText.Text = labelText;
- lblText.MaximumSize = new Size(width: 300, height: 0);
- lblText.AutoSize = true;
- flowLayoutPanel.SetFlowBreak(control: lblText, value: true);
- flowLayoutPanel.Controls.Add(value: lblText);
-
- // these are to make my life easier -- gets overwritten further down
- string acceptButtonReturnText = "##yes##";
- string cancelButtonReturnText = "##no##";
-
- AddButtons();
- flowLayoutPanel.Padding = new Padding(all: 5);
- flowLayoutPanel.AutoSize = true;
-
- promptBoxForm.Controls.Add(value: flowLayoutPanel);
- promptBoxForm.AutoSize = true;
- promptBoxForm.ShowInTaskbar = false;
-
- promptBoxForm.StartPosition = FormStartPosition.CenterScreen;
- promptBoxForm.ShowDialog();
-
- // in case of idiots break glass -- basically if someone ALT+F4s then we reset stuff to "no".
- if (!returnChoicesList.Contains(value: acceptButtonReturnText) &&
- !returnChoicesList.Contains(value: cancelButtonReturnText))
- {
- returnChoicesList.Add(item: cancelButtonReturnText);
- }
-
- return returnChoicesList;
-
- void AddButtons()
- {
- // add buttons
- for (int i = 0; i < buttonsDictionary.Count; i++)
- {
- KeyValuePair keyValuePair =
- buttonsDictionary.ElementAt(index: i);
- Button btn = new();
- btn.Text = keyValuePair.Key;
- btn.Tag = keyValuePair.Value;
- switch (keyValuePair.Value.ToLower())
- {
- case "yes":
- case "ok":
- promptBoxForm.AcceptButton = btn;
- acceptButtonReturnText = keyValuePair.Value;
- break;
- case "no":
- case "cancel":
- promptBoxForm.CancelButton = btn;
- cancelButtonReturnText = keyValuePair.Value;
- break;
- }
-
- btn.Click += (s,
- e) =>
- {
- if (promptBoxForm.AcceptButton == btn)
- {
- returnChoicesList.Add(item: acceptButtonReturnText);
- }
- else if (promptBoxForm.CancelButton == btn)
- {
- returnChoicesList.Add(item: cancelButtonReturnText);
- }
- else
- {
- returnChoicesList.Add(item: btn.Tag.ToString());
- }
-
- promptBoxForm.Close();
- };
- btn.AutoSize = true;
- flowLayoutPanel.Controls.Add(value: btn);
- // add flowbreak to the last btn
- if (i == buttonsDictionary.Count &&
- orientation == "Horizontal")
- {
- flowLayoutPanel.SetFlowBreak(control: btn, value: true);
- }
- }
- }
- }
-}
-
-
diff --git a/changelog.md b/changelog.md
index c2ac2b1..3ced50f 100644
--- a/changelog.md
+++ b/changelog.md
@@ -1,6 +1,17 @@
# GeoTagNinja Changelog
**Build 8xxx [20240xxx]**
+- NEW & UPDATED:
+ - Dark Mode should now apply to GPX Import Report
+ - Custom MessageBoxes should now respect hotkeys in certain cases
+ - Added PNG and WEBP file support
+ - Added an auto-updater. It's a bit tricky to test but I think it works. Report bugs pls.
+ - Updated some of the underlying packages; removed x86 references to SQLite
+
+- BUGS & FIXES:
+ - Patched GPX Import Report re #105
+
+**Build 8834 [20240309]**
- NEW & UPDATED:
- Paste coordinate-pair string from clipboard into Edit Form (see readme about this or the tooltip in the Edit Form) #100
- Added a button to the Edit Form to move to the next image when there's a multi-selection (Apply & Move to Next) [also #100]
diff --git a/packages.config b/packages.config
index e9f97fa..52a8523 100644
--- a/packages.config
+++ b/packages.config
@@ -1,24 +1,25 @@
+
-
+
-
-
+
+
-
+
-
+
@@ -27,9 +28,9 @@
-
-
-
+
+
+
diff --git a/readme.md b/readme.md
index a2f5f73..70dcd18 100644
--- a/readme.md
+++ b/readme.md
@@ -5,7 +5,7 @@ GeoTagNinja is an open-source photo geotagger GUI for Windows. GTN uses [exifToo
There is a "short" (15 mins) demo on [YouTube](https://youtu.be/ulP1ZG7mH-I) if you feel like watching it. It's from the original (Aug 2022) release but it still covers the main features more or less. It's only gotten better since...
-## Download & Install (Windows 7+ only)
+## Download & Install (Windows 7+ x64 only)
- Download the .msi file from [Releases](https://github.com/nemethviktor/GeoTagNinja/releases) - Find the newest release (topmost, easy) then click on Assets if they are not showing. [There are now Development and Prod releases, both should be stable but if you'd like to be on the safer side, pick the prod updates.]
- As of 20221202 I've removed the built-in webView2 installer because it was more of a pain in the backside than benefit. If the app breaks complaining about the lack of webView2, it's available [here](https://go.microsoft.com/fwlink/p/?LinkId=2124703)
@@ -141,8 +141,7 @@ Longer: Hypothetically the idea with Destinations is that if there are groups of
## System Requirements
-- Windows 7+ is needed.
-- SQLite is running x86 but fwiw the app isn't really memory-hungry so it will do. Chances are if you're still on a 1st-gen Intel Core you're not on Windows 7. Hopefully.
+- Windows 7+ x64 is needed.
- You'll need an ArcGIS API key to use the map search functionality. Register for free [here](https://developers.arcgis.com/)
- You'll need a geoNames username and password to use toponomy search. Register for free [here](https://www.geonames.org/)
- WebView2 is required but should come with your OS most likely. If not, get it from [here](https://go.microsoft.com/fwlink/p/?LinkId=2124703)
\ No newline at end of file