Merge pull request #4392 from jlewin/master
Add DialogPage to control import/calibration/blacklist behavior
This commit is contained in:
commit
9ef792ff9b
12 changed files with 430 additions and 140 deletions
188
MatterControlLib/Library/Widgets/CloneSettingsPage.cs
Normal file
188
MatterControlLib/Library/Widgets/CloneSettingsPage.cs
Normal file
|
|
@ -0,0 +1,188 @@
|
|||
/*
|
||||
Copyright (c) 2019, John Lewin
|
||||
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.Collections.Generic;
|
||||
using System.IO;
|
||||
using MatterHackers.Agg;
|
||||
using MatterHackers.Agg.Platform;
|
||||
using MatterHackers.Agg.UI;
|
||||
using MatterHackers.Localizations;
|
||||
using MatterHackers.MatterControl.CustomWidgets;
|
||||
using MatterHackers.MatterControl.SlicerConfiguration;
|
||||
|
||||
namespace MatterHackers.MatterControl.PrintLibrary
|
||||
{
|
||||
|
||||
public class CloneSettingsPage : DialogPage
|
||||
{
|
||||
public CloneSettingsPage()
|
||||
{
|
||||
this.WindowTitle = "Import Printer".Localize();
|
||||
this.HeaderText = "Import Printer".Localize() + ":";
|
||||
this.Name = "Import Printer Window";
|
||||
|
||||
var commonMargin = new BorderDouble(4, 2);
|
||||
|
||||
contentRow.AddChild(new TextWidget("File Path".Localize(), pointSize: theme.DefaultFontSize, textColor: theme.TextColor));
|
||||
|
||||
var pathRow = new FlowLayoutWidget()
|
||||
{
|
||||
HAnchor = HAnchor.Stretch,
|
||||
VAnchor = VAnchor.Fit,
|
||||
};
|
||||
contentRow.AddChild(pathRow);
|
||||
|
||||
TextButton importButton = null;
|
||||
|
||||
var textEditWidget = new MHTextEditWidget("", theme)
|
||||
{
|
||||
HAnchor = HAnchor.Stretch,
|
||||
VAnchor = VAnchor.Center
|
||||
};
|
||||
textEditWidget.ActualTextEditWidget.EditComplete += (s, e) =>
|
||||
{
|
||||
importButton.Enabled = !string.IsNullOrEmpty(textEditWidget.Text)
|
||||
&& File.Exists(textEditWidget.Text);
|
||||
};
|
||||
pathRow.AddChild(textEditWidget);
|
||||
|
||||
// Must come before pathButton.Click definition
|
||||
RadioButton copyAndCalibrateOption = null;
|
||||
|
||||
var openButton = new IconButton(AggContext.StaticData.LoadIcon("fa-folder-open_16.png", 16, 16, theme.InvertIcons), theme)
|
||||
{
|
||||
BackgroundColor = theme.MinimalShade,
|
||||
Margin = new BorderDouble(left: 8)
|
||||
};
|
||||
openButton.Click += (s, e) =>
|
||||
{
|
||||
AggContext.FileDialogs.OpenFileDialog(
|
||||
new OpenFileDialogParams("settings files|*.ini;*.printer;*.slice"),
|
||||
(result) =>
|
||||
{
|
||||
if (!string.IsNullOrEmpty(result.FileName)
|
||||
&& File.Exists(result.FileName))
|
||||
{
|
||||
textEditWidget.Text = result.FileName;
|
||||
}
|
||||
|
||||
importButton.Enabled = !string.IsNullOrEmpty(textEditWidget.Text)
|
||||
&& File.Exists(textEditWidget.Text);
|
||||
});
|
||||
};
|
||||
pathRow.AddChild(openButton);
|
||||
|
||||
var exactCloneColumn = new FlowLayoutWidget(FlowDirection.TopToBottom)
|
||||
{
|
||||
HAnchor = HAnchor.Stretch,
|
||||
VAnchor = VAnchor.Fit,
|
||||
Margin = new BorderDouble(top: 15)
|
||||
};
|
||||
contentRow.AddChild(exactCloneColumn);
|
||||
|
||||
var siblingList = new List<GuiWidget>();
|
||||
|
||||
var exactCloneOption = new RadioButton(new RadioButtonViewText("Exact clone".Localize(), theme.TextColor, fontSize: theme.DefaultFontSize))
|
||||
{
|
||||
HAnchor = HAnchor.Left,
|
||||
Margin = commonMargin,
|
||||
Cursor = Cursors.Hand,
|
||||
Name = "Exact Clone Button",
|
||||
Checked = true,
|
||||
SiblingRadioButtonList = siblingList
|
||||
};
|
||||
exactCloneColumn.AddChild(exactCloneOption);
|
||||
siblingList.Add(exactCloneOption);
|
||||
|
||||
var exactCloneSummary = new WrappedTextWidget("Copy all settings including hardware calibration".Localize(), pointSize: theme.DefaultFontSize - 1, textColor: theme.TextColor)
|
||||
{
|
||||
HAnchor = HAnchor.Stretch,
|
||||
Margin = new BorderDouble(left: 30, bottom: 10, top: 4),
|
||||
};
|
||||
exactCloneColumn.AddChild(exactCloneSummary);
|
||||
|
||||
var copySettingsColumn = new FlowLayoutWidget(FlowDirection.TopToBottom)
|
||||
{
|
||||
HAnchor = HAnchor.Stretch,
|
||||
VAnchor = VAnchor.Fit
|
||||
};
|
||||
contentRow.AddChild(copySettingsColumn);
|
||||
|
||||
// Create export button for each plugin
|
||||
copyAndCalibrateOption = new RadioButton(new RadioButtonViewText("Copy and recalibrate".Localize(), theme.TextColor, fontSize: theme.DefaultFontSize))
|
||||
{
|
||||
HAnchor = HAnchor.Left,
|
||||
Margin = commonMargin,
|
||||
Cursor = Cursors.Hand,
|
||||
Name = "Copy and Calibrate Button",
|
||||
SiblingRadioButtonList = siblingList
|
||||
};
|
||||
copySettingsColumn.AddChild(copyAndCalibrateOption);
|
||||
siblingList.Add(copyAndCalibrateOption);
|
||||
|
||||
string summary = string.Format(
|
||||
"{0}\r\n{1}",
|
||||
"Copy everything but hardware specific calibration settings".Localize(),
|
||||
"Ideal for cloning settings across different physical printers".Localize());
|
||||
|
||||
var copySummary = new WrappedTextWidget(summary, pointSize: theme.DefaultFontSize - 1, textColor: theme.TextColor)
|
||||
{
|
||||
HAnchor = HAnchor.Stretch,
|
||||
Margin = new BorderDouble(left: 30, bottom: 10, top: 4)
|
||||
};
|
||||
copySettingsColumn.AddChild(copySummary);
|
||||
|
||||
importButton = theme.CreateDialogButton("Import".Localize());
|
||||
importButton.Enabled = false;
|
||||
importButton.Name = "Import Button";
|
||||
importButton.Click += (s, e) =>
|
||||
{
|
||||
var filePath = textEditWidget.Text;
|
||||
|
||||
if (ProfileManager.ImportFromExisting(filePath, clearBlackList: copyAndCalibrateOption.Checked))
|
||||
{
|
||||
string importPrinterSuccessMessage = "You have successfully imported a new printer profile. You can find '{0}' in your list of available printers.".Localize();
|
||||
this.DialogWindow.ChangeToPage(
|
||||
new ImportSucceededPage(
|
||||
importPrinterSuccessMessage.FormatWith(Path.GetFileNameWithoutExtension(filePath))));
|
||||
}
|
||||
else
|
||||
{
|
||||
StyledMessageBox.ShowMessageBox(
|
||||
string.Format(
|
||||
"Oops! Settings file '{0}' did not contain any settings we could import.".Localize(),
|
||||
Path.GetFileName(filePath)),
|
||||
"Unable to Import".Localize());
|
||||
}
|
||||
};
|
||||
|
||||
this.AddPageAction(importButton);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -49,7 +49,7 @@ namespace MatterHackers.MatterControl.PrintLibrary
|
|||
private EventHandler unregisterEvents;
|
||||
|
||||
public HardwareTreeView(ThemeConfig theme)
|
||||
: base (theme)
|
||||
: base(theme)
|
||||
{
|
||||
rootColumn = new FlowLayoutWidget(FlowDirection.TopToBottom)
|
||||
{
|
||||
|
|
@ -109,28 +109,7 @@ namespace MatterHackers.MatterControl.PrintLibrary
|
|||
};
|
||||
importPrinter.Click += (s, e) => UiThread.RunOnIdle(() =>
|
||||
{
|
||||
AggContext.FileDialogs.OpenFileDialog(
|
||||
new OpenFileDialogParams(
|
||||
"settings files|*.ini;*.printer;*.slice"),
|
||||
(result) =>
|
||||
{
|
||||
if (!string.IsNullOrEmpty(result.FileName)
|
||||
&& File.Exists(result.FileName))
|
||||
{
|
||||
//simpleTabs.RemoveTab(simpleTabs.ActiveTab);
|
||||
if (ProfileManager.ImportFromExisting(result.FileName))
|
||||
{
|
||||
string importPrinterSuccessMessage = "You have successfully imported a new printer profile. You can find '{0}' in your list of available printers.".Localize();
|
||||
DialogWindow.Show(
|
||||
new ImportSucceeded(
|
||||
importPrinterSuccessMessage.FormatWith(Path.GetFileNameWithoutExtension(result.FileName))));
|
||||
}
|
||||
else
|
||||
{
|
||||
StyledMessageBox.ShowMessageBox("Oops! Settings file '{0}' did not contain any settings we could import.".Localize().FormatWith(Path.GetFileName(result.FileName)), "Unable to Import".Localize());
|
||||
}
|
||||
}
|
||||
});
|
||||
DialogWindow.Show(new CloneSettingsPage());
|
||||
});
|
||||
mainRow.AddChild(importPrinter);
|
||||
|
||||
|
|
@ -161,6 +140,7 @@ namespace MatterHackers.MatterControl.PrintLibrary
|
|||
}, ref unregisterEvents);
|
||||
}
|
||||
|
||||
|
||||
public static void CreatePrinterProfilesTree(TreeNode printersNode, ThemeConfig theme)
|
||||
{
|
||||
if (printersNode == null)
|
||||
|
|
@ -170,7 +150,7 @@ namespace MatterHackers.MatterControl.PrintLibrary
|
|||
|
||||
printersNode.Nodes.Clear();
|
||||
|
||||
//Add the menu items to the menu itself
|
||||
// Add the menu items to the menu itself
|
||||
foreach (var printer in ProfileManager.Instance.ActiveProfiles.OrderBy(p => p.Name))
|
||||
{
|
||||
var printerNode = new TreeNode(theme)
|
||||
|
|
@ -200,7 +180,7 @@ namespace MatterHackers.MatterControl.PrintLibrary
|
|||
|
||||
printersNode.Nodes.Clear();
|
||||
|
||||
//Add the menu items to the menu itself
|
||||
// Add the menu items to the menu itself
|
||||
foreach (var printer in ApplicationController.Instance.ActivePrinters)
|
||||
{
|
||||
string printerName = printer.Settings.GetValue(SettingsKey.printer_name);
|
||||
|
|
|
|||
|
|
@ -2853,6 +2853,7 @@ You will then need to logout and log back in to the computer for the changes to
|
|||
|
||||
public void Dispose()
|
||||
{
|
||||
TerminalLog.Dispose();
|
||||
Disposed?.Invoke(this, null);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
Copyright (c) 2019, Lars Brubaker, John Lewin
|
||||
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.
|
||||
*/
|
||||
|
||||
namespace MatterHackers.MatterControl
|
||||
{
|
||||
public class TerminalLine
|
||||
{
|
||||
public TerminalLine(string line, MessageDirection direction)
|
||||
{
|
||||
this.Line = line;
|
||||
this.Direction = direction;
|
||||
}
|
||||
|
||||
public string Line { get; }
|
||||
|
||||
public MessageDirection Direction { get; }
|
||||
|
||||
public enum MessageDirection
|
||||
{
|
||||
ToPrinter,
|
||||
ToTerminal,
|
||||
FromPrinter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014, Lars Brubaker
|
||||
Copyright (c) 2019, Lars Brubaker, John Lewin
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
|
@ -27,31 +27,30 @@ of the authors and should not be interpreted as representing official policies,
|
|||
either expressed or implied, of the FreeBSD Project.
|
||||
*/
|
||||
|
||||
using MatterHackers.Agg;
|
||||
using MatterHackers.Localizations;
|
||||
using MatterHackers.MatterControl.PrinterCommunication;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using MatterHackers.Localizations;
|
||||
using MatterHackers.MatterControl.PrinterCommunication;
|
||||
|
||||
namespace MatterHackers.MatterControl
|
||||
{
|
||||
public class TerminalLog
|
||||
public class TerminalLog : IDisposable
|
||||
{
|
||||
private static readonly bool Is32Bit = IntPtr.Size == 4;
|
||||
|
||||
public List<(string line, bool output)> PrinterLines = new List<(string line, bool output)>();
|
||||
|
||||
public event EventHandler<(string line, bool output)> HasChanged;
|
||||
private int maxLinesToBuffer = int.MaxValue - 1;
|
||||
|
||||
private PrinterConnection printerConnection;
|
||||
|
||||
public TerminalLog(PrinterConnection printerConnection)
|
||||
{
|
||||
// Register event listeners
|
||||
printerConnection.ConnectionFailed += Instance_ConnectionFailed;
|
||||
printerConnection.Disposed += (s, e) => printerConnection.ConnectionFailed -= Instance_ConnectionFailed;
|
||||
|
||||
printerConnection.LineReceived += Printer_LineReceived;
|
||||
printerConnection.LineSent += Printer_LineSent;
|
||||
|
||||
this.printerConnection = printerConnection;
|
||||
|
||||
if (Is32Bit)
|
||||
{
|
||||
// About 10 megs worth. Average line length in gcode file is about 14 and we store strings as chars (16 bit) so 450,000 lines.
|
||||
|
|
@ -59,50 +58,58 @@ namespace MatterHackers.MatterControl
|
|||
}
|
||||
}
|
||||
|
||||
private void OnHasChanged((string line, bool output) lineData)
|
||||
public event EventHandler<TerminalLine> LineAdded;
|
||||
|
||||
public event EventHandler LogCleared;
|
||||
|
||||
public List<TerminalLine> PrinterLines { get; } = new List<TerminalLine>();
|
||||
|
||||
private void OnLineAdded(TerminalLine terminalLine)
|
||||
{
|
||||
HasChanged?.Invoke(this, lineData);
|
||||
PrinterLines.Add(terminalLine);
|
||||
|
||||
LineAdded?.Invoke(this, terminalLine);
|
||||
|
||||
if (PrinterLines.Count > maxLinesToBuffer)
|
||||
{
|
||||
Clear();
|
||||
this.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
private void Printer_LineReceived(object sender, string line)
|
||||
{
|
||||
PrinterLines.Add((line, false));
|
||||
OnHasChanged((line, false));
|
||||
this.OnLineAdded(
|
||||
new TerminalLine(
|
||||
line,
|
||||
TerminalLine.MessageDirection.FromPrinter));
|
||||
}
|
||||
|
||||
private void Printer_LineSent(object sender, string line)
|
||||
{
|
||||
PrinterLines.Add((line, true));
|
||||
OnHasChanged((line, true));
|
||||
this.OnLineAdded(
|
||||
new TerminalLine(
|
||||
line,
|
||||
TerminalLine.MessageDirection.ToPrinter));
|
||||
}
|
||||
|
||||
public void WriteLine(string line)
|
||||
{
|
||||
this.WriteLine((line, true));
|
||||
}
|
||||
|
||||
public void WriteLine((string line, bool output) lineData)
|
||||
{
|
||||
PrinterLines.Add(lineData);
|
||||
OnHasChanged(lineData);
|
||||
this.OnLineAdded(
|
||||
new TerminalLine(
|
||||
line,
|
||||
TerminalLine.MessageDirection.ToTerminal));
|
||||
}
|
||||
|
||||
private void Instance_ConnectionFailed(object sender, EventArgs e)
|
||||
{
|
||||
OnHasChanged((null, true));
|
||||
|
||||
if (e is ConnectFailedEventArgs args)
|
||||
{
|
||||
string message;
|
||||
|
||||
switch(args.Reason)
|
||||
switch (args.Reason)
|
||||
{
|
||||
case ConnectionFailure.AlreadyConnected:
|
||||
message = "You can only connect when not currently connected.".Localize();
|
||||
message = "You can only connect when not currently connected".Localize();
|
||||
break;
|
||||
case ConnectionFailure.UnsupportedBaudRate:
|
||||
message = "Unsupported Baud Rate".Localize();
|
||||
|
|
@ -113,27 +120,38 @@ namespace MatterHackers.MatterControl
|
|||
case ConnectionFailure.PortNotFound:
|
||||
message = "Port not found".Localize();
|
||||
break;
|
||||
case ConnectionFailure.PortUnavailable:
|
||||
message = "Port not available".Localize();
|
||||
break;
|
||||
default:
|
||||
message = "Unknown Reason".Localize();
|
||||
break;
|
||||
}
|
||||
|
||||
PrinterLines.Add(("Connection Failed".Localize() + ": " + message, true));
|
||||
this.WriteLine("Connection Failed".Localize() + ": " + message);
|
||||
}
|
||||
|
||||
StringEventArgs eventArgs = new StringEventArgs("Lost connection to printer.");
|
||||
PrinterLines.Add((eventArgs.Data, true));
|
||||
OnHasChanged((eventArgs.Data, true));
|
||||
this.WriteLine("Lost connection to printer");
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
lock(PrinterLines)
|
||||
lock (PrinterLines)
|
||||
{
|
||||
PrinterLines.Clear();
|
||||
}
|
||||
|
||||
OnHasChanged((null, true));
|
||||
this.LogCleared?.Invoke(this, null);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
// Unregister event listeners
|
||||
printerConnection.ConnectionFailed -= Instance_ConnectionFailed;
|
||||
printerConnection.LineReceived -= Printer_LineReceived;
|
||||
printerConnection.LineSent -= Printer_LineSent;
|
||||
|
||||
printerConnection = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -46,8 +46,6 @@ namespace MatterHackers.MatterControl
|
|||
private MHTextEditWidget manualCommandTextEdit;
|
||||
private TextScrollWidget textScrollWidget;
|
||||
private PrinterConfig printer;
|
||||
private string writeFailedWaring = "WARNING: Write Failed!".Localize();
|
||||
private string cantAccessPath = "Can't access '{0}'.".Localize();
|
||||
|
||||
private List<string> commandHistory = new List<string>();
|
||||
private int commandHistoryIndex = 0;
|
||||
|
|
@ -110,8 +108,8 @@ namespace MatterHackers.MatterControl
|
|||
|
||||
textScrollWidget.LineFilterFunction = lineData =>
|
||||
{
|
||||
var line = lineData.line;
|
||||
var output = lineData.output;
|
||||
var line = lineData.Line;
|
||||
var output = lineData.Direction == TerminalLine.MessageDirection.ToPrinter;
|
||||
var outputLine = line;
|
||||
|
||||
var lineWithoutChecksum = GCodeFile.GetLineWithoutChecksum(line);
|
||||
|
|
@ -156,13 +154,17 @@ namespace MatterHackers.MatterControl
|
|||
|
||||
if (UserSettings.Instance.Fields.GetBool(UserSettingsKey.TerminalShowInputOutputMarks, true))
|
||||
{
|
||||
if (lineData.output)
|
||||
switch (lineData.Direction)
|
||||
{
|
||||
outputLine = "->" + outputLine;
|
||||
}
|
||||
else
|
||||
{
|
||||
outputLine = "<-" + outputLine;
|
||||
case TerminalLine.MessageDirection.FromPrinter:
|
||||
outputLine = "→ " + outputLine;
|
||||
break;
|
||||
case TerminalLine.MessageDirection.ToPrinter:
|
||||
outputLine = "← " + outputLine;
|
||||
break;
|
||||
case TerminalLine.MessageDirection.ToTerminal:
|
||||
outputLine = "* " + outputLine;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -267,6 +269,7 @@ namespace MatterHackers.MatterControl
|
|||
if (!string.IsNullOrEmpty(saveParams.FileName))
|
||||
{
|
||||
string filePathToSave = saveParams.FileName;
|
||||
|
||||
if (filePathToSave != null && filePathToSave != "")
|
||||
{
|
||||
try
|
||||
|
|
@ -277,10 +280,10 @@ namespace MatterHackers.MatterControl
|
|||
{
|
||||
Debug.Print(ex.Message);
|
||||
|
||||
printer.Connection.TerminalLog.PrinterLines.Add(("", true));
|
||||
printer.Connection.TerminalLog.PrinterLines.Add((writeFailedWaring, true));
|
||||
printer.Connection.TerminalLog.PrinterLines.Add((cantAccessPath.FormatWith(filePathToSave), true));
|
||||
printer.Connection.TerminalLog.PrinterLines.Add(("", true));
|
||||
printer.Connection.TerminalLog.WriteLine("");
|
||||
printer.Connection.TerminalLog.WriteLine("WARNING: Write Failed!".Localize());
|
||||
printer.Connection.TerminalLog.WriteLine("Can't access".Localize() + " " + filePathToSave);
|
||||
printer.Connection.TerminalLog.WriteLine("");
|
||||
|
||||
UiThread.RunOnIdle(() =>
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2018, Lars Brubaker, John Lewin
|
||||
Copyright (c) 2019, Lars Brubaker, John Lewin
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
|
@ -39,28 +39,31 @@ namespace MatterHackers.MatterControl
|
|||
{
|
||||
public class TextScrollWidget : GuiWidget
|
||||
{
|
||||
object locker = new object();
|
||||
private object locker = new object();
|
||||
|
||||
private Func<(string line, bool output), string> _lineFilterFunction;
|
||||
public Func<(string line, bool output), string> LineFilterFunction
|
||||
{
|
||||
get => _lineFilterFunction;
|
||||
set
|
||||
{
|
||||
_lineFilterFunction = value;
|
||||
RebuildFilteredList();
|
||||
}
|
||||
}
|
||||
|
||||
private List<(string line, bool output)> allSourceLines;
|
||||
private List<TerminalLine> allSourceLines;
|
||||
private List<string> visibleLines;
|
||||
|
||||
private TypeFacePrinter typeFacePrinter = null;
|
||||
private PrinterConfig printer = null;
|
||||
|
||||
public Color TextColor = new Color(102, 102, 102);
|
||||
private int forceStartLine = -1;
|
||||
|
||||
private Func<TerminalLine, string> _lineFilterFunction;
|
||||
|
||||
public TextScrollWidget(PrinterConfig printer, List<TerminalLine> sourceLines)
|
||||
{
|
||||
this.printer = printer;
|
||||
this.typeFacePrinter = new TypeFacePrinter("", new StyledTypeFace(ApplicationController.GetTypeFace(NamedTypeFace.Liberation_Mono), 12));
|
||||
this.typeFacePrinter.DrawFromHintedCache = true;
|
||||
this.allSourceLines = sourceLines;
|
||||
this.visibleLines = sourceLines.Select(ld => ld.Line).ToList();
|
||||
|
||||
// Register listeners
|
||||
printer.Connection.TerminalLog.LineAdded += this.TerminalLog_LineAdded;
|
||||
printer.Connection.TerminalLog.LogCleared += this.TerminalLog_LogCleared;
|
||||
}
|
||||
|
||||
public double Position0To1
|
||||
{
|
||||
get
|
||||
|
|
@ -71,7 +74,7 @@ namespace MatterHackers.MatterControl
|
|||
}
|
||||
else
|
||||
{
|
||||
return ((visibleLines.Count - (double)forceStartLine) / visibleLines.Count);
|
||||
return (visibleLines.Count - (double)forceStartLine) / visibleLines.Count;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -87,48 +90,49 @@ namespace MatterHackers.MatterControl
|
|||
{
|
||||
forceStartLine = -1;
|
||||
}
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
public int NumVisibleLines => (int)Math.Ceiling(Height / typeFacePrinter.TypeFaceStyle.EmSizeInPixels);
|
||||
public int NumVisibleLines => (int)Math.Ceiling(Height / typeFacePrinter.TypeFaceStyle.EmSizeInPixels);
|
||||
|
||||
public TextScrollWidget(PrinterConfig printer, List<(string line, bool output)> sourceLines)
|
||||
public Color TextColor { get; set; } = new Color(102, 102, 102);
|
||||
|
||||
public Func<TerminalLine, string> LineFilterFunction
|
||||
{
|
||||
this.printer = printer;
|
||||
printer.Connection.TerminalLog.HasChanged += RecievedNewLine;
|
||||
this.typeFacePrinter = new TypeFacePrinter("", new StyledTypeFace(ApplicationController.GetTypeFace(NamedTypeFace.Liberation_Mono), 12));
|
||||
this.typeFacePrinter.DrawFromHintedCache = true;
|
||||
this.allSourceLines = sourceLines;
|
||||
this.visibleLines = sourceLines.Select(ld => ld.line).ToList();
|
||||
get => _lineFilterFunction;
|
||||
set
|
||||
{
|
||||
_lineFilterFunction = value;
|
||||
RebuildFilteredList();
|
||||
}
|
||||
}
|
||||
|
||||
private void ConditionalyAddToVisible((string line, bool output) lineData)
|
||||
private void ConditionalyAddToVisible(TerminalLine terminalLine)
|
||||
{
|
||||
var line = lineData.line;
|
||||
var line = terminalLine.Line;
|
||||
|
||||
if (LineFilterFunction != null)
|
||||
{
|
||||
line = LineFilterFunction(lineData);
|
||||
line = LineFilterFunction(terminalLine);
|
||||
}
|
||||
|
||||
if(!string.IsNullOrEmpty(line))
|
||||
if (!string.IsNullOrEmpty(line))
|
||||
{
|
||||
visibleLines.Add(line);
|
||||
}
|
||||
}
|
||||
|
||||
private void RecievedNewLine(object sender, (string line, bool output) lineData)
|
||||
private void TerminalLog_LineAdded(object sender, TerminalLine terminalLine)
|
||||
{
|
||||
if (lineData.line != null)
|
||||
{
|
||||
ConditionalyAddToVisible(lineData);
|
||||
}
|
||||
else // the list changed in some big way (probably cleared)
|
||||
{
|
||||
RebuildFilteredList();
|
||||
}
|
||||
this.ConditionalyAddToVisible(terminalLine);
|
||||
this.Invalidate();
|
||||
}
|
||||
|
||||
Invalidate();
|
||||
private void TerminalLog_LogCleared(object sender, EventArgs e)
|
||||
{
|
||||
this.RebuildFilteredList();
|
||||
}
|
||||
|
||||
public void RebuildFilteredList()
|
||||
|
|
@ -136,7 +140,7 @@ namespace MatterHackers.MatterControl
|
|||
lock (locker)
|
||||
{
|
||||
visibleLines = new List<string>();
|
||||
(string, bool)[] allSourceLinesTemp = allSourceLines.ToArray();
|
||||
var allSourceLinesTemp = allSourceLines.ToArray();
|
||||
foreach (var lineData in allSourceLinesTemp)
|
||||
{
|
||||
ConditionalyAddToVisible(lineData);
|
||||
|
|
@ -147,19 +151,22 @@ namespace MatterHackers.MatterControl
|
|||
public void WriteToFile(string filePath)
|
||||
{
|
||||
// Make a copy so we don't have it change while writing.
|
||||
string[] allSourceLinesTemp = allSourceLines.Select(ld => ld.line).ToArray();
|
||||
string[] allSourceLinesTemp = allSourceLines.Select(ld => ld.Line).ToArray();
|
||||
System.IO.File.WriteAllLines(filePath, allSourceLinesTemp);
|
||||
}
|
||||
|
||||
public override void OnClosed(EventArgs e)
|
||||
{
|
||||
printer.Connection.TerminalLog.HasChanged -= RecievedNewLine;
|
||||
// Unregister listeners
|
||||
printer.Connection.TerminalLog.LineAdded -= this.TerminalLog_LineAdded;
|
||||
printer.Connection.TerminalLog.LogCleared -= this.TerminalLog_LogCleared;
|
||||
|
||||
base.OnClosed(e);
|
||||
}
|
||||
|
||||
public override void OnDraw(Graphics2D graphics2D)
|
||||
{
|
||||
RectangleDouble Bounds = LocalBounds;
|
||||
RectangleDouble bounds = LocalBounds;
|
||||
|
||||
int numLinesToDraw = NumVisibleLines;
|
||||
|
||||
|
|
@ -183,6 +190,7 @@ namespace MatterHackers.MatterControl
|
|||
startLineIndex = Math.Min(forceStartLine, startLineIndex);
|
||||
}
|
||||
}
|
||||
|
||||
int endLineIndex = visibleLines.Count;
|
||||
for (int lineIndex = startLineIndex; lineIndex < endLineIndex; lineIndex++)
|
||||
{
|
||||
|
|
@ -191,10 +199,11 @@ namespace MatterHackers.MatterControl
|
|||
if (visibleLines[lineIndex] != null)
|
||||
{
|
||||
typeFacePrinter.Text = visibleLines[lineIndex];
|
||||
typeFacePrinter.Origin = new Vector2(Bounds.Left + 2, y);
|
||||
typeFacePrinter.Origin = new Vector2(bounds.Left + 2, y);
|
||||
typeFacePrinter.Render(graphics2D, TextColor);
|
||||
}
|
||||
}
|
||||
|
||||
y -= typeFacePrinter.TypeFaceStyle.EmSizeInPixels;
|
||||
if (y < -typeFacePrinter.TypeFaceStyle.EmSizeInPixels)
|
||||
{
|
||||
|
|
@ -210,15 +219,15 @@ namespace MatterHackers.MatterControl
|
|||
public override void OnMouseWheel(MouseEventArgs mouseEvent)
|
||||
{
|
||||
base.OnMouseWheel(mouseEvent);
|
||||
double scrollDelta = (mouseEvent.WheelDelta / ((visibleLines.Count) * 60.0));
|
||||
double scrollDelta = mouseEvent.WheelDelta / (visibleLines.Count * 60.0);
|
||||
|
||||
if (scrollDelta < 0)//Rounding seems to favor scrolling up, compensating scroll down to feel as smooth
|
||||
if (scrollDelta < 0) // Rounding seems to favor scrolling up, compensating scroll down to feel as smooth
|
||||
{
|
||||
scrollDelta *= 2;
|
||||
}
|
||||
else if (Position0To1 == 0)//IF we scroll up at the bottom get pop out from the "on screen" chunk
|
||||
else if (Position0To1 == 0) // If we scroll up at the bottom get pop out from the "on screen" chunk
|
||||
{
|
||||
scrollDelta = (NumVisibleLines / (double)visibleLines.Count);
|
||||
scrollDelta = NumVisibleLines / (double)visibleLines.Count;
|
||||
}
|
||||
|
||||
double newPos = Position0To1 + scrollDelta;
|
||||
|
|
@ -247,7 +256,7 @@ namespace MatterHackers.MatterControl
|
|||
&& !keyEvent.Shift)
|
||||
{
|
||||
double startingScrollPosition = Position0To1;
|
||||
double scrollDelta = (NumVisibleLines / (double)visibleLines.Count);
|
||||
double scrollDelta = NumVisibleLines / (double)visibleLines.Count;
|
||||
double newPos = Position0To1;
|
||||
|
||||
switch (keyEvent.KeyCode)
|
||||
|
|
|
|||
|
|
@ -196,14 +196,14 @@ namespace MatterHackers.MatterControl
|
|||
var printerSettingsLayer = new PrinterSettingsLayer();
|
||||
printer.Settings.Merge(printerSettingsLayer, settingsToImport, sourceFilter, copyName);
|
||||
|
||||
var layerName = (printerSettingsLayer.ContainsKey(SettingsKey.layer_name)) ? printerSettingsLayer[SettingsKey.layer_name] : "none";
|
||||
var layerName = printerSettingsLayer.ContainsKey(SettingsKey.layer_name) ? printerSettingsLayer[SettingsKey.layer_name] : "none";
|
||||
|
||||
string sectionName = destIsMaterial ? "Material".Localize() : "Quality".Localize();
|
||||
|
||||
string importSettingSuccessMessage = string.Format("You have successfully imported a new {0} setting. You can find '{1}' in your list of {0} settings.".Localize(), sectionName, layerName);
|
||||
|
||||
DialogWindow.ChangeToPage(
|
||||
new ImportSucceeded(importSettingSuccessMessage)
|
||||
new ImportSucceededPage(importSettingSuccessMessage)
|
||||
{
|
||||
DialogWindow = this.DialogWindow,
|
||||
});
|
||||
|
|
@ -235,16 +235,4 @@ namespace MatterHackers.MatterControl
|
|||
StyledMessageBox.ShowMessageBox("Oops! Settings file '{0}' did not contain any settings we could import.".Localize().FormatWith(Path.GetFileName(settingsFilePath)), "Unable to Import".Localize());
|
||||
}
|
||||
}
|
||||
|
||||
public class ImportSucceeded : DialogPage
|
||||
{
|
||||
public ImportSucceeded(string successMessage) :
|
||||
base("Done".Localize())
|
||||
{
|
||||
this.WindowTitle = "Import Wizard".Localize();
|
||||
this.HeaderText = "Import Successful".Localize();
|
||||
|
||||
contentRow.AddChild(new WrappedTextWidget(successMessage, textColor: theme.TextColor));
|
||||
}
|
||||
}
|
||||
}
|
||||
52
MatterControlLib/SetupWizard/ImportSucceededPage.cs
Normal file
52
MatterControlLib/SetupWizard/ImportSucceededPage.cs
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
Copyright (c) 2018, Lars Brubaker, John Lewin
|
||||
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.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using MatterHackers.Agg;
|
||||
using MatterHackers.Agg.UI;
|
||||
using MatterHackers.Localizations;
|
||||
using MatterHackers.MatterControl.SlicerConfiguration;
|
||||
|
||||
namespace MatterHackers.MatterControl
|
||||
{
|
||||
|
||||
public class ImportSucceededPage : DialogPage
|
||||
{
|
||||
public ImportSucceededPage(string successMessage)
|
||||
: base("Done".Localize())
|
||||
{
|
||||
this.WindowTitle = "Import Wizard".Localize();
|
||||
this.HeaderText = "Import Successful".Localize();
|
||||
|
||||
contentRow.AddChild(new WrappedTextWidget(successMessage, textColor: theme.TextColor));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -497,7 +497,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
|
|||
return null;
|
||||
}
|
||||
|
||||
internal static bool ImportFromExisting(string settingsFilePath)
|
||||
internal static bool ImportFromExisting(string settingsFilePath, bool clearBlackList = true)
|
||||
{
|
||||
if (string.IsNullOrEmpty(settingsFilePath) || !File.Exists(settingsFilePath))
|
||||
{
|
||||
|
|
@ -543,7 +543,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
|
|||
printerInfo.Model = printerSettings.OemLayer[SettingsKey.model] ?? "Other";
|
||||
}
|
||||
|
||||
printerSettings.Save(clearBlackListSettings: true);
|
||||
printerSettings.Save(clearBlackList);
|
||||
importSuccessful = true;
|
||||
}
|
||||
break;
|
||||
|
|
@ -592,7 +592,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
|
|||
|
||||
printerSettings.Helpers.SetName(printerInfo.Name);
|
||||
|
||||
printerSettings.Save(clearBlackListSettings: true);
|
||||
printerSettings.Save(clearBlackList);
|
||||
importSuccessful = true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -244,7 +244,7 @@ namespace MatterHackers.MatterControl.CustomWidgets
|
|||
{
|
||||
Mate = new MateOptions(alignLeft ? MateEdge.Right : MateEdge.Left, MateEdge.Top),
|
||||
AltMate = new MateOptions(alignLeft ? MateEdge.Left : MateEdge.Right, MateEdge.Bottom),
|
||||
//Offset = new RectangleDouble(12, 0, 12, 0)
|
||||
// Offset = new RectangleDouble(12, 0, 12, 0)
|
||||
},
|
||||
secondsToClose: closeSeconds);
|
||||
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ namespace MatterHackers.MatterControl.Tests.Automation
|
|||
Assert.AreEqual(printer.Connection.CommunicationState, PrinterCommunication.CommunicationStates.Connected);
|
||||
|
||||
// Assert that two G28s were output to the terminal
|
||||
int g28Count = printer.Connection.TerminalLog.PrinterLines.Where(lineData => lineData.line.Contains("G28")).Count();
|
||||
int g28Count = printer.Connection.TerminalLog.PrinterLines.Where(lineData => lineData.Line.Contains("G28")).Count();
|
||||
Assert.AreEqual(2, g28Count, "The terminal log should contain one G28 from Start-GCode and one G28 from Cancel-GCode");
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue