Merge branch '1.6'

This commit is contained in:
Lars Brubaker 2016-12-15 15:32:34 -08:00
commit 3e5a92d0bb
14 changed files with 133 additions and 121 deletions

View file

@ -434,18 +434,9 @@ namespace MatterHackers.MatterControl
ApplicationClosed?.Invoke(null, null);
}
static void LoadUITheme()
static void LoadOemOrDefaultTheme()
{
// if the user setting has a theme color assume it is correct and use it right away
if (UserSettings.Instance != null)
{
var themeName = UserSettings.Instance.get(UserSettingsKey.ActiveThemeName);
if (!string.IsNullOrEmpty(themeName))
{
ActiveTheme.Instance = ActiveTheme.GetThemeColors(themeName);
return;
}
}
ActiveTheme.SuspendEvents();
// if not check for the oem color and use it if set
// else default to "Blue - Light"
@ -456,9 +447,10 @@ namespace MatterHackers.MatterControl
}
else
{
UserSettings.Instance.set(UserSettingsKey.ActiveThemeName, oemColor);
ActiveTheme.Instance = ActiveTheme.GetThemeColors(oemColor);
}
ActiveTheme.ResumeEvents();
}
public static ApplicationController Instance
@ -471,11 +463,10 @@ namespace MatterHackers.MatterControl
{
globalInstance = new ApplicationController();
// set the colors
LoadUITheme();
// Set the default theme colors
LoadOemOrDefaultTheme();
// We previously made a call to Reload, which fired the method twice due to it being in the static constructor. Accessing
// any property will run the static constructor and perform the Reload behavior without the overhead of duplicate calls
// Accessing any property on ProfileManager will run the static constructor and spin up the ProfileManager instance
bool na = ProfileManager.Instance.IsGuestProfile;
if (UserSettings.Instance.DisplayMode == ApplicationDisplayType.Touchscreen)

View file

@ -108,8 +108,6 @@ namespace MatterHackers.MatterControl.DataStorage.ClassicDB
ProfileManager.Instance.LastProfileID = printer.Id.ToString();
}
printerSettings.UserLayer[SettingsKey.active_theme_name] = UserSettings.Instance.get(UserSettingsKey.ActiveThemeName);
// Import macros from the database
var allMacros = Datastore.Instance.dbSQLite.Query<CustomCommands>("SELECT * FROM CustomCommands WHERE PrinterId = " + printer.Id);
printerSettings.Macros = allMacros.Select(macro => new GCodeMacro()

View file

@ -334,6 +334,8 @@ namespace MatterHackers.MatterControl.DataStorage
public string PrintingGCodeFileName { get; set; }
public double RecoveryCount { get; set; }
public double PercentDone { get; set; }
public bool PrintComplete { get; set; }

View file

@ -146,7 +146,19 @@ namespace MatterHackers.MatterControl.PrintHistory
if (printTask.PercentDone > 0)
{
timeIndicator.AutoExpandBoundsToText = true;
timeIndicator.Text += " ({0:0.0}%)".FormatWith(printTask.PercentDone);
timeIndicator.Text += $" ({printTask.PercentDone:0.0}%)";
if(printTask.RecoveryCount > 0)
{
if (printTask.RecoveryCount == 1)
{
timeIndicator.Text += " - " + "recovered once".Localize();
}
else
{
timeIndicator.Text += " - " + "recovered {0} times".FormatWith(printTask.RecoveryCount);
}
}
}
timeIndicator.Margin = new BorderDouble(right: 6);

View file

@ -265,8 +265,8 @@ namespace MatterHackers.MatterControl.PrinterCommunication
ReadLineContainsCallBacks.AddCallbackToKey("T:", ReadTemperatures);
ReadLineContainsCallBacks.AddCallbackToKey("rs ", PrinterRequestsResend); // smoothie is lower case and no :
ReadLineContainsCallBacks.AddCallbackToKey("RS:", PrinterRequestsResend);
ReadLineStartCallBacks.AddCallbackToKey("rs ", PrinterRequestsResend); // smoothie is lower case and no :
ReadLineStartCallBacks.AddCallbackToKey("RS:", PrinterRequestsResend);
ReadLineContainsCallBacks.AddCallbackToKey("Resend:", PrinterRequestsResend);
ReadLineContainsCallBacks.AddCallbackToKey("FIRMWARE_NAME:", PrinterStatesFirmware);
@ -1470,17 +1470,22 @@ namespace MatterHackers.MatterControl.PrinterCommunication
{
FoundStringEventArgs foundStringEventArgs = e as FoundStringEventArgs;
string[] splitOnColon = foundStringEventArgs.LineToCheck.Split(':');
if (splitOnColon.Length > 1)
if (foundStringEventArgs != null
&& !string.IsNullOrEmpty(foundStringEventArgs.LineToCheck))
{
int result = 0;
if (int.TryParse(splitOnColon[1], out result))
string line = foundStringEventArgs.LineToCheck;
// marlin and repetier send a : before the number and then and ok
if (!GCodeFile.GetFirstNumberAfter(":", line, ref currentLineIndexToSend))
{
currentLineIndexToSend = result;
// smoothie sends an N before the number and no ok
if (GCodeFile.GetFirstNumberAfter("N", line, ref currentLineIndexToSend))
{
// clear waiting for ok because smoothie will not send it
PrintingCanContinue(null, null);
}
}
if(currentLineIndexToSend >= allCheckSumLinesSent.Count)
if (currentLineIndexToSend >= allCheckSumLinesSent.Count)
{
SendLineToPrinterNow("M110 N1");
}
@ -2222,6 +2227,9 @@ namespace MatterHackers.MatterControl.PrinterCommunication
private void AttemptToConnect(string serialPortName, int baudRate)
{
// make sure we don't have a left over print task
activePrintTask = null;
connectionFailureMessage = LocalizedString.Get("Unknown Reason");
if (PrinterIsConnected)
@ -2450,6 +2458,9 @@ namespace MatterHackers.MatterControl.PrinterCommunication
&& activePrintTask != null) // We are resuming a failed print (do lots of interesting stuff).
{
pauseHandlingStream1 = new PauseHandlingStream(new PrintRecoveryStream(gCodeFileStream0, activePrintTask.PercentDone));
// And increment the recovery count
activePrintTask.RecoveryCount++;
activePrintTask.Commit();
}
else
{

View file

@ -11,7 +11,6 @@ namespace MatterHackers.MatterControl
public const string UpdateFeedType = nameof(UpdateFeedType);
public const string ApplicationDisplayMode = nameof(ApplicationDisplayMode);
public const string defaultRenderSetting = nameof(defaultRenderSetting);
public const string ActiveThemeName = nameof(ActiveThemeName);
public const string ThumbnailRenderingMode = nameof(ThumbnailRenderingMode);
public const string CredentialsInvalid = nameof(CredentialsInvalid);
public const string CredentialsInvalidReason = nameof(CredentialsInvalidReason);

View file

@ -40,6 +40,7 @@ using MatterHackers.Agg.PlatformAbstract;
using MatterHackers.SerialPortCommunication.FrostedSerial;
using MatterHackers.Agg.UI;
using System.Threading.Tasks;
using MatterHackers.Localizations;
namespace MatterHackers.MatterControl.SlicerConfiguration
{
@ -51,7 +52,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
public static RootedObjectEventHandler ActiveProfileModified = new RootedObjectEventHandler();
public static RootedObjectEventHandler SettingChanged = new RootedObjectEventHandler();
private static PrinterSettings activeInstance = null;
private static PrinterSettings activeInstance = PrinterSettings.Empty;
public static PrinterSettings Instance
{
get
@ -60,37 +61,31 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
}
set
{
// EmptyProfile instances may differ but IDs are always be the same. Only process if instance and IDs differ
if (activeInstance != value
&& activeInstance?.ID != value.ID)
&& value != null)
{
// If we have an active printer, run Disable otherwise skip to prevent empty ActiveSliceSettings due to null ActivePrinter
if (activeInstance != null)
// If we have an active printer, run Disable
if (activeInstance != PrinterSettings.Empty)
{
PrinterConnectionAndCommunication.Instance.Disable();
}
activeInstance = value;
if (activeInstance != null)
{
BedSettings.SetMakeAndModel(activeInstance.GetValue(SettingsKey.make), activeInstance.GetValue(SettingsKey.model));
}
SwitchToPrinterTheme(MatterControlApplication.IsLoading);
BedSettings.SetMakeAndModel(activeInstance.GetValue(SettingsKey.make), activeInstance.GetValue(SettingsKey.model));
SwitchToPrinterTheme(!MatterControlApplication.IsLoading);
if (!MatterControlApplication.IsLoading)
{
OnActivePrinterChanged(null);
if (ActiveSliceSettings.Instance.PrinterSelected)
if (ActiveSliceSettings.Instance.PrinterSelected
&& Instance.GetValue<bool>(SettingsKey.auto_connect))
{
if (Instance.GetValue<bool>(SettingsKey.auto_connect))
UiThread.RunOnIdle(() =>
{
UiThread.RunOnIdle(() =>
{
//PrinterConnectionAndCommunication.Instance.HaltConnectionThread();
PrinterConnectionAndCommunication.Instance.ConnectToActivePrinter();
}, 2);
}
PrinterConnectionAndCommunication.Instance.ConnectToActivePrinter();
}, 2);
}
}
}
@ -132,39 +127,28 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
/// </summary>
public static void SwitchToPrinterTheme(bool doReloadEvent)
{
if (ActiveSliceSettings.Instance != null)
if (ActiveSliceSettings.Instance.PrinterSelected)
{
if (ActiveSliceSettings.Instance.PrinterSelected)
//Attempt to load userSetting theme as default
string activeThemeName = ActiveSliceSettings.Instance.GetValue(SettingsKey.active_theme_name);
if (!string.IsNullOrEmpty(activeThemeName))
{
//Attempt to load userSetting theme as default
if (ActiveSliceSettings.Instance.Contains(SettingsKey.active_theme_name))
if (!doReloadEvent)
{
string activeThemeName = ActiveSliceSettings.Instance.GetValue(SettingsKey.active_theme_name);
if (!doReloadEvent)
{
ActiveTheme.SuspendEvents();
}
ActiveTheme.Instance = ActiveTheme.GetThemeColors(activeThemeName);
// Save the theme so we can load it first thing on startup before a profile is loaded.
UserSettings.Instance.set(UserSettingsKey.ActiveThemeName, ActiveTheme.Instance.Name);
ActiveTheme.ResumeEvents();
ActiveTheme.SuspendEvents();
}
ActiveTheme.Instance = ActiveTheme.GetThemeColors(activeThemeName);
ActiveTheme.ResumeEvents();
}
}
}
static ActiveSliceSettings()
{
// Load last profile or fall back to empty
Instance = ProfileManager.Instance?.LoadWithoutRecovery(ProfileManager.Instance.LastProfileID) ?? ProfileManager.LoadEmptyProfile();
}
internal static async Task SwitchToProfile(string printerID)
{
ProfileManager.Instance.LastProfileID = printerID;
Instance = (await ProfileManager.LoadProfileAsync(printerID)) ?? ProfileManager.LoadEmptyProfile();
Instance = (await ProfileManager.LoadProfileAsync(printerID)) ?? PrinterSettings.Empty;
}
private static void OnActivePrinterChanged(EventArgs e)

View file

@ -59,6 +59,8 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
private static PrinterSettingsLayer baseLayerCache;
public static PrinterSettings Empty { get; }
public int DocumentVersion { get; set; } = LatestVersion;
public string ID { get; set; }
@ -75,6 +77,12 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
public PrinterSettingsLayer StagedUserSettings { get; set; } = new PrinterSettingsLayer();
static PrinterSettings()
{
Empty = new PrinterSettings() { ID = "EmptyProfile" };
Empty.UserLayer[SettingsKey.printer_name] = "Printers...".Localize();
}
public PrinterSettings()
{
this.Helpers = new SettingsHelpers(this);
@ -91,6 +99,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
}
}
}
public IEnumerable<GCodeMacro> ActionMacros()
{
foreach (var macro in Macros)
@ -357,7 +366,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
{
// If we still have failed to recover a profile, create an empty profile with
// just enough data to delete the printer
printerSettings = ProfileManager.LoadEmptyProfile();
printerSettings = PrinterSettings.Empty;
printerSettings.ID = printerInfo.ID;
printerSettings.UserLayer[SettingsKey.device_token] = printerInfo.DeviceToken;
printerSettings.Helpers.SetComPort(printerInfo.ComPort);
@ -548,6 +557,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
}
[JsonIgnore]
public SettingsHelpers Helpers { get; set; }
[JsonIgnore]
public bool PrinterSelected => OemLayer?.Keys.Count > 0;
@ -978,12 +988,6 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
{
var persistenceLayer = layer ?? UserLayer;
if(settingsKey == SettingsKey.active_theme_name)
{
// also save it to the user settings so we can load it first thing on startup before a profile is loaded.
UserSettings.Instance.set(UserSettingsKey.ActiveThemeName, settingsValue);
}
// If the setting exists and is set the requested value, exit without setting or saving
string existingValue;
if (persistenceLayer.TryGetValue(settingsKey, out existingValue) && existingValue == settingsValue)

View file

@ -29,25 +29,54 @@ either expressed or implied, of the FreeBSD Project.
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using MatterHackers.Agg;
using MatterHackers.Agg.UI;
using MatterHackers.MatterControl.DataStorage;
using MatterHackers.MatterControl.SettingsManagement;
using Newtonsoft.Json;
namespace MatterHackers.MatterControl.SlicerConfiguration
{
using System.Collections.ObjectModel;
using System.Threading.Tasks;
using Agg;
using DataStorage;
using Localizations;
using SettingsManagement;
public class ProfileManager
{
public static RootedObjectEventHandler ProfilesListChanged = new RootedObjectEventHandler();
public static ProfileManager Instance { get; private set; }
private static ProfileManager activeInstance = null;
public static ProfileManager Instance
{
get
{
return activeInstance;
}
private set
{
activeInstance = value;
// If the loaded slice settings do not match the last active settings for this profile, change to the last active
if (ActiveSliceSettings.Instance?.ID != activeInstance.LastProfileID)
{
// Load or download on a background thread
var lastProfile = LoadProfileAsync(activeInstance.LastProfileID).Result;
if (MatterControlApplication.IsLoading)
{
ActiveSliceSettings.Instance = lastProfile ?? PrinterSettings.Empty;
}
else
{
UiThread.RunOnIdle(() =>
{
// Assign on the UI thread
ActiveSliceSettings.Instance = lastProfile ?? PrinterSettings.Empty;
});
}
}
}
}
private static EventHandler unregisterEvents;
@ -147,32 +176,6 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
loadedInstance = new ProfileManager() { UserName = userName };
}
// If the loaded slice settings do not match the last active settings for this profile, change to the last active
if (ActiveSliceSettings.Instance?.ID != loadedInstance.LastProfileID)
{
// async so we can safely wait for LoadProfileAsync to complete
Task.Run(async () =>
{
// Load or download on a background thread
var lastProfile = await LoadProfileAsync(Instance.LastProfileID);
if (MatterControlApplication.IsLoading)
{
// TODO: Not true - we're on a background thread in an async lambda... what is the intent of this?
// Assign on the UI thread
ActiveSliceSettings.Instance = lastProfile ?? LoadEmptyProfile();
}
else
{
UiThread.RunOnIdle(() =>
{
// Assign on the UI thread
ActiveSliceSettings.Instance = lastProfile ?? LoadEmptyProfile();
});
}
});
}
return loadedInstance;
}
@ -209,14 +212,6 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
}
}
public static PrinterSettings LoadEmptyProfile()
{
var emptyProfile = new PrinterSettings() { ID = "EmptyProfile" };
emptyProfile.UserLayer[SettingsKey.printer_name] = "Printers...".Localize();
return emptyProfile;
}
[JsonIgnore]
public string LastProfileID
{

View file

@ -196,7 +196,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
UiThread.RunOnIdle(() =>
{
ActiveSliceSettings.Instance = ProfileManager.LoadEmptyProfile();
ActiveSliceSettings.Instance = PrinterSettings.Empty;
// Notify listeners of a ProfileListChange event due to this printers removal
ProfileManager.ProfilesListChanged.CallEvents(this, null);

View file

@ -1138,6 +1138,7 @@
"ShowIfSet": "!has_hardware_leveling",
"ResetAtEndOfPrint": false,
"DefaultValue": "3 Point Plane",
"ReloadUiWhenChanged": true,
"RebuildGCodeOnChange": false
},
{

View file

@ -5671,3 +5671,18 @@ Translated:Discard Changes
English:Stay Connected
Translated:Stay Connected
English:Cancel Print
Translated:Cancel Print
English:Continue Printing
Translated:Continue Printing
English:Recovered Once
Translated:Recovered Once
English:Recovered once
Translated:Recovered once
English:recovered once
Translated:recovered once

@ -1 +1 @@
Subproject commit 3a04f46f41c96a0ce5f084112d2ff0000a1d9ac3
Subproject commit 17c395640e43ceb5a4803611a8bbfe4cacd72d84

@ -1 +1 @@
Subproject commit 9a88dacf7849a32b08e4be1497ac18037d151970
Subproject commit f7a23ccde5b894dc12bd1fdba867dcb1008013f5