diff --git a/ElectronNET.API/Dialog.cs b/ElectronNET.API/Dialog.cs
index d30eab9..8fe4686 100644
--- a/ElectronNET.API/Dialog.cs
+++ b/ElectronNET.API/Dialog.cs
@@ -31,7 +31,7 @@ namespace ElectronNET.API
/// and a directory selector, so if you set properties to ['openFile', 'openDirectory']
/// on these platforms, a directory selector will be shown.
///
- ///
+ /// The browserWindow argument allows the dialog to attach itself to a parent window, making it modal.
///
/// An array of file paths chosen by the user
public Task ShowOpenDialogAsync(BrowserWindow browserWindow, OpenDialogOptions options)
@@ -53,6 +53,30 @@ namespace ElectronNET.API
return taskCompletionSource.Task;
}
+ ///
+ /// Dialog for save files.
+ ///
+ /// The browserWindow argument allows the dialog to attach itself to a parent window, making it modal.
+ ///
+ /// Returns String, the path of the file chosen by the user, if a callback is provided it returns an empty string.
+ public Task ShowSaveDialogAsync(BrowserWindow browserWindow, SaveDialogOptions options)
+ {
+ var taskCompletionSource = new TaskCompletionSource();
+
+ BridgeConnector.Socket.On("showSaveDialogComplete", (filename) =>
+ {
+ BridgeConnector.Socket.Off("showSaveDialogComplete");
+
+ taskCompletionSource.SetResult(filename.ToString());
+ });
+
+ BridgeConnector.Socket.Emit("showSaveDialog",
+ JObject.FromObject(browserWindow, _jsonSerializer),
+ JObject.FromObject(options, _jsonSerializer));
+
+ return taskCompletionSource.Task;
+ }
+
///
/// Shows a message box, it will block the process until the message box is closed.
/// It returns the index of the clicked button. The browserWindow argument allows
@@ -106,6 +130,58 @@ namespace ElectronNET.API
return taskCompletionSource.Task;
}
+ ///
+ /// Displays a modal dialog that shows an error message.
+ ///
+ /// This API can be called safely before the ready event the app module emits,
+ /// it is usually used to report errors in early stage of startup.If called
+ /// before the app readyevent on Linux, the message will be emitted to stderr,
+ /// and no GUI dialog will appear.
+ ///
+ /// The title to display in the error box.
+ /// The text content to display in the error box.
+ public void ShowErrorBox(string title, string content)
+ {
+ BridgeConnector.Socket.Emit("showErrorBox", title, content);
+ }
+
+ ///
+ /// On macOS, this displays a modal dialog that shows a message and certificate information,
+ /// and gives the user the option of trusting/importing the certificate. If you provide a
+ /// browserWindow argument the dialog will be attached to the parent window, making it modal.
+ ///
+ ///
+ ///
+ public Task ShowCertificateTrustDialogAsync(CertificateTrustDialogOptions options)
+ {
+ return ShowCertificateTrustDialogAsync(null, options);
+ }
+
+ ///
+ /// On macOS, this displays a modal dialog that shows a message and certificate information,
+ /// and gives the user the option of trusting/importing the certificate. If you provide a
+ /// browserWindow argument the dialog will be attached to the parent window, making it modal.
+ ///
+ ///
+ ///
+ ///
+ public Task ShowCertificateTrustDialogAsync(BrowserWindow browserWindow, CertificateTrustDialogOptions options)
+ {
+ var taskCompletionSource = new TaskCompletionSource();
+
+ BridgeConnector.Socket.On("showCertificateTrustDialogComplete", () =>
+ {
+ BridgeConnector.Socket.Off("showCertificateTrustDialogComplete");
+ taskCompletionSource.SetResult(null);
+ });
+
+ BridgeConnector.Socket.Emit("showCertificateTrustDialog",
+ JObject.FromObject(browserWindow, _jsonSerializer),
+ JObject.FromObject(options, _jsonSerializer));
+
+ return taskCompletionSource.Task;
+ }
+
private JsonSerializer _jsonSerializer = new JsonSerializer()
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
diff --git a/ElectronNET.API/Entities/Certificate.cs b/ElectronNET.API/Entities/Certificate.cs
new file mode 100644
index 0000000..957ce5b
--- /dev/null
+++ b/ElectronNET.API/Entities/Certificate.cs
@@ -0,0 +1,55 @@
+namespace ElectronNET.API.Entities
+{
+ public class Certificate
+ {
+ ///
+ /// PEM encoded data
+ ///
+ public string Data { get; set; }
+
+ ///
+ /// Fingerprint of the certificate
+ ///
+ public string Fingerprint { get; set; }
+
+ ///
+ /// Issuer principal
+ ///
+ public CertificatePrincipal Issuer { get; set; }
+
+ ///
+ /// Issuer certificate (if not self-signed)
+ ///
+ public Certificate IssuerCert { get; set; }
+
+ ///
+ /// Issuer's Common Name
+ ///
+ public string IssuerName { get; set; }
+
+ ///
+ /// Hex value represented string
+ ///
+ public string SerialNumber { get; set; }
+
+ ///
+ /// Subject principal
+ ///
+ public CertificatePrincipal Subject { get; set; }
+
+ ///
+ /// Subject's Common Name
+ ///
+ public string SubjectName { get; set; }
+
+ ///
+ /// End date of the certificate being valid in seconds
+ ///
+ public int ValidExpiry { get; set; }
+
+ ///
+ /// Start date of the certificate being valid in seconds
+ ///
+ public int ValidStart { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/ElectronNET.API/Entities/CertificatePrincipal.cs b/ElectronNET.API/Entities/CertificatePrincipal.cs
new file mode 100644
index 0000000..8691c96
--- /dev/null
+++ b/ElectronNET.API/Entities/CertificatePrincipal.cs
@@ -0,0 +1,35 @@
+namespace ElectronNET.API.Entities
+{
+ public class CertificatePrincipal
+ {
+ ///
+ /// Common Name
+ ///
+ public string CommonName { get; set; }
+
+ ///
+ /// Country or region
+ ///
+ public string Country { get; set; }
+
+ ///
+ /// Locality
+ ///
+ public string Locality { get; set; }
+
+ ///
+ /// Organization names
+ ///
+ public string[] Organizations { get; set; }
+
+ ///
+ /// Organization Unit names
+ ///
+ public string[] OrganizationUnits { get; set; }
+
+ ///
+ /// State or province
+ ///
+ public string State { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/ElectronNET.API/Entities/CertificateTrustDialogOptions.cs b/ElectronNET.API/Entities/CertificateTrustDialogOptions.cs
new file mode 100644
index 0000000..ed5729d
--- /dev/null
+++ b/ElectronNET.API/Entities/CertificateTrustDialogOptions.cs
@@ -0,0 +1,15 @@
+namespace ElectronNET.API.Entities
+{
+ public class CertificateTrustDialogOptions
+ {
+ ///
+ /// The certificate to trust/import.
+ ///
+ public Certificate Certificate { get; set; }
+
+ ///
+ /// The message to display to the user.
+ ///
+ public string Message { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/ElectronNET.API/Entities/SaveDialogOptions.cs b/ElectronNET.API/Entities/SaveDialogOptions.cs
new file mode 100644
index 0000000..42c4954
--- /dev/null
+++ b/ElectronNET.API/Entities/SaveDialogOptions.cs
@@ -0,0 +1,52 @@
+using ElectronNET.API.Entities;
+
+namespace ElectronNET.API
+{
+ public class SaveDialogOptions
+ {
+ public string Title { get; set; }
+
+ ///
+ /// Absolute directory path, absolute file path, or file name to use by default.
+ ///
+ public string DefaultPath { get; set; }
+
+ ///
+ /// Custom label for the confirmation button, when left empty the default label will
+ /// be used.
+ ///
+ public string ButtonLabel { get; set; }
+
+ ///
+ /// The filters specifies an array of file types that can be displayed or
+ /// selected when you want to limit the user to a specific type. For example:
+ ///
+ ///
+ ///
+ /// new FileFilter[]
+ /// {
+ /// new FileFiler { Name = "Images", Extensions = new string[] { "jpg", "png", "gif" } },
+ /// new FileFiler { Name = "Movies", Extensions = new string[] { "mkv", "avi", "mp4" } },
+ /// new FileFiler { Name = "Custom File Type", Extensions= new string[] {"as" } },
+ /// new FileFiler { Name = "All Files", Extensions= new string[] { "*" } }
+ /// }
+ ///
+ ///
+ public FileFilter[] Filters { get; set; }
+
+ ///
+ /// Message to display above text fields.
+ ///
+ public string Message { get; set; }
+
+ ///
+ /// Custom label for the text displayed in front of the filename text field.
+ ///
+ public string NameFieldLabel { get; set; }
+
+ ///
+ /// Show the tags input box, defaults to true.
+ ///
+ public bool ShowsTagField { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/ElectronNET.Host/api/dialog.js b/ElectronNET.Host/api/dialog.js
index 67c9945..7f66ddf 100644
--- a/ElectronNET.Host/api/dialog.js
+++ b/ElectronNET.Host/api/dialog.js
@@ -21,5 +21,20 @@ module.exports = function (socket) {
socket.emit('showOpenDialogComplete', filePaths || []);
});
});
+ socket.on('showSaveDialog', function (browserWindow, options) {
+ var window = electron_1.BrowserWindow.fromId(browserWindow.id);
+ electron_1.dialog.showSaveDialog(window, options, function (filename) {
+ socket.emit('showSaveDialogComplete', filename || '');
+ });
+ });
+ socket.on('showErrorBox', function (title, content) {
+ electron_1.dialog.showErrorBox(title, content);
+ });
+ socket.on('showCertificateTrustDialog', function (browserWindow, options) {
+ var window = electron_1.BrowserWindow.fromId(browserWindow.id);
+ electron_1.dialog.showCertificateTrustDialog(window, options, function () {
+ socket.emit('showCertificateTrustDialogComplete');
+ });
+ });
};
//# sourceMappingURL=dialog.js.map
\ No newline at end of file
diff --git a/ElectronNET.Host/api/dialog.js.map b/ElectronNET.Host/api/dialog.js.map
index 489341c..62bdf50 100644
--- a/ElectronNET.Host/api/dialog.js.map
+++ b/ElectronNET.Host/api/dialog.js.map
@@ -1 +1 @@
-{"version":3,"file":"dialog.js","sourceRoot":"","sources":["dialog.ts"],"names":[],"mappings":";;AAAA,qCAAiD;AAEjD,MAAM,CAAC,OAAO,GAAG,UAAC,MAAuB;IACrC,MAAM,CAAC,EAAE,CAAC,gBAAgB,EAAE,UAAC,aAAa,EAAE,OAAO;QAC/C,EAAE,CAAA,CAAC,IAAI,IAAI,aAAa,CAAC,CAAC,CAAC;YACvB,IAAI,MAAM,GAAG,wBAAa,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;YAEpD,iBAAM,CAAC,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,UAAC,QAAQ,EAAE,eAAe;gBAC7D,MAAM,CAAC,IAAI,CAAC,wBAAwB,EAAE,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC,CAAC;YACvE,CAAC,CAAC,CAAC;QACP,CAAC;QAAC,IAAI,CAAC,CAAC;YACJ,iBAAM,CAAC,cAAc,CAAC,aAAa,EAAE,UAAC,QAAQ,EAAE,eAAe;gBAC3D,MAAM,CAAC,IAAI,CAAC,wBAAwB,EAAE,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC,CAAC;YACvE,CAAC,CAAC,CAAC;QACP,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,gBAAgB,EAAE,UAAC,aAAa,EAAE,OAAO;QAC3C,IAAI,MAAM,GAAG,wBAAa,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;QACpD,iBAAM,CAAC,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,UAAC,SAAS;YAC7C,MAAM,CAAC,IAAI,CAAC,wBAAwB,EAAE,SAAS,IAAI,EAAE,CAAC,CAAC;QAC3D,CAAC,CAAC,CAAC;IACX,CAAC,CAAC,CAAC;AACP,CAAC,CAAA"}
\ No newline at end of file
+{"version":3,"file":"dialog.js","sourceRoot":"","sources":["dialog.ts"],"names":[],"mappings":";;AAAA,qCAAiD;AAEjD,MAAM,CAAC,OAAO,GAAG,UAAC,MAAuB;IACrC,MAAM,CAAC,EAAE,CAAC,gBAAgB,EAAE,UAAC,aAAa,EAAE,OAAO;QAC/C,EAAE,CAAC,CAAC,IAAI,IAAI,aAAa,CAAC,CAAC,CAAC;YACxB,IAAI,MAAM,GAAG,wBAAa,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;YAEpD,iBAAM,CAAC,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,UAAC,QAAQ,EAAE,eAAe;gBAC7D,MAAM,CAAC,IAAI,CAAC,wBAAwB,EAAE,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC,CAAC;YACvE,CAAC,CAAC,CAAC;QACP,CAAC;QAAC,IAAI,CAAC,CAAC;YACJ,iBAAM,CAAC,cAAc,CAAC,aAAa,EAAE,UAAC,QAAQ,EAAE,eAAe;gBAC3D,MAAM,CAAC,IAAI,CAAC,wBAAwB,EAAE,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC,CAAC;YACvE,CAAC,CAAC,CAAC;QACP,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,gBAAgB,EAAE,UAAC,aAAa,EAAE,OAAO;QAC/C,IAAI,MAAM,GAAG,wBAAa,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;QACpD,iBAAM,CAAC,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,UAAC,SAAS;YAC7C,MAAM,CAAC,IAAI,CAAC,wBAAwB,EAAE,SAAS,IAAI,EAAE,CAAC,CAAC;QAC3D,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,gBAAgB,EAAE,UAAC,aAAa,EAAE,OAAO;QAC/C,IAAI,MAAM,GAAG,wBAAa,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;QACpD,iBAAM,CAAC,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,UAAC,QAAQ;YAC5C,MAAM,CAAC,IAAI,CAAC,wBAAwB,EAAE,QAAQ,IAAI,EAAE,CAAC,CAAC;QAC1D,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,cAAc,EAAE,UAAC,KAAK,EAAE,OAAO;QACrC,iBAAM,CAAC,YAAY,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,4BAA4B,EAAE,UAAC,aAAa,EAAE,OAAO;QAC3D,IAAI,MAAM,GAAG,wBAAa,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;QACpD,iBAAM,CAAC,0BAA0B,CAAC,MAAM,EAAE,OAAO,EAAE;YAC/C,MAAM,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC;QACtD,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;AACP,CAAC,CAAA"}
\ No newline at end of file
diff --git a/ElectronNET.Host/api/dialog.ts b/ElectronNET.Host/api/dialog.ts
index ac108ef..6be3fa0 100644
--- a/ElectronNET.Host/api/dialog.ts
+++ b/ElectronNET.Host/api/dialog.ts
@@ -2,7 +2,7 @@ import { BrowserWindow, dialog } from "electron";
module.exports = (socket: SocketIO.Server) => {
socket.on('showMessageBox', (browserWindow, options) => {
- if("id" in browserWindow) {
+ if ("id" in browserWindow) {
var window = BrowserWindow.fromId(browserWindow.id);
dialog.showMessageBox(window, options, (response, checkboxChecked) => {
@@ -16,9 +16,27 @@ module.exports = (socket: SocketIO.Server) => {
});
socket.on('showOpenDialog', (browserWindow, options) => {
- var window = BrowserWindow.fromId(browserWindow.id);
- dialog.showOpenDialog(window, options, (filePaths) => {
- socket.emit('showOpenDialogComplete', filePaths || []);
- });
+ var window = BrowserWindow.fromId(browserWindow.id);
+ dialog.showOpenDialog(window, options, (filePaths) => {
+ socket.emit('showOpenDialogComplete', filePaths || []);
+ });
+ });
+
+ socket.on('showSaveDialog', (browserWindow, options) => {
+ var window = BrowserWindow.fromId(browserWindow.id);
+ dialog.showSaveDialog(window, options, (filename) => {
+ socket.emit('showSaveDialogComplete', filename || '');
+ });
+ });
+
+ socket.on('showErrorBox', (title, content) => {
+ dialog.showErrorBox(title, content);
+ });
+
+ socket.on('showCertificateTrustDialog', (browserWindow, options) => {
+ var window = BrowserWindow.fromId(browserWindow.id);
+ dialog.showCertificateTrustDialog(window, options, () => {
+ socket.emit('showCertificateTrustDialogComplete');
+ });
});
}
\ No newline at end of file