2017-08-18 18:13:15 -07:00
|
|
|
|
/*
|
2019-06-04 17:12:53 -07:00
|
|
|
|
Copyright (c) 2019, Lars Brubaker, John Lewin
|
2017-08-18 18:13:15 -07:00
|
|
|
|
All rights reserved.
|
|
|
|
|
|
|
|
|
|
|
|
Redistribution and use in source and binary forms, with or without
|
|
|
|
|
|
modification, are permitted provided that the following conditions are met:
|
|
|
|
|
|
|
|
|
|
|
|
1. Redistributions of source code must retain the above copyright notice, this
|
|
|
|
|
|
list of conditions and the following disclaimer.
|
|
|
|
|
|
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
|
|
|
|
this list of conditions and the following disclaimer in the documentation
|
|
|
|
|
|
and/or other materials provided with the distribution.
|
|
|
|
|
|
|
|
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
|
|
|
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
|
|
|
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
|
|
|
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
|
|
|
|
|
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
|
|
|
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
|
|
|
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
|
|
|
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
|
|
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
|
|
|
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
|
|
|
|
|
|
|
|
The views and conclusions contained in the software and documentation are those
|
|
|
|
|
|
of the authors and should not be interpreted as representing official policies,
|
|
|
|
|
|
either expressed or implied, of the FreeBSD Project.
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
using System;
|
2017-07-18 18:15:10 -07:00
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.IO;
|
2017-08-11 23:13:19 -07:00
|
|
|
|
using System.Linq;
|
2017-07-18 18:15:10 -07:00
|
|
|
|
using MatterHackers.Agg;
|
2017-08-20 02:34:39 -07:00
|
|
|
|
using MatterHackers.Agg.Platform;
|
2014-01-29 19:09:30 -08:00
|
|
|
|
using MatterHackers.Agg.UI;
|
|
|
|
|
|
using MatterHackers.Localizations;
|
2014-06-19 15:55:20 -07:00
|
|
|
|
using MatterHackers.MatterControl.CustomWidgets;
|
2017-08-09 07:30:07 -07:00
|
|
|
|
using MatterHackers.MatterControl.Library;
|
2017-08-11 23:53:27 -07:00
|
|
|
|
using MatterHackers.MatterControl.Library.Export;
|
2019-03-18 18:06:10 -07:00
|
|
|
|
using MatterHackers.MatterControl.PartPreviewWindow;
|
2014-01-29 19:09:30 -08:00
|
|
|
|
|
|
|
|
|
|
namespace MatterHackers.MatterControl
|
|
|
|
|
|
{
|
2017-11-08 15:56:37 -08:00
|
|
|
|
public class ExportPrintItemPage : DialogPage
|
2015-04-08 15:20:10 -07:00
|
|
|
|
{
|
|
|
|
|
|
private CheckBox showInFolderAfterSave;
|
|
|
|
|
|
|
2017-08-10 21:55:16 -07:00
|
|
|
|
private Dictionary<RadioButton, IExportPlugin> exportPluginButtons;
|
2017-08-09 14:40:48 -07:00
|
|
|
|
|
2019-03-18 18:06:10 -07:00
|
|
|
|
private FlowLayoutWidget validationPanel;
|
2018-09-07 10:25:29 -07:00
|
|
|
|
|
2018-11-12 09:32:08 -08:00
|
|
|
|
public ExportPrintItemPage(IEnumerable<ILibraryItem> libraryItems, bool centerOnBed, PrinterConfig printer)
|
2015-04-08 15:20:10 -07:00
|
|
|
|
{
|
2017-08-23 15:51:29 -07:00
|
|
|
|
this.WindowTitle = "Export File".Localize();
|
2021-03-16 15:37:46 -07:00
|
|
|
|
var exportWholeBed = libraryItems.First().Name == printer?.Bed.Scene.Name;
|
2021-03-14 14:21:39 -07:00
|
|
|
|
if (exportWholeBed)
|
2021-02-25 23:06:42 -08:00
|
|
|
|
{
|
|
|
|
|
|
this.HeaderText = "Export bed to".Localize() + ":";
|
|
|
|
|
|
this.Name = "Export Scene Window";
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
this.HeaderText = "Export selection to".Localize() + ":";
|
|
|
|
|
|
this.Name = "Export Item Window";
|
|
|
|
|
|
}
|
2015-04-08 15:20:10 -07:00
|
|
|
|
|
2017-08-08 20:31:34 -07:00
|
|
|
|
var commonMargin = new BorderDouble(4, 2);
|
|
|
|
|
|
|
2017-08-19 09:50:24 -07:00
|
|
|
|
bool isFirstItem = true;
|
|
|
|
|
|
|
2019-03-18 18:06:10 -07:00
|
|
|
|
// Must be constructed before plugins are initialized
|
|
|
|
|
|
var exportButton = theme.CreateDialogButton("Export".Localize());
|
|
|
|
|
|
validationPanel = new FlowLayoutWidget(FlowDirection.TopToBottom)
|
|
|
|
|
|
{
|
|
|
|
|
|
HAnchor = HAnchor.Stretch,
|
|
|
|
|
|
VAnchor = VAnchor.Fit
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2017-08-09 13:24:49 -07:00
|
|
|
|
// GCode export
|
2018-04-13 18:34:58 -07:00
|
|
|
|
exportPluginButtons = new Dictionary<RadioButton, IExportPlugin>();
|
2017-08-09 13:24:49 -07:00
|
|
|
|
|
2021-03-14 14:21:39 -07:00
|
|
|
|
foreach (IExportPlugin plugin in PluginFinder.CreateInstancesOf<IExportPlugin>().OrderBy(p => p.Priority))
|
2018-04-13 18:34:58 -07:00
|
|
|
|
{
|
|
|
|
|
|
plugin.Initialize(printer);
|
2018-02-13 18:11:01 -08:00
|
|
|
|
|
2018-04-13 18:34:58 -07:00
|
|
|
|
// Skip plugins which are invalid for the current printer
|
|
|
|
|
|
if (!plugin.Enabled)
|
2016-03-17 08:57:58 -07:00
|
|
|
|
{
|
2018-12-05 11:33:49 -08:00
|
|
|
|
if (!string.IsNullOrEmpty(plugin.DisabledReason))
|
2018-11-29 17:35:08 -08:00
|
|
|
|
{
|
|
|
|
|
|
// add a message to let us know why not enabled
|
|
|
|
|
|
var disabledPluginButton = new RadioButton(new RadioImageWidget(plugin.ButtonText, theme.TextColor, plugin.Icon))
|
|
|
|
|
|
{
|
|
|
|
|
|
HAnchor = HAnchor.Left,
|
|
|
|
|
|
Margin = commonMargin,
|
|
|
|
|
|
Cursor = Cursors.Hand,
|
|
|
|
|
|
Name = plugin.ButtonText + " Button",
|
|
|
|
|
|
Enabled = false
|
|
|
|
|
|
};
|
|
|
|
|
|
contentRow.AddChild(disabledPluginButton);
|
2018-12-05 11:33:49 -08:00
|
|
|
|
contentRow.AddChild(new TextWidget("Disabled: {0}".Localize().FormatWith(plugin.DisabledReason), textColor: theme.PrimaryAccentColor)
|
2018-11-29 17:35:08 -08:00
|
|
|
|
{
|
|
|
|
|
|
Margin = new BorderDouble(left: 80),
|
|
|
|
|
|
HAnchor = HAnchor.Left
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
2020-05-25 09:54:50 -07:00
|
|
|
|
|
2018-04-13 18:34:58 -07:00
|
|
|
|
continue;
|
|
|
|
|
|
}
|
2018-02-13 18:11:01 -08:00
|
|
|
|
|
2018-04-13 18:34:58 -07:00
|
|
|
|
// Create export button for each plugin
|
2018-11-03 09:13:07 -07:00
|
|
|
|
var pluginButton = new RadioButton(new RadioImageWidget(plugin.ButtonText, theme.TextColor, plugin.Icon))
|
2018-04-13 18:34:58 -07:00
|
|
|
|
{
|
|
|
|
|
|
HAnchor = HAnchor.Left,
|
|
|
|
|
|
Margin = commonMargin,
|
|
|
|
|
|
Cursor = Cursors.Hand,
|
|
|
|
|
|
Name = plugin.ButtonText + " Button"
|
|
|
|
|
|
};
|
2018-11-03 10:12:27 -07:00
|
|
|
|
contentRow.AddChild(pluginButton);
|
2018-02-13 18:30:17 -08:00
|
|
|
|
|
2019-03-18 18:06:10 -07:00
|
|
|
|
if (plugin is GCodeExport)
|
|
|
|
|
|
{
|
|
|
|
|
|
var gcodeExportButton = pluginButton;
|
|
|
|
|
|
gcodeExportButton.CheckedStateChanged += (s, e) =>
|
|
|
|
|
|
{
|
2021-01-29 16:44:47 -08:00
|
|
|
|
validationPanel.CloseChildren();
|
2019-03-18 18:06:10 -07:00
|
|
|
|
|
|
|
|
|
|
if (gcodeExportButton.Checked)
|
|
|
|
|
|
{
|
2022-03-28 11:49:29 -07:00
|
|
|
|
var errors = new List<ValidationError>();
|
|
|
|
|
|
printer.ValidateSettings(errors, validatePrintBed: false);
|
2019-03-18 18:06:10 -07:00
|
|
|
|
|
|
|
|
|
|
exportButton.Enabled = !errors.Any(item => item.ErrorLevel == ValidationErrorLevel.Error);
|
|
|
|
|
|
|
|
|
|
|
|
validationPanel.AddChild(
|
|
|
|
|
|
new ValidationErrorsPanel(
|
|
|
|
|
|
errors,
|
|
|
|
|
|
AppContext.Theme)
|
|
|
|
|
|
{
|
|
|
|
|
|
HAnchor = HAnchor.Stretch
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
exportButton.Enabled = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-04-13 18:34:58 -07:00
|
|
|
|
if (isFirstItem)
|
|
|
|
|
|
{
|
|
|
|
|
|
pluginButton.Checked = true;
|
|
|
|
|
|
isFirstItem = false;
|
|
|
|
|
|
}
|
2017-08-19 09:50:24 -07:00
|
|
|
|
|
2018-04-13 18:34:58 -07:00
|
|
|
|
if (plugin is IExportWithOptions pluginWithOptions)
|
|
|
|
|
|
{
|
2023-03-11 10:56:32 -08:00
|
|
|
|
var optionPanel = pluginWithOptions.GetOptionsPanel(libraryItems, pluginButton);
|
2018-04-13 18:34:58 -07:00
|
|
|
|
if (optionPanel != null)
|
2017-08-11 23:13:19 -07:00
|
|
|
|
{
|
2018-04-13 18:34:58 -07:00
|
|
|
|
optionPanel.HAnchor = HAnchor.Stretch;
|
|
|
|
|
|
optionPanel.VAnchor = VAnchor.Fit;
|
2018-11-03 10:12:27 -07:00
|
|
|
|
contentRow.AddChild(optionPanel);
|
2017-03-06 17:32:46 -08:00
|
|
|
|
}
|
2015-04-08 15:20:10 -07:00
|
|
|
|
}
|
2018-04-13 18:34:58 -07:00
|
|
|
|
|
|
|
|
|
|
exportPluginButtons.Add(pluginButton, plugin);
|
2015-04-08 15:20:10 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2019-03-18 18:06:10 -07:00
|
|
|
|
ContentRow.AddChild(new VerticalSpacer());
|
|
|
|
|
|
contentRow.AddChild(validationPanel);
|
2015-04-08 15:20:10 -07:00
|
|
|
|
|
|
|
|
|
|
// TODO: make this work on the mac and then delete this if
|
2017-08-20 02:34:39 -07:00
|
|
|
|
if (AggContext.OperatingSystem == OSType.Windows
|
|
|
|
|
|
|| AggContext.OperatingSystem == OSType.X11)
|
2015-04-08 15:20:10 -07:00
|
|
|
|
{
|
2018-11-03 09:13:07 -07:00
|
|
|
|
showInFolderAfterSave = new CheckBox("Show file in folder after save".Localize(), theme.TextColor, 10)
|
2017-08-08 20:37:13 -07:00
|
|
|
|
{
|
|
|
|
|
|
HAnchor = HAnchor.Left,
|
|
|
|
|
|
Cursor = Cursors.Hand
|
|
|
|
|
|
};
|
2018-11-03 10:12:27 -07:00
|
|
|
|
contentRow.AddChild(showInFolderAfterSave);
|
2015-04-08 15:20:10 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-08-30 13:41:49 -07:00
|
|
|
|
exportButton.Name = "Export Button";
|
2017-08-09 07:45:26 -07:00
|
|
|
|
exportButton.Click += (s, e) =>
|
|
|
|
|
|
{
|
2017-08-10 21:55:16 -07:00
|
|
|
|
IExportPlugin activePlugin = null;
|
2017-08-09 13:24:49 -07:00
|
|
|
|
|
2017-08-11 23:13:19 -07:00
|
|
|
|
// Loop over all plugin buttons, break on the first checked item found
|
2019-05-24 10:19:45 -07:00
|
|
|
|
foreach (var button in this.exportPluginButtons.Keys)
|
2017-08-09 11:14:38 -07:00
|
|
|
|
{
|
2017-08-11 23:13:19 -07:00
|
|
|
|
if (button.Checked)
|
2017-08-09 13:24:49 -07:00
|
|
|
|
{
|
2017-08-11 23:13:19 -07:00
|
|
|
|
activePlugin = exportPluginButtons[button];
|
|
|
|
|
|
break;
|
2017-08-09 13:24:49 -07:00
|
|
|
|
}
|
2017-08-11 23:13:19 -07:00
|
|
|
|
}
|
2017-08-09 13:24:49 -07:00
|
|
|
|
|
2017-08-11 23:13:19 -07:00
|
|
|
|
// Early exit if no plugin radio button is selected
|
|
|
|
|
|
if (activePlugin == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
2017-08-09 13:24:49 -07:00
|
|
|
|
}
|
2017-08-09 07:49:50 -07:00
|
|
|
|
|
2019-09-25 10:51:50 -07:00
|
|
|
|
DoExport(libraryItems, printer, activePlugin, centerOnBed, showInFolderAfterSave?.Checked == true);
|
2017-08-11 23:13:19 -07:00
|
|
|
|
|
2017-08-09 07:45:26 -07:00
|
|
|
|
this.Parent.CloseOnIdle();
|
2019-05-24 10:19:45 -07:00
|
|
|
|
};
|
2017-08-11 23:53:27 -07:00
|
|
|
|
|
2019-05-24 10:19:45 -07:00
|
|
|
|
this.AddPageAction(exportButton);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static void DoExport(IEnumerable<ILibraryItem> libraryItems, PrinterConfig printer, IExportPlugin exportPlugin, bool centerOnBed = false, bool showFile = false)
|
|
|
|
|
|
{
|
2019-06-04 17:12:53 -07:00
|
|
|
|
string targetExtension = exportPlugin.FileExtension;
|
2019-05-24 10:19:45 -07:00
|
|
|
|
|
|
|
|
|
|
if (exportPlugin is FolderExport)
|
|
|
|
|
|
{
|
2017-08-09 07:45:26 -07:00
|
|
|
|
UiThread.RunOnIdle(() =>
|
|
|
|
|
|
{
|
2019-05-24 10:19:45 -07:00
|
|
|
|
AggContext.FileDialogs.SelectFolderDialog(
|
2020-07-13 18:08:09 -07:00
|
|
|
|
new SelectFolderDialogParams("Select Location To Export Files")
|
|
|
|
|
|
{
|
2017-08-09 11:07:03 -07:00
|
|
|
|
ActionButtonLabel = "Export".Localize(),
|
2019-05-24 10:19:45 -07:00
|
|
|
|
Title = ApplicationController.Instance.ProductName + " - " + "Select A Folder".Localize()
|
2017-08-09 07:45:26 -07:00
|
|
|
|
},
|
2020-07-13 18:08:09 -07:00
|
|
|
|
(openParams) =>
|
|
|
|
|
|
{
|
2019-05-24 10:19:45 -07:00
|
|
|
|
ApplicationController.Instance.Tasks.Execute(
|
|
|
|
|
|
"Saving".Localize() + "...",
|
|
|
|
|
|
printer,
|
2021-12-05 22:01:50 -08:00
|
|
|
|
async (reporter, cancellationTokenSource) =>
|
2020-07-13 18:08:09 -07:00
|
|
|
|
{
|
2019-05-24 10:19:45 -07:00
|
|
|
|
string path = openParams.FolderPath;
|
2020-07-13 18:08:09 -07:00
|
|
|
|
if (!string.IsNullOrEmpty(path))
|
|
|
|
|
|
{
|
2021-12-05 22:01:50 -08:00
|
|
|
|
await exportPlugin.Generate(libraryItems, path, reporter, cancellationTokenSource.Token);
|
2019-05-24 10:19:45 -07:00
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-03-11 12:17:09 -08:00
|
|
|
|
if (exportPlugin is ExportStlToExecutable)
|
|
|
|
|
|
{
|
|
|
|
|
|
ApplicationController.Instance.Tasks.Execute(
|
|
|
|
|
|
"Saving".Localize() + "...",
|
|
|
|
|
|
printer,
|
|
|
|
|
|
async (reporter, cancellationTokenSource) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
await exportPlugin.Generate(libraryItems, null, reporter, cancellationTokenSource.Token);
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-05-24 10:19:45 -07:00
|
|
|
|
UiThread.RunOnIdle(() =>
|
|
|
|
|
|
{
|
|
|
|
|
|
string title = ApplicationController.Instance.ProductName + " - " + "Export File".Localize();
|
|
|
|
|
|
string workspaceName = "Workspace " + DateTime.Now.ToString("yyyy-MM-dd HH_mm_ss");
|
|
|
|
|
|
AggContext.FileDialogs.SaveFileDialog(
|
2019-06-04 17:12:53 -07:00
|
|
|
|
new SaveFileDialogParams(exportPlugin.ExtensionFilter)
|
2019-05-24 10:19:45 -07:00
|
|
|
|
{
|
|
|
|
|
|
Title = title,
|
|
|
|
|
|
ActionButtonLabel = "Export".Localize(),
|
|
|
|
|
|
FileName = Path.GetFileNameWithoutExtension(libraryItems.FirstOrDefault()?.Name ?? workspaceName)
|
|
|
|
|
|
},
|
|
|
|
|
|
(saveParams) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
string savePath = saveParams.FileName;
|
|
|
|
|
|
|
|
|
|
|
|
if (!string.IsNullOrEmpty(savePath))
|
2017-08-09 07:45:26 -07:00
|
|
|
|
{
|
2019-05-24 10:19:45 -07:00
|
|
|
|
ApplicationController.Instance.Tasks.Execute(
|
|
|
|
|
|
"Exporting".Localize() + "...",
|
|
|
|
|
|
printer,
|
2021-12-05 22:01:50 -08:00
|
|
|
|
async (reporter, cancellationTokenSource) =>
|
2019-05-24 10:19:45 -07:00
|
|
|
|
{
|
|
|
|
|
|
string extension = Path.GetExtension(savePath);
|
|
|
|
|
|
if (!extension.Equals(targetExtension, StringComparison.OrdinalIgnoreCase))
|
|
|
|
|
|
{
|
|
|
|
|
|
savePath += targetExtension;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
List<ValidationError> exportErrors = null;
|
|
|
|
|
|
|
|
|
|
|
|
if (exportPlugin != null)
|
2017-08-09 11:07:03 -07:00
|
|
|
|
{
|
2019-05-24 10:19:45 -07:00
|
|
|
|
if (exportPlugin is GCodeExport gCodeExport)
|
2018-08-17 17:49:41 -07:00
|
|
|
|
{
|
2019-05-24 10:19:45 -07:00
|
|
|
|
gCodeExport.CenterOnBed = centerOnBed;
|
2018-08-17 17:49:41 -07:00
|
|
|
|
}
|
2017-08-09 11:07:03 -07:00
|
|
|
|
|
2021-12-05 22:01:50 -08:00
|
|
|
|
exportErrors = await exportPlugin.Generate(libraryItems, savePath, reporter, cancellationTokenSource.Token);
|
2019-05-24 10:19:45 -07:00
|
|
|
|
}
|
2017-08-09 11:07:03 -07:00
|
|
|
|
|
2019-05-24 10:19:45 -07:00
|
|
|
|
if (exportErrors == null || exportErrors.Count == 0)
|
|
|
|
|
|
{
|
2018-08-17 17:49:41 -07:00
|
|
|
|
{
|
2019-05-24 10:19:45 -07:00
|
|
|
|
if (AggContext.OperatingSystem == OSType.Windows || AggContext.OperatingSystem == OSType.X11)
|
2018-09-07 10:25:29 -07:00
|
|
|
|
{
|
2020-07-03 09:33:51 -07:00
|
|
|
|
if (showFile)
|
|
|
|
|
|
{
|
2019-05-24 10:19:45 -07:00
|
|
|
|
AggContext.FileDialogs.ShowFileInFolder(savePath);
|
|
|
|
|
|
}
|
2018-09-07 10:25:29 -07:00
|
|
|
|
}
|
2018-08-17 17:49:41 -07:00
|
|
|
|
}
|
2019-05-24 10:19:45 -07:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
bool showGenerateErrors = !(exportPlugin is GCodeExport);
|
2019-03-18 18:06:10 -07:00
|
|
|
|
|
2019-06-04 17:12:53 -07:00
|
|
|
|
// Only show errors in Generate if not GCodeExport - GCodeExport shows validation errors before Generate call
|
|
|
|
|
|
if (showGenerateErrors)
|
|
|
|
|
|
{
|
|
|
|
|
|
ApplicationController.Instance.ShowValidationErrors("Export Error".Localize(), exportErrors);
|
|
|
|
|
|
}
|
2019-05-24 10:19:45 -07:00
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
});
|
2017-08-09 12:05:17 -07:00
|
|
|
|
}
|
2015-04-08 15:20:10 -07:00
|
|
|
|
}
|
2017-11-16 07:50:42 -08:00
|
|
|
|
}
|